Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@mcp-layer/schema

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mcp-layer/schema - npm Package Compare versions

Comparing version
1.0.1
to
1.0.2
+7
-6
package.json
{
"name": "@mcp-layer/schema",
"version": "1.0.1",
"version": "1.0.2",
"description": "Extract and normalize MCP schemas into a unified Zod-based format.",

@@ -35,9 +35,10 @@ "repository": {

"ajv": "^8.17.1",
"zod": "^3.25.76"
"zod": "^3.25.76",
"@mcp-layer/error": "0.2.0"
},
"devDependencies": {
"@mcp-layer/attach": "1.1.0",
"@mcp-layer/config": "1.0.0",
"@mcp-layer/connect": "1.0.0",
"@mcp-layer/test-server": "1.0.0"
"@mcp-layer/attach": "1.1.1",
"@mcp-layer/config": "1.0.1",
"@mcp-layer/connect": "1.0.1",
"@mcp-layer/test-server": "1.0.1"
},

@@ -44,0 +45,0 @@ "scripts": {

@@ -5,2 +5,15 @@ # @mcp-layer/schema

## Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [What this package does](#what-this-package-does)
- [Output shape (authoritative)](#output-shape-authoritative)
- [MCP Apps support](#mcp-apps-support)
- [Generator guidance](#generator-guidance)
- [Responsibilities and lifecycle](#responsibilities-and-lifecycle)
- [Error handling](#error-handling)
- [JSON Schema vs Zod](#json-schema-vs-zod)
- [Runtime Error Reference](#runtime-error-reference)
## Installation

@@ -147,1 +160,34 @@

Zod validators are produced to allow direct runtime validation, but the original JSON Schema is preserved in `detail.input.json` and `detail.output.json` so generators can emit OpenAPI, JSON Schema, or other schema formats without losing fidelity.
## Runtime Error Reference
This section is written for high-pressure debugging moments. Each entry maps directly to schema extraction preconditions.
<a id="error-49ae61"></a>
### Expected a Session instance.
Thrown from: `extract`
This happens when `extract(link)` is called without a connected `Session` object (or with an object that does not expose `.client`). The extractor relies on MCP client capabilities and list calls.
Step-by-step resolution:
1. Verify you are passing the `Session` returned by `connect(...)` or `attach(...)`.
2. Confirm session setup completed and `session.client` is available.
3. Avoid passing raw MCP client objects directly; wrap flows around `Session`.
4. Add an integration test that extracts from a real connected session.
<details>
<summary>Fix Example: extract schemas from a connected Session</summary>
```js
const session = await connect(config, 'local-dev');
const catalog = await extract(session);
console.log(catalog.items.length);
await session.close();
```
</details>
## License
MIT
import Ajv from 'ajv';
import { z } from 'zod';
import { LayerError } from '@mcp-layer/error';

@@ -21,9 +22,5 @@ const ajv = new Ajv({ allErrors: true, strict: false });

function ismissing(error) {
if (!error || typeof error !== 'object') {
return false;
}
if (!error || typeof error !== 'object') return false;
const code = 'code' in error ? error.code : undefined;
if (code === -32601) {
return true;
}
if (code === -32601) return true;
const message = 'message' in error ? String(error.message) : '';

@@ -48,5 +45,3 @@ return message.includes('Method') && message.includes('not found');

const ok = check(value);
if (ok) {
return;
}
if (ok) return;
const text = validator.errorsText(check.errors, { dataVar: 'value' });

@@ -93,9 +88,5 @@ ctx.addIssue({ code: z.ZodIssueCode.custom, message: text });

const batch = pull(result);
if (Array.isArray(batch)) {
list.push(...batch);
}
if (Array.isArray(batch)) list.push(...batch);
cursor = result.nextCursor;
if (!cursor) {
break;
}
if (!cursor) break;
}

@@ -196,5 +187,3 @@

} catch (error) {
if (ismissing(error)) {
return [];
}
if (ismissing(error)) return [];
throw error;

@@ -241,8 +230,4 @@ }

const out = {};
if (Array.isArray(item.icons)) {
out.icons = item.icons;
}
if (isrecord(item._meta)) {
out._meta = item._meta;
}
if (Array.isArray(item.icons)) out.icons = item.icons;
if (isrecord(item._meta)) out._meta = item._meta;
return out;

@@ -258,5 +243,3 @@ }

const out = meta(tool);
if (isrecord(tool.annotations)) {
out.annotations = tool.annotations;
}
if (isrecord(tool.annotations)) out.annotations = tool.annotations;
return out;

@@ -271,8 +254,4 @@ }

function tooltitle(tool) {
if (typeof tool.title === 'string') {
return tool.title;
}
if (isrecord(tool.annotations) && typeof tool.annotations.title === 'string') {
return tool.annotations.title;
}
if (typeof tool.title === 'string') return tool.title;
if (isrecord(tool.annotations) && typeof tool.annotations.title === 'string') return tool.annotations.title;
return undefined;

@@ -287,22 +266,10 @@ }

function uiitem(item) {
if (!isrecord(item._meta)) {
return undefined;
}
if (!isrecord(item._meta.ui)) {
return undefined;
}
if (!isrecord(item._meta)) return undefined;
if (!isrecord(item._meta.ui)) return undefined;
const ui = /** @type {Record<string, unknown>} */ (item._meta.ui);
const out = {};
if (typeof ui.resourceUri === 'string') {
out.resourceUri = ui.resourceUri;
}
if (typeof ui.csp === 'string') {
out.csp = ui.csp;
}
if (Array.isArray(ui.permissions)) {
out.permissions = ui.permissions;
}
if (Object.keys(out).length === 0) {
return undefined;
}
if (typeof ui.resourceUri === 'string') out.resourceUri = ui.resourceUri;
if (typeof ui.csp === 'string') out.csp = ui.csp;
if (Array.isArray(ui.permissions)) out.permissions = ui.permissions;
if (Object.keys(out).length === 0) return undefined;
return out;

@@ -322,8 +289,4 @@ }

if (isrecord(tool.outputSchema)) {
detail.output = output;
}
if (ui) {
detail.ui = ui;
}
if (isrecord(tool.outputSchema)) detail.output = output;
if (ui) detail.ui = ui;

@@ -387,5 +350,3 @@ return {

function promptinput(prompt) {
if (!Array.isArray(prompt.arguments)) {
return wrapschema(undefined);
}
if (!Array.isArray(prompt.arguments)) return wrapschema(undefined);

@@ -396,14 +357,8 @@ const properties = {};

for (const item of prompt.arguments) {
if (!isrecord(item)) {
continue;
}
if (typeof item.name !== 'string' || item.name.length === 0) {
continue;
}
if (!isrecord(item)) continue;
if (typeof item.name !== 'string' || item.name.length === 0) continue;
properties[item.name] = {
description: typeof item.description === 'string' ? item.description : undefined
};
if (item.required === true) {
required.push(item.name);
}
if (item.required === true) required.push(item.name);
}

@@ -482,3 +437,7 @@

if (!link || !link.client) {
throw new Error('Expected a Session instance.');
throw new LayerError({
name: 'schema',
method: 'extract',
message: 'Expected a Session instance.',
});
}

@@ -498,5 +457,3 @@

if (caps && caps.tools) {
data.tools = await tools(client);
}
if (caps && caps.tools) data.tools = await tools(client);

@@ -508,5 +465,3 @@ if (caps && caps.resources) {

if (caps && caps.prompts) {
data.prompts = await prompts(client);
}
if (caps && caps.prompts) data.prompts = await prompts(client);

@@ -513,0 +468,0 @@ const items = normalize(data);