feat: support Standard Schema for tool/prompt schemas (#1689)

Co-authored-by: Matt Carey <mcarey@cloudflare.com>
This commit is contained in:
Felix Weinberger 2026-03-23 14:44:38 +00:00 • committed by GitHub
commit 0784be1a67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 1327 additions and 212 deletions

View file

@ -0,0 +1,34 @@
---
'@modelcontextprotocol/core': minor
'@modelcontextprotocol/server': minor
'@modelcontextprotocol/client': minor
---
Support Standard Schema for tool and prompt schemas
Tool and prompt registration now accepts any schema library that implements the [Standard Schema spec](https://standardschema.dev/): Zod v4, Valibot, ArkType, and others. `RegisteredTool.inputSchema`, `RegisteredTool.outputSchema`, and `RegisteredPrompt.argsSchema` now use `StandardSchemaWithJSON` (requires both `~standard.validate` and `~standard.jsonSchema`) instead of the Zod-specific `AnySchema` type.
**Zod v4 schemas continue to work unchanged** — Zod v4 implements the required interfaces natively.
```typescript
import { type } from 'arktype';
server.registerTool('greet', {
inputSchema: type({ name: 'string' })
}, async ({ name }) => ({ content: [{ type: 'text', text: `Hello, ${name}!` }] }));
```
For raw JSON Schema (e.g. TypeBox output), use the new `fromJsonSchema` adapter:
```typescript
import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core';
server.registerTool('greet', {
inputSchema: fromJsonSchema({ type: 'object', properties: { name: { type: 'string' } } }, new AjvJsonSchemaValidator())
}, handler);
```
**Breaking changes:**
- `experimental.tasks.getTaskResult()` no longer accepts a `resultSchema` parameter. Returns `GetTaskPayloadResult` (a loose `Result`); cast to the expected type at the call site.
- Removed unused exports from `@modelcontextprotocol/core`: `SchemaInput`, `schemaToJson`, `parseSchemaAsync`, `getSchemaShape`, `getSchemaDescription`, `isOptionalSchema`, `unwrapOptionalSchema`. Use the new `standardSchemaToJsonSchema` and `validateStandardSchema` instead.
- `completable()` remains Zod-specific (it relies on Zod's `.shape` introspection).

View file

@ -209,7 +209,7 @@ if (error instanceof OAuthError && error.code === OAuthErrorCode.InvalidClient)
The variadic `.tool()`, `.prompt()`, `.resource()` methods are removed. Use the `register*` methods with a config object.
**IMPORTANT**: v2 requires full Zod schemas — raw shapes like `{ name: z.string() }` are no longer supported. You must wrap with `z.object()`. This applies to `inputSchema`, `outputSchema`, and `argsSchema`.
**IMPORTANT**: v2 requires schema objects implementing [Standard Schema](https://standardschema.dev/) — raw shapes like `{ name: z.string() }` are no longer supported. Wrap with `z.object()` (Zod v4), or use ArkType's `type({...})`, or Valibot. For raw JSON Schema, wrap with `fromJsonSchema(schema, validator)` from `@modelcontextprotocol/core`. Applies to `inputSchema`, `outputSchema`, and `argsSchema`.
### Tools
@ -279,13 +279,22 @@ Note: the third argument (`metadata`) is required — pass `{}` if no metadata.
### Schema Migration Quick Reference
| v1 (raw shape) | v2 (Zod schema) |
| v1 (raw shape) | v2 (Standard Schema object) |
|----------------|-----------------|
| `{ name: z.string() }` | `z.object({ name: z.string() })` |
| `{ count: z.number().optional() }` | `z.object({ count: z.number().optional() })` |
| `{}` (empty) | `z.object({})` |
| `undefined` (no schema) | `undefined` or omit the field |
### Removed core exports
| Removed from `@modelcontextprotocol/core` | Replacement |
|---|---|
| `schemaToJson(schema)` | `standardSchemaToJsonSchema(schema)` |
| `parseSchemaAsync(schema, data)` | `validateStandardSchema(schema, data)` |
| `SchemaInput<T>` | `StandardSchemaWithJSON.InferInput<T>` |
| `getSchemaShape`, `getSchemaDescription`, `isOptionalSchema`, `unwrapOptionalSchema` | none (internal Zod introspection helpers) |
## 7. Headers API
Transport constructors and `RequestInfo.headers` now use the Web Standard `Headers` object instead of plain objects.

View file

@ -200,17 +200,17 @@ import * as z from 'zod/v4';
const server = new McpServer({ name: 'demo', version: '1.0.0' });
// Tool with schema
server.registerTool('greet', { inputSchema: { name: z.string() } }, async ({ name }) => {
server.registerTool('greet', { inputSchema: z.object({ name: z.string() }) }, async ({ name }) => {
return { content: [{ type: 'text', text: `Hello, ${name}!` }] };
});
// Tool with description
server.registerTool('greet', { description: 'Greet a user', inputSchema: { name: z.string() } }, async ({ name }) => {
server.registerTool('greet', { description: 'Greet a user', inputSchema: z.object({ name: z.string() }) }, async ({ name }) => {
return { content: [{ type: 'text', text: `Hello, ${name}!` }] };
});
// Prompt
server.registerPrompt('summarize', { argsSchema: { text: z.string() } }, async ({ text }) => {
server.registerPrompt('summarize', { argsSchema: z.object({ text: z.string() }) }, async ({ text }) => {
return { messages: [{ role: 'user', content: { type: 'text', text: `Summarize: ${text}` } }] };
});
@ -220,9 +220,9 @@ server.registerResource('config', 'config://app', {}, async uri => {
});
```
### Zod schemas required (raw shapes no longer supported)
### Standard Schema objects required (raw shapes no longer supported)
v2 requires full Zod schemas for `inputSchema` and `argsSchema`. Raw object shapes are no longer accepted.
v2 requires schema objects implementing the [Standard Schema spec](https://standardschema.dev/) for `inputSchema`, `outputSchema`, and `argsSchema`. Raw object shapes are no longer accepted. Zod v4, ArkType, and Valibot all implement the spec.
**Before (v1):**
@ -240,11 +240,23 @@ server.registerTool('greet', {
```typescript
import * as z from 'zod/v4';
// Must wrap with z.object()
// Wrap with z.object() (or use any Standard Schema library)
server.registerTool('greet', {
inputSchema: z.object({ name: z.string() }) // full Zod schema
inputSchema: z.object({ name: z.string() })
}, async ({ name }) => { ... });
// ArkType works too
import { type } from 'arktype';
server.registerTool('greet', {
inputSchema: type({ name: 'string' })
}, async ({ name }) => { ... });
// Raw JSON Schema via fromJsonSchema
import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core';
server.registerTool('greet', {
inputSchema: fromJsonSchema({ type: 'object', properties: { name: { type: 'string' } } }, new AjvJsonSchemaValidator())
}, handler);
// For tools with no parameters, use z.object({})
server.registerTool('ping', {
inputSchema: z.object({})
@ -256,6 +268,15 @@ This applies to:
- `outputSchema` in `registerTool()`
- `argsSchema` in `registerPrompt()`
**Removed Zod-specific helpers** from `@modelcontextprotocol/core` (use Standard Schema equivalents):
| Removed | Replacement |
|---|---|
| `schemaToJson(schema)` | `standardSchemaToJsonSchema(schema)` |
| `parseSchemaAsync(schema, data)` | `validateStandardSchema(schema, data)` |
| `SchemaInput<T>` | `StandardSchemaWithJSON.InferInput<T>` |
| `getSchemaShape`, `getSchemaDescription`, `isOptionalSchema`, `unwrapOptionalSchema` | No replacement — these are now internal Zod introspection helpers |
### Host header validation moved
Express-specific middleware (`hostHeaderValidation()`, `localhostHostValidation()`) moved from the server package to `@modelcontextprotocol/express`. The server package now exports framework-agnostic functions instead: `validateHostHeader()`, `localhostAllowedHostnames()`,

View file

@ -34,14 +34,17 @@
"dependencies": {
"@hono/node-server": "catalog:runtimeServerOnly",
"@modelcontextprotocol/examples-shared": "workspace:^",
"@modelcontextprotocol/node": "workspace:^",
"@modelcontextprotocol/server": "workspace:^",
"@modelcontextprotocol/express": "workspace:^",
"@modelcontextprotocol/hono": "workspace:^",
"@modelcontextprotocol/node": "workspace:^",
"@modelcontextprotocol/server": "workspace:^",
"@valibot/to-json-schema": "catalog:devTools",
"arktype": "catalog:devTools",
"better-auth": "^1.4.17",
"cors": "catalog:runtimeServerOnly",
"express": "catalog:runtimeServerOnly",
"hono": "catalog:runtimeServerOnly",
"valibot": "catalog:devTools",
"zod": "catalog:runtimeShared"
},
"devDependencies": {

View file

@ -0,0 +1,28 @@
#!/usr/bin/env node
/**
* Minimal MCP server using ArkType for schema validation.
* ArkType implements the Standard Schema spec with built-in JSON Schema conversion.
*/
import { McpServer, StdioServerTransport } from '@modelcontextprotocol/server';
import { type } from 'arktype';
const server = new McpServer({
name: 'arktype-example',
version: '1.0.0'
});
// Register a tool with ArkType schema
server.registerTool(
'greet',
{
description: 'Generate a greeting',
inputSchema: type({ name: 'string' })
},
async ({ name }) => ({
content: [{ type: 'text', text: `Hello, ${name}!` }]
})
);
const transport = new StdioServerTransport();
await server.connect(transport);

View file

@ -0,0 +1,30 @@
#!/usr/bin/env node
/**
* Minimal MCP server using Valibot for schema validation.
* Use toStandardJsonSchema() from @valibot/to-json-schema to create
* StandardJSONSchemaV1-compliant schemas.
*/
import { McpServer, StdioServerTransport } from '@modelcontextprotocol/server';
import { toStandardJsonSchema } from '@valibot/to-json-schema';
import * as v from 'valibot';
const server = new McpServer({
name: 'valibot-example',
version: '1.0.0'
});
// Register a tool with Valibot schema
server.registerTool(
'greet',
{
description: 'Generate a greeting',
inputSchema: toStandardJsonSchema(v.object({ name: v.string() }))
},
async ({ name }) => ({
content: [{ type: 'text', text: `Hello, ${name}!` }]
})
);
const transport = new StdioServerTransport();
await server.connect(transport);

View file

@ -6,20 +6,19 @@
*/
import type {
AnyObjectSchema,
CallToolRequest,
CallToolResult,
CancelTaskResult,
CreateTaskResult,
GetTaskPayloadResult,
GetTaskResult,
ListTasksResult,
RequestMethod,
RequestOptions,
ResponseMessage,
ResultTypeMap,
SchemaOutput
ResultTypeMap
} from '@modelcontextprotocol/core';
import { ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/core';
import { GetTaskPayloadResultSchema, ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/core';
import type { Client } from '../../client/client.js';
@ -185,23 +184,22 @@ export class ExperimentalClientTasks {
* Retrieves the result of a completed task.
*
* @param taskId - The task identifier
* @param resultSchema - Zod schema for validating the result
* @param options - Optional request options
* @returns The task result
* @returns The task result. The payload structure matches the result type of the
* original request (e.g., a `tools/call` task returns a `CallToolResult`).
*
* @experimental
*/
async getTaskResult<T extends AnyObjectSchema>(taskId: string, resultSchema?: T, options?: RequestOptions): Promise<SchemaOutput<T>> {
// Delegate to the client's underlying Protocol method
async getTaskResult(taskId: string, options?: RequestOptions): Promise<GetTaskPayloadResult> {
return (
this._client as unknown as {
getTaskResult: <U extends AnyObjectSchema>(
getTaskResult: (
params: { taskId: string },
resultSchema?: U,
resultSchema: typeof GetTaskPayloadResultSchema,
options?: RequestOptions
) => Promise<SchemaOutput<U>>;
) => Promise<GetTaskPayloadResult>;
}
).getTaskResult({ taskId }, resultSchema, options);
).getTaskResult({ taskId }, GetTaskPayloadResultSchema, options);
}
/**

View file

@ -12,11 +12,13 @@ export * from './shared/uriTemplate.js';
export * from './types/types.js';
export * from './util/inMemory.js';
export * from './util/schema.js';
export * from './util/standardSchema.js';
// experimental exports
export * from './experimental/index.js';
export * from './validators/ajvProvider.js';
export * from './validators/cfWorkerProvider.js';
export * from './validators/fromJsonSchema.js';
/**
* JSON Schema validation
*

View file

@ -1,34 +1,25 @@
/**
* Internal Zod schema utilities for protocol handling.
* These are used internally by the SDK for protocol message validation.
*/
import * as z from 'zod/v4';
/**
* Base type for any Zod schema.
* This is the canonical type to use when accepting user-provided schemas.
*/
export type AnySchema = z.core.$ZodType;
/**
* A Zod schema for objects specifically (not unions).
* Use this when you need to constrain to ZodObject schemas.
* A Zod schema for objects specifically.
*/
export type AnyObjectSchema = z.core.$ZodObject;
/**
* Extracts the input type from a Zod schema.
*/
export type SchemaInput<T extends AnySchema> = z.input<T>;
/**
* Extracts the output type from a Zod schema.
*/
export type SchemaOutput<T extends AnySchema> = z.output<T>;
/**
* Converts a Zod schema to JSON Schema.
*/
export function schemaToJson(schema: AnySchema, options?: { io?: 'input' | 'output' }): Record<string, unknown> {
return z.toJSONSchema(schema, options) as Record<string, unknown>;
}
/**
* Parses data against a Zod schema (synchronous).
* Returns a discriminated union with success/error.
@ -39,56 +30,3 @@ export function parseSchema<T extends AnySchema>(
): { success: true; data: z.output<T> } | { success: false; error: z.core.$ZodError } {
return z.safeParse(schema, data);
}
/**
* Parses data against a Zod schema (asynchronous).
* Returns a discriminated union with success/error.
*/
export function parseSchemaAsync<T extends AnySchema>(
schema: T,
data: unknown
): Promise<{ success: true; data: z.output<T> } | { success: false; error: z.core.$ZodError }> {
return z.safeParseAsync(schema, data);
}
/**
* Gets the shape of an object schema.
* Returns undefined if the schema is not an object schema.
*/
export function getSchemaShape(schema: AnySchema): Record<string, AnySchema> | undefined {
const candidate = schema as { shape?: unknown };
if (candidate.shape && typeof candidate.shape === 'object') {
return candidate.shape as Record<string, AnySchema>;
}
return undefined;
}
/**
* Gets the description from a schema if it has one.
*/
export function getSchemaDescription(schema: AnySchema): string | undefined {
const candidate = schema as { description?: string };
return candidate.description;
}
/**
* Checks if a schema is optional (accepts undefined).
* Uses the public .type property which works in both zod/v4 and zod/v4/mini.
*/
export function isOptionalSchema(schema: AnySchema): boolean {
const candidate = schema as { type?: string };
return candidate.type === 'optional';
}
/**
* Unwraps an optional schema to get the inner schema.
* If the schema is not optional, returns it unchanged.
* Uses the public .def.innerType property which works in both zod/v4 and zod/v4/mini.
*/
export function unwrapOptionalSchema(schema: AnySchema): AnySchema {
if (!isOptionalSchema(schema)) {
return schema;
}
const candidate = schema as { def?: { innerType?: AnySchema } };
return candidate.def?.innerType ?? schema;
}

View file

@ -0,0 +1,180 @@
/**
* Standard Schema utilities for user-provided schemas.
* Supports Zod v4, Valibot, ArkType, and other Standard Schema implementations.
* @see https://standardschema.dev
*/
/* eslint-disable @typescript-eslint/no-namespace */
// Standard Schema interfaces — vendored from https://standardschema.dev (spec v1, Jan 2025)
export interface StandardTypedV1<Input = unknown, Output = Input> {
readonly '~standard': StandardTypedV1.Props<Input, Output>;
}
export namespace StandardTypedV1 {
export interface Props<Input = unknown, Output = Input> {
readonly version: 1;
readonly vendor: string;
readonly types?: Types<Input, Output> | undefined;
}
export interface Types<Input = unknown, Output = Input> {
readonly input: Input;
readonly output: Output;
}
export type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema['~standard']['types']>['input'];
export type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema['~standard']['types']>['output'];
}
export interface StandardSchemaV1<Input = unknown, Output = Input> {
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
}
export namespace StandardSchemaV1 {
export interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
readonly validate: (value: unknown, options?: Options | undefined) => Result<Output> | Promise<Result<Output>>;
}
export interface Options {
readonly libraryOptions?: Record<string, unknown> | undefined;
}
export type Result<Output> = SuccessResult<Output> | FailureResult;
export interface SuccessResult<Output> {
readonly value: Output;
readonly issues?: undefined;
}
export interface FailureResult {
readonly issues: ReadonlyArray<Issue>;
}
export interface Issue {
readonly message: string;
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
}
export interface PathSegment {
readonly key: PropertyKey;
}
export type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
export type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
}
export interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
readonly '~standard': StandardJSONSchemaV1.Props<Input, Output>;
}
export namespace StandardJSONSchemaV1 {
export interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
readonly jsonSchema: Converter;
}
export interface Converter {
readonly input: (options: Options) => Record<string, unknown>;
readonly output: (options: Options) => Record<string, unknown>;
}
export type Target = 'draft-2020-12' | 'draft-07' | 'openapi-3.0' | (object & string);
export interface Options {
readonly target: Target;
readonly libraryOptions?: Record<string, unknown> | undefined;
}
export type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
export type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
}
/**
* Combined interface for schemas with both validation and JSON Schema conversion —
* the intersection of {@linkcode StandardSchemaV1} and {@linkcode StandardJSONSchemaV1}.
*
* This is the type accepted by `registerTool` / `registerPrompt`. The SDK needs
* `~standard.jsonSchema` to advertise the tool's argument shape in `tools/list`, and
* `~standard.validate` to check incoming arguments when a `tools/call` arrives.
*
* Zod v4, ArkType, and Valibot (via `@valibot/to-json-schema`'s `toStandardJsonSchema`)
* all implement both interfaces.
*
* @see https://standardschema.dev/ for the Standard Schema specification
*/
export interface StandardSchemaWithJSON<Input = unknown, Output = Input> {
readonly '~standard': StandardSchemaV1.Props<Input, Output> & StandardJSONSchemaV1.Props<Input, Output>;
}
export namespace StandardSchemaWithJSON {
export type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
export type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
}
// Type guards
export function isStandardJSONSchema(schema: unknown): schema is StandardJSONSchemaV1 {
if (schema == null) return false;
const schemaType = typeof schema;
if (schemaType !== 'object' && schemaType !== 'function') return false;
if (!('~standard' in (schema as object))) return false;
const std = (schema as StandardJSONSchemaV1)['~standard'];
return typeof std?.jsonSchema?.input === 'function' && typeof std?.jsonSchema?.output === 'function';
}
export function isStandardSchema(schema: unknown): schema is StandardSchemaV1 {
if (schema == null) return false;
const schemaType = typeof schema;
if (schemaType !== 'object' && schemaType !== 'function') return false;
if (!('~standard' in (schema as object))) return false;
const std = (schema as StandardSchemaV1)['~standard'];
return typeof std?.validate === 'function';
}
export function isStandardSchemaWithJSON(schema: unknown): schema is StandardSchemaWithJSON {
return isStandardJSONSchema(schema) && isStandardSchema(schema);
}
// JSON Schema conversion
export function standardSchemaToJsonSchema(schema: StandardJSONSchemaV1, io: 'input' | 'output' = 'input'): Record<string, unknown> {
return schema['~standard'].jsonSchema[io]({ target: 'draft-2020-12' });
}
// Validation
export type StandardSchemaValidationResult<T> = { success: true; data: T } | { success: false; error: string };
function formatIssue(issue: StandardSchemaV1.Issue): string {
if (!issue.path?.length) return issue.message;
const path = issue.path.map(p => String(typeof p === 'object' ? p.key : p)).join('.');
return `${path}: ${issue.message}`;
}
export async function validateStandardSchema<T extends StandardSchemaWithJSON>(
schema: T,
data: unknown
): Promise<StandardSchemaValidationResult<StandardSchemaWithJSON.InferOutput<T>>> {
const result = await schema['~standard'].validate(data);
if (result.issues && result.issues.length > 0) {
return { success: false, error: result.issues.map(i => formatIssue(i)).join(', ') };
}
return { success: true, data: (result as StandardSchemaV1.SuccessResult<unknown>).value as StandardSchemaWithJSON.InferOutput<T> };
}
// Prompt argument extraction
export function promptArgumentsFromStandardSchema(
schema: StandardJSONSchemaV1
): Array<{ name: string; description?: string; required: boolean }> {
const jsonSchema = standardSchemaToJsonSchema(schema, 'input');
const properties = (jsonSchema.properties as Record<string, { description?: string }>) || {};
const required = (jsonSchema.required as string[]) || [];
return Object.entries(properties).map(([name, prop]) => ({
name,
description: prop?.description,
required: required.includes(name)
}));
}

View file

@ -0,0 +1,24 @@
/**
* Type-checked examples for `fromJsonSchema.ts`.
*
* These examples are synced into JSDoc comments via the sync-snippets script.
*
* @module
*/
import { AjvJsonSchemaValidator } from './ajvProvider.js';
import { fromJsonSchema } from './fromJsonSchema.js';
/**
* Example: wrap a raw JSON Schema object for use with registerTool.
*/
function fromJsonSchema_basicUsage() {
//#region fromJsonSchema_basicUsage
const inputSchema = fromJsonSchema<{ name: string }>(
{ type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
new AjvJsonSchemaValidator()
);
// Use with server.registerTool('greet', { inputSchema }, handler)
//#endregion fromJsonSchema_basicUsage
return inputSchema;
}

View file

@ -0,0 +1,38 @@
import type { StandardSchemaV1, StandardSchemaWithJSON } from '../util/standardSchema.js';
import type { JsonSchemaType, jsonSchemaValidator } from './types.js';
/**
* Wrap a raw JSON Schema object as a {@linkcode StandardSchemaWithJSON} so it can be
* passed to `registerTool` / `registerPrompt`. Use this when you already have JSON
* Schema (e.g. from TypeBox, or hand-written) and want to register it without going
* through a Standard Schema library.
*
* The callback arguments will be typed `unknown` (raw JSON Schema has no TypeScript
* types attached). Cast at the call site, or use the generic `fromJsonSchema<MyType>(...)`.
*
* @example
* ```ts source="./fromJsonSchema.examples.ts#fromJsonSchema_basicUsage"
* const inputSchema = fromJsonSchema<{ name: string }>(
* { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
* new AjvJsonSchemaValidator()
* );
* // Use with server.registerTool('greet', { inputSchema }, handler)
* ```
*/
export function fromJsonSchema<T = unknown>(schema: JsonSchemaType, validator: jsonSchemaValidator): StandardSchemaWithJSON<T, T> {
const check = validator.getValidator<T>(schema);
return {
'~standard': {
version: 1,
vendor: 'mcp',
jsonSchema: {
input: () => schema as Record<string, unknown>,
output: () => schema as Record<string, unknown>
},
validate: (data: unknown): StandardSchemaV1.Result<T> => {
const result = check(data);
return result.valid ? { value: result.data } : { issues: [{ message: result.errorMessage }] };
}
}
};
}

View file

@ -4,12 +4,12 @@
*/
import type {
AnySchema,
CallToolResult,
CreateTaskResult,
CreateTaskServerContext,
GetTaskResult,
Result,
StandardSchemaWithJSON,
TaskServerContext
} from '@modelcontextprotocol/core';
@ -23,18 +23,17 @@ import type { BaseToolCallback } from '../../server/mcp.js';
* Handler for creating a task.
* @experimental
*/
export type CreateTaskRequestHandler<ResultT extends Result, Args extends AnySchema | undefined = undefined> = BaseToolCallback<
ResultT,
CreateTaskServerContext,
Args
>;
export type CreateTaskRequestHandler<
SendResultT extends Result,
Args extends StandardSchemaWithJSON | undefined = undefined
> = BaseToolCallback<SendResultT, CreateTaskServerContext, Args>;
/**
* Handler for task operations (`get`, `getResult`).
* @experimental
*/
export type TaskRequestHandler<ResultT extends Result, Args extends AnySchema | undefined = undefined> = BaseToolCallback<
ResultT,
export type TaskRequestHandler<SendResultT extends Result, Args extends StandardSchemaWithJSON | undefined = undefined> = BaseToolCallback<
SendResultT,
TaskServerContext,
Args
>;
@ -48,7 +47,7 @@ export type TaskRequestHandler<ResultT extends Result, Args extends AnySchema |
* @see {@linkcode @modelcontextprotocol/server!experimental/tasks/mcpServer.ExperimentalMcpServerTasks#registerToolTask | registerToolTask} for registration.
* @experimental
*/
export interface ToolTaskHandler<Args extends AnySchema | undefined = undefined> {
export interface ToolTaskHandler<Args extends StandardSchemaWithJSON | undefined = undefined> {
/**
* Called on the initial `tools/call` request.
*

View file

@ -5,7 +5,7 @@
* @experimental
*/
import type { AnySchema, TaskToolExecution, ToolAnnotations, ToolExecution } from '@modelcontextprotocol/core';
import type { StandardSchemaWithJSON, TaskToolExecution, ToolAnnotations, ToolExecution } from '@modelcontextprotocol/core';
import type { AnyToolHandler, McpServer, RegisteredTool } from '../../server/mcp.js';
import type { ToolTaskHandler } from './interfaces.js';
@ -19,12 +19,12 @@ interface McpServerInternal {
name: string,
title: string | undefined,
description: string | undefined,
inputSchema: AnySchema | undefined,
outputSchema: AnySchema | undefined,
inputSchema: StandardSchemaWithJSON | undefined,
outputSchema: StandardSchemaWithJSON | undefined,
annotations: ToolAnnotations | undefined,
execution: ToolExecution | undefined,
_meta: Record<string, unknown> | undefined,
handler: AnyToolHandler<AnySchema | undefined>
handler: AnyToolHandler<StandardSchemaWithJSON | undefined>
): RegisteredTool;
}
@ -76,7 +76,7 @@ export class ExperimentalMcpServerTasks {
*
* @experimental
*/
registerToolTask<OutputArgs extends AnySchema | undefined>(
registerToolTask<OutputArgs extends StandardSchemaWithJSON | undefined>(
name: string,
config: {
title?: string;
@ -89,7 +89,7 @@ export class ExperimentalMcpServerTasks {
handler: ToolTaskHandler<undefined>
): RegisteredTool;
registerToolTask<InputArgs extends AnySchema, OutputArgs extends AnySchema | undefined>(
registerToolTask<InputArgs extends StandardSchemaWithJSON, OutputArgs extends StandardSchemaWithJSON | undefined>(
name: string,
config: {
title?: string;
@ -103,7 +103,7 @@ export class ExperimentalMcpServerTasks {
handler: ToolTaskHandler<InputArgs>
): RegisteredTool;
registerToolTask<InputArgs extends AnySchema | undefined, OutputArgs extends AnySchema | undefined>(
registerToolTask<InputArgs extends StandardSchemaWithJSON | undefined, OutputArgs extends StandardSchemaWithJSON | undefined>(
name: string,
config: {
title?: string;
@ -133,7 +133,7 @@ export class ExperimentalMcpServerTasks {
config.annotations,
execution,
config._meta,
handler as AnyToolHandler<AnySchema | undefined>
handler as AnyToolHandler<StandardSchemaWithJSON | undefined>
);
}
}

View file

@ -6,21 +6,21 @@
*/
import type {
AnySchema,
CancelTaskResult,
CreateMessageRequestParams,
CreateMessageResult,
ElicitRequestFormParams,
ElicitRequestURLParams,
ElicitResult,
GetTaskPayloadResult,
GetTaskResult,
ListTasksResult,
RequestMethod,
RequestOptions,
ResponseMessage,
ResultTypeMap,
SchemaOutput
ResultTypeMap
} from '@modelcontextprotocol/core';
import { GetTaskPayloadResultSchema } from '@modelcontextprotocol/core';
import type { Server } from '../../server/server.js';
@ -258,22 +258,22 @@ export class ExperimentalServerTasks {
* Retrieves the result of a completed task.
*
* @param taskId - The task identifier
* @param resultSchema - Zod schema for validating the result
* @param options - Optional request options
* @returns The task result
* @returns The task result. The payload structure matches the result type of the
* original request (e.g., a `tools/call` task returns a `CallToolResult`).
*
* @experimental
*/
async getTaskResult<T extends AnySchema>(taskId: string, resultSchema?: T, options?: RequestOptions): Promise<SchemaOutput<T>> {
async getTaskResult(taskId: string, options?: RequestOptions): Promise<GetTaskPayloadResult> {
return (
this._server as unknown as {
getTaskResult: <U extends AnySchema>(
getTaskResult: (
params: { taskId: string },
resultSchema?: U,
resultSchema: typeof GetTaskPayloadResultSchema,
options?: RequestOptions
) => Promise<SchemaOutput<U>>;
) => Promise<GetTaskPayloadResult>;
}
).getTaskResult({ taskId }, resultSchema, options);
).getTaskResult({ taskId }, GetTaskPayloadResultSchema, options);
}
/**

View file

@ -1,25 +1,24 @@
import type { AnySchema } from '@modelcontextprotocol/core';
import type * as z from 'zod/v4';
import type { StandardSchemaWithJSON } from '@modelcontextprotocol/core';
export const COMPLETABLE_SYMBOL: unique symbol = Symbol.for('mcp.completable');
export type CompleteCallback<T extends AnySchema = AnySchema> = (
value: z.input<T>,
export type CompleteCallback<T extends StandardSchemaWithJSON = StandardSchemaWithJSON> = (
value: StandardSchemaWithJSON.InferInput<T>,
context?: {
arguments?: Record<string, string>;
}
) => z.input<T>[] | Promise<z.input<T>[]>;
) => StandardSchemaWithJSON.InferInput<T>[] | Promise<StandardSchemaWithJSON.InferInput<T>[]>;
export type CompletableMeta<T extends AnySchema = AnySchema> = {
export type CompletableMeta<T extends StandardSchemaWithJSON = StandardSchemaWithJSON> = {
complete: CompleteCallback<T>;
};
export type CompletableSchema<T extends AnySchema> = T & {
export type CompletableSchema<T extends StandardSchemaWithJSON> = T & {
[COMPLETABLE_SYMBOL]: CompletableMeta<T>;
};
/**
* Wraps a Zod type to provide autocompletion capabilities. Useful for, e.g., prompt arguments in MCP.
* Wraps a schema to provide autocompletion capabilities. Useful for, e.g., prompt arguments in MCP.
*
* @example
* ```ts source="./completable.examples.ts#completable_basicUsage"
@ -49,7 +48,7 @@ export type CompletableSchema<T extends AnySchema> = T & {
*
* @see {@linkcode server/mcp.McpServer.registerPrompt | McpServer.registerPrompt} for using completable schemas in prompt argument definitions
*/
export function completable<T extends AnySchema>(schema: T, complete: CompleteCallback<T>): CompletableSchema<T> {
export function completable<T extends StandardSchemaWithJSON>(schema: T, complete: CompleteCallback<T>): CompletableSchema<T> {
Object.defineProperty(schema as object, COMPLETABLE_SYMBOL, {
value: { complete } as CompletableMeta<T>,
enumerable: false,
@ -62,14 +61,14 @@ export function completable<T extends AnySchema>(schema: T, complete: CompleteCa
/**
* Checks if a schema is completable (has completion metadata).
*/
export function isCompletable(schema: unknown): schema is CompletableSchema<AnySchema> {
export function isCompletable(schema: unknown): schema is CompletableSchema<StandardSchemaWithJSON> {
return !!schema && typeof schema === 'object' && COMPLETABLE_SYMBOL in (schema as object);
}
/**
* Gets the completer callback from a completable schema, if it exists.
*/
export function getCompleter<T extends AnySchema>(schema: T): CompleteCallback<T> | undefined {
export function getCompleter<T extends StandardSchemaWithJSON>(schema: T): CompleteCallback<T> | undefined {
const meta = (schema as unknown as { [COMPLETABLE_SYMBOL]?: CompletableMeta<T> })[COMPLETABLE_SYMBOL];
return meta?.complete as CompleteCallback<T> | undefined;
}

View file

@ -1,5 +1,4 @@
import type {
AnySchema,
BaseMetadata,
CallToolRequest,
CallToolResult,
@ -15,14 +14,13 @@ import type {
ListToolsResult,
LoggingMessageNotification,
Prompt,
PromptArgument,
PromptReference,
ReadResourceResult,
Resource,
ResourceTemplateReference,
Result,
SchemaOutput,
ServerContext,
StandardSchemaWithJSON,
Tool,
ToolAnnotations,
ToolExecution,
@ -32,16 +30,13 @@ import type {
import {
assertCompleteRequestPrompt,
assertCompleteRequestResourceTemplate,
getSchemaDescription,
getSchemaShape,
isOptionalSchema,
parseSchemaAsync,
promptArgumentsFromStandardSchema,
ProtocolError,
ProtocolErrorCode,
schemaToJson,
unwrapOptionalSchema,
standardSchemaToJsonSchema,
UriTemplate,
validateAndWarnToolName
validateAndWarnToolName,
validateStandardSchema
} from '@modelcontextprotocol/core';
import type { ToolTaskHandler } from '../experimental/tasks/interfaces.js';
@ -147,7 +142,7 @@ export class McpServer {
title: tool.title,
description: tool.description,
inputSchema: tool.inputSchema
? (schemaToJson(tool.inputSchema, { io: 'input' }) as Tool['inputSchema'])
? (standardSchemaToJsonSchema(tool.inputSchema, 'input') as Tool['inputSchema'])
: EMPTY_OBJECT_JSON_SCHEMA,
annotations: tool.annotations,
execution: tool.execution,
@ -155,9 +150,7 @@ export class McpServer {
};
if (tool.outputSchema) {
toolDefinition.outputSchema = schemaToJson(tool.outputSchema, {
io: 'output'
}) as Tool['outputSchema'];
toolDefinition.outputSchema = standardSchemaToJsonSchema(tool.outputSchema, 'output') as Tool['outputSchema'];
}
return toolDefinition;
@ -177,7 +170,7 @@ export class McpServer {
try {
const isTaskRequest = !!request.params.task;
const taskSupport = tool.execution?.taskSupport;
const isTaskHandler = 'createTask' in (tool.handler as AnyToolHandler<AnySchema>);
const isTaskHandler = 'createTask' in (tool.handler as AnyToolHandler<StandardSchemaWithJSON>);
// Validate task hint configuration
if ((taskSupport === 'required' || taskSupport === 'optional') && !isTaskHandler) {
@ -245,23 +238,22 @@ export class McpServer {
* Validates tool input arguments against the tool's input schema.
*/
private async validateToolInput<
Tool extends RegisteredTool,
Args extends Tool['inputSchema'] extends infer InputSchema
? InputSchema extends AnySchema
? SchemaOutput<InputSchema>
ToolType extends RegisteredTool,
Args extends ToolType['inputSchema'] extends infer InputSchema
? InputSchema extends StandardSchemaWithJSON
? StandardSchemaWithJSON.InferOutput<InputSchema>
: undefined
: undefined
>(tool: Tool, args: Args, toolName: string): Promise<Args> {
>(tool: ToolType, args: Args, toolName: string): Promise<Args> {
if (!tool.inputSchema) {
return undefined as Args;
}
const parseResult = await parseSchemaAsync(tool.inputSchema, args ?? {});
const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {});
if (!parseResult.success) {
const errorMessage = parseResult.error.issues.map((i: { message: string }) => i.message).join(', ');
throw new ProtocolError(
ProtocolErrorCode.InvalidParams,
`Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage}`
`Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`
);
}
@ -293,12 +285,11 @@ export class McpServer {
}
// if the tool has an output schema, validate structured content
const parseResult = await parseSchemaAsync(tool.outputSchema, result.structuredContent);
const parseResult = await validateStandardSchema(tool.outputSchema, result.structuredContent);
if (!parseResult.success) {
const errorMessage = parseResult.error.issues.map((i: { message: string }) => i.message).join(', ');
throw new ProtocolError(
ProtocolErrorCode.InvalidParams,
`Output validation error: Invalid structured content for tool ${toolName}: ${errorMessage}`
`Output validation error: Invalid structured content for tool ${toolName}: ${parseResult.error}`
);
}
}
@ -394,7 +385,7 @@ export class McpServer {
}
const promptShape = getSchemaShape(prompt.argsSchema);
const field = promptShape?.[request.params.argument.name];
const field = unwrapOptionalSchema(promptShape?.[request.params.argument.name]);
if (!isCompletable(field)) {
return EMPTY_COMPLETION_RESULT;
}
@ -403,6 +394,7 @@ export class McpServer {
if (!completer) {
return EMPTY_COMPLETION_RESULT;
}
const suggestions = await completer(request.params.argument.value, request.params.context);
return createCompletionResult(suggestions);
}
@ -538,7 +530,7 @@ export class McpServer {
name,
title: prompt.title,
description: prompt.description,
arguments: prompt.argsSchema ? promptArgumentsFromSchema(prompt.argsSchema) : undefined
arguments: prompt.argsSchema ? promptArgumentsFromStandardSchema(prompt.argsSchema) : undefined
};
})
})
@ -706,8 +698,8 @@ export class McpServer {
name: string,
title: string | undefined,
description: string | undefined,
argsSchema: AnySchema | undefined,
callback: PromptCallback<AnySchema | undefined>
argsSchema: StandardSchemaWithJSON | undefined,
callback: PromptCallback<StandardSchemaWithJSON | undefined>
): RegisteredPrompt {
// Track current schema and callback for handler regeneration
let currentArgsSchema = argsSchema;
@ -738,7 +730,7 @@ export class McpServer {
needsHandlerRegen = true;
}
if (updates.callback !== undefined) {
currentCallback = updates.callback as PromptCallback<AnySchema | undefined>;
currentCallback = updates.callback as PromptCallback<StandardSchemaWithJSON | undefined>;
needsHandlerRegen = true;
}
if (needsHandlerRegen) {
@ -772,12 +764,12 @@ export class McpServer {
name: string,
title: string | undefined,
description: string | undefined,
inputSchema: AnySchema | undefined,
outputSchema: AnySchema | undefined,
inputSchema: StandardSchemaWithJSON | undefined,
outputSchema: StandardSchemaWithJSON | undefined,
annotations: ToolAnnotations | undefined,
execution: ToolExecution | undefined,
_meta: Record<string, unknown> | undefined,
handler: AnyToolHandler<AnySchema | undefined>
handler: AnyToolHandler<StandardSchemaWithJSON | undefined>
): RegisteredTool {
// Validate tool name according to SEP specification
validateAndWarnToolName(name);
@ -818,7 +810,7 @@ export class McpServer {
}
if (updates.callback !== undefined) {
registeredTool.handler = updates.callback;
currentHandler = updates.callback as AnyToolHandler<AnySchema | undefined>;
currentHandler = updates.callback as AnyToolHandler<StandardSchemaWithJSON | undefined>;
needsExecutorRegen = true;
}
if (needsExecutorRegen) {
@ -866,7 +858,7 @@ export class McpServer {
* );
* ```
*/
registerTool<OutputArgs extends AnySchema, InputArgs extends AnySchema | undefined = undefined>(
registerTool<OutputArgs extends StandardSchemaWithJSON, InputArgs extends StandardSchemaWithJSON | undefined = undefined>(
name: string,
config: {
title?: string;
@ -893,7 +885,7 @@ export class McpServer {
annotations,
{ taskSupport: 'forbidden' },
_meta,
cb as ToolCallback<AnySchema | undefined>
cb as ToolCallback<StandardSchemaWithJSON | undefined>
);
}
@ -923,7 +915,7 @@ export class McpServer {
* );
* ```
*/
registerPrompt<Args extends AnySchema>(
registerPrompt<Args extends StandardSchemaWithJSON>(
name: string,
config: {
title?: string;
@ -943,7 +935,7 @@ export class McpServer {
title,
description,
argsSchema,
cb as PromptCallback<AnySchema | undefined>
cb as PromptCallback<StandardSchemaWithJSON | undefined>
);
this.setPromptRequestHandlers();
@ -1064,19 +1056,27 @@ export class ResourceTemplate {
}
}
export type BaseToolCallback<ResultT extends Result, Ctx extends ServerContext, Args extends AnySchema | undefined> = Args extends AnySchema
? (args: SchemaOutput<Args>, ctx: Ctx) => ResultT | Promise<ResultT>
: (ctx: Ctx) => ResultT | Promise<ResultT>;
export type BaseToolCallback<
SendResultT extends Result,
Ctx extends ServerContext,
Args extends StandardSchemaWithJSON | undefined
> = Args extends StandardSchemaWithJSON
? (args: StandardSchemaWithJSON.InferOutput<Args>, ctx: Ctx) => SendResultT | Promise<SendResultT>
: (ctx: Ctx) => SendResultT | Promise<SendResultT>;
/**
* Callback for a tool handler registered with {@linkcode McpServer.registerTool}.
*/
export type ToolCallback<Args extends AnySchema | undefined = undefined> = BaseToolCallback<CallToolResult, ServerContext, Args>;
export type ToolCallback<Args extends StandardSchemaWithJSON | undefined = undefined> = BaseToolCallback<
CallToolResult,
ServerContext,
Args
>;
/**
* Supertype that can handle both regular tools (simple callback) and task-based tools (task handler object).
*/
export type AnyToolHandler<Args extends AnySchema | undefined = undefined> = ToolCallback<Args> | ToolTaskHandler<Args>;
export type AnyToolHandler<Args extends StandardSchemaWithJSON | undefined = undefined> = ToolCallback<Args> | ToolTaskHandler<Args>;
/**
* Internal executor type that encapsulates handler invocation with proper types.
@ -1086,12 +1086,12 @@ type ToolExecutor = (args: unknown, ctx: ServerContext) => Promise<CallToolResul
export type RegisteredTool = {
title?: string;
description?: string;
inputSchema?: AnySchema;
outputSchema?: AnySchema;
inputSchema?: StandardSchemaWithJSON;
outputSchema?: StandardSchemaWithJSON;
annotations?: ToolAnnotations;
execution?: ToolExecution;
_meta?: Record<string, unknown>;
handler: AnyToolHandler<AnySchema | undefined>;
handler: AnyToolHandler<StandardSchemaWithJSON | undefined>;
/** @hidden */
executor: ToolExecutor;
enabled: boolean;
@ -1101,11 +1101,11 @@ export type RegisteredTool = {
name?: string | null;
title?: string;
description?: string;
paramsSchema?: AnySchema;
outputSchema?: AnySchema;
paramsSchema?: StandardSchemaWithJSON;
outputSchema?: StandardSchemaWithJSON;
annotations?: ToolAnnotations;
_meta?: Record<string, unknown>;
callback?: ToolCallback<AnySchema>;
callback?: ToolCallback<StandardSchemaWithJSON>;
enabled?: boolean;
}): void;
remove(): void;
@ -1116,7 +1116,10 @@ export type RegisteredTool = {
* When `inputSchema` is defined, the handler is called with `(args, ctx)`.
* When `inputSchema` is undefined, the handler is called with just `(ctx)`.
*/
function createToolExecutor(inputSchema: AnySchema | undefined, handler: AnyToolHandler<AnySchema | undefined>): ToolExecutor {
function createToolExecutor(
inputSchema: StandardSchemaWithJSON | undefined,
handler: AnyToolHandler<StandardSchemaWithJSON | undefined>
): ToolExecutor {
const isTaskHandler = 'createTask' in handler;
if (isTaskHandler) {
@ -1211,8 +1214,8 @@ export type RegisteredResourceTemplate = {
remove(): void;
};
export type PromptCallback<Args extends AnySchema | undefined = undefined> = Args extends AnySchema
? (args: SchemaOutput<Args>, ctx: ServerContext) => GetPromptResult | Promise<GetPromptResult>
export type PromptCallback<Args extends StandardSchemaWithJSON | undefined = undefined> = Args extends StandardSchemaWithJSON
? (args: StandardSchemaWithJSON.InferOutput<Args>, ctx: ServerContext) => GetPromptResult | Promise<GetPromptResult>
: (ctx: ServerContext) => GetPromptResult | Promise<GetPromptResult>;
/**
@ -1230,13 +1233,13 @@ type TaskHandlerInternal = {
export type RegisteredPrompt = {
title?: string;
description?: string;
argsSchema?: AnySchema;
argsSchema?: StandardSchemaWithJSON;
/** @hidden */
handler: PromptHandler;
enabled: boolean;
enable(): void;
disable(): void;
update<Args extends AnySchema>(updates: {
update<Args extends StandardSchemaWithJSON>(updates: {
name?: string | null;
title?: string;
description?: string;
@ -1253,19 +1256,18 @@ export type RegisteredPrompt = {
*/
function createPromptHandler(
name: string,
argsSchema: AnySchema | undefined,
callback: PromptCallback<AnySchema | undefined>
argsSchema: StandardSchemaWithJSON | undefined,
callback: PromptCallback<StandardSchemaWithJSON | undefined>
): PromptHandler {
if (argsSchema) {
const typedCallback = callback as (args: SchemaOutput<AnySchema>, ctx: ServerContext) => GetPromptResult | Promise<GetPromptResult>;
const typedCallback = callback as (args: unknown, ctx: ServerContext) => GetPromptResult | Promise<GetPromptResult>;
return async (args, ctx) => {
const parseResult = await parseSchemaAsync(argsSchema, args);
const parseResult = await validateStandardSchema(argsSchema, args);
if (!parseResult.success) {
const errorMessage = parseResult.error.issues.map((i: { message: string }) => i.message).join(', ');
throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${errorMessage}`);
throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${parseResult.error}`);
}
return typedCallback(parseResult.data as SchemaOutput<AnySchema>, ctx);
return typedCallback(parseResult.data, ctx);
};
} else {
const typedCallback = callback as (ctx: ServerContext) => GetPromptResult | Promise<GetPromptResult>;
@ -1276,18 +1278,6 @@ function createPromptHandler(
}
}
function promptArgumentsFromSchema(schema: AnySchema): PromptArgument[] {
const shape = getSchemaShape(schema);
if (!shape) return [];
return Object.entries(shape).map(([name, field]): PromptArgument => {
return {
name,
description: getSchemaDescription(field),
required: !isOptionalSchema(field)
};
});
}
function createCompletionResult(suggestions: readonly unknown[]): CompleteResult {
const values = suggestions.map(String).slice(0, 100);
return {
@ -1305,3 +1295,27 @@ const EMPTY_COMPLETION_RESULT: CompleteResult = {
hasMore: false
}
};
/** @internal Gets the shape of a Zod object schema */
function getSchemaShape(schema: unknown): Record<string, unknown> | undefined {
const candidate = schema as { shape?: unknown };
if (candidate.shape && typeof candidate.shape === 'object') {
return candidate.shape as Record<string, unknown>;
}
return undefined;
}
/** @internal Checks if a Zod schema is optional */
function isOptionalSchema(schema: unknown): boolean {
const candidate = schema as { type?: string } | null | undefined;
return candidate?.type === 'optional';
}
/** @internal Unwraps an optional Zod schema */
function unwrapOptionalSchema(schema: unknown): unknown {
if (!isOptionalSchema(schema)) {
return schema;
}
const candidate = schema as { def?: { innerType?: unknown } };
return candidate.def?.innerType ?? schema;
}

76
pnpm-lock.yaml generated
View file

@ -36,6 +36,12 @@ catalogs:
'@typescript/native-preview':
specifier: ^7.0.0-dev.20251217.1
version: 7.0.0-dev.20260105.1
'@valibot/to-json-schema':
specifier: ^1.5.0
version: 1.5.0
arktype:
specifier: ^2.1.29
version: 2.2.0
eslint:
specifier: ^9.39.2
version: 9.39.2
@ -66,6 +72,9 @@ catalogs:
typescript-eslint:
specifier: ^8.48.1
version: 8.51.0
valibot:
specifier: ^1.2.0
version: 1.2.0
vite-tsconfig-paths:
specifier: ^5.1.4
version: 5.1.4
@ -351,6 +360,12 @@ importers:
'@modelcontextprotocol/server':
specifier: workspace:^
version: link:../../packages/server
'@valibot/to-json-schema':
specifier: catalog:devTools
version: 1.5.0(valibot@1.2.0(typescript@5.9.3))
arktype:
specifier: catalog:devTools
version: 2.2.0
better-auth:
specifier: ^1.4.17
version: 1.4.17(better-sqlite3@12.6.2)(vitest@4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2))
@ -363,6 +378,9 @@ importers:
hono:
specifier: catalog:runtimeServerOnly
version: 4.11.4
valibot:
specifier: catalog:devTools
version: 1.2.0(typescript@5.9.3)
zod:
specifier: catalog:runtimeShared
version: 4.3.5
@ -963,9 +981,18 @@ importers:
'@modelcontextprotocol/vitest-config':
specifier: workspace:^
version: link:../../common/vitest-config
'@valibot/to-json-schema':
specifier: catalog:devTools
version: 1.5.0(valibot@1.2.0(typescript@5.9.3))
arktype:
specifier: catalog:devTools
version: 2.2.0
supertest:
specifier: catalog:devTools
version: 7.1.4
valibot:
specifier: catalog:devTools
version: 1.2.0(typescript@5.9.3)
vitest:
specifier: catalog:devTools
version: 4.0.16(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)
@ -987,6 +1014,12 @@ packages:
zod:
optional: true
'@ark/schema@0.56.0':
resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==}
'@ark/util@0.56.0':
resolution: {integrity: sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA==}
'@babel/generator@7.28.5':
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
engines: {node: '>=6.9.0'}
@ -2451,6 +2484,11 @@ packages:
cpu: [x64]
os: [win32]
'@valibot/to-json-schema@1.5.0':
resolution: {integrity: sha512-GE7DmSr1C2UCWPiV0upRH6mv0cCPsqYGs819fb6srCS1tWhyXrkGGe+zxUiwzn/L1BOfADH4sNjY/YHCuP8phQ==}
peerDependencies:
valibot: ^1.2.0
'@vitest/expect@4.0.16':
resolution: {integrity: sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==}
@ -2530,6 +2568,12 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
arkregex@0.0.5:
resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==}
arktype@2.2.0:
resolution: {integrity: sha512-t54MZ7ti5BhOEvzEkgKnWvqj+UbDfWig+DHr5I34xatymPusKLS0lQpNJd8M6DzmIto2QGszHfNKoFIT8tMCZQ==}
array-buffer-byte-length@1.0.2:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'}
@ -4512,6 +4556,14 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
valibot@1.2.0:
resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==}
peerDependencies:
typescript: '>=5'
peerDependenciesMeta:
typescript:
optional: true
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
@ -4714,6 +4766,12 @@ snapshots:
optionalDependencies:
zod: 4.3.5
'@ark/schema@0.56.0':
dependencies:
'@ark/util': 0.56.0
'@ark/util@0.56.0': {}
'@babel/generator@7.28.5':
dependencies:
'@babel/parser': 7.28.5
@ -5956,6 +6014,10 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
optional: true
'@valibot/to-json-schema@1.5.0(valibot@1.2.0(typescript@5.9.3))':
dependencies:
valibot: 1.2.0(typescript@5.9.3)
'@vitest/expect@4.0.16':
dependencies:
'@standard-schema/spec': 1.1.0
@ -6040,6 +6102,16 @@ snapshots:
argparse@2.0.1: {}
arkregex@0.0.5:
dependencies:
'@ark/util': 0.56.0
arktype@2.2.0:
dependencies:
'@ark/schema': 0.56.0
'@ark/util': 0.56.0
arkregex: 0.0.5
array-buffer-byte-length@1.0.2:
dependencies:
call-bound: 1.0.4
@ -8239,6 +8311,10 @@ snapshots:
util-deprecate@1.0.2: {}
valibot@1.2.0(typescript@5.9.3):
optionalDependencies:
typescript: 5.9.3
vary@1.1.2: {}
vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.0(@types/node@24.10.4)(tsx@4.21.0)(yaml@2.8.2)):

View file

@ -7,6 +7,9 @@ packages:
catalogs:
devTools:
'@eslint/js': ^9.39.2
'@valibot/to-json-schema': ^1.5.0
arktype: ^2.1.29
valibot: ^1.2.0
wrangler: ^4.14.4
'@types/content-type': ^1.1.8
'@types/cors': ^2.8.17

View file

@ -34,19 +34,22 @@
"test:integration:deno": "deno test --no-check --allow-net --allow-read --allow-env test/server/deno.test.ts"
},
"devDependencies": {
"@modelcontextprotocol/core": "workspace:^",
"@cfworker/json-schema": "catalog:runtimeShared",
"@modelcontextprotocol/client": "workspace:^",
"@modelcontextprotocol/server": "workspace:^",
"@modelcontextprotocol/core": "workspace:^",
"@modelcontextprotocol/eslint-config": "workspace:^",
"@modelcontextprotocol/express": "workspace:^",
"@modelcontextprotocol/node": "workspace:^",
"@cfworker/json-schema": "catalog:runtimeShared",
"zod": "catalog:runtimeShared",
"vitest": "catalog:devTools",
"supertest": "catalog:devTools",
"wrangler": "catalog:devTools",
"@modelcontextprotocol/server": "workspace:^",
"@modelcontextprotocol/test-helpers": "workspace:^",
"@modelcontextprotocol/tsconfig": "workspace:^",
"@modelcontextprotocol/vitest-config": "workspace:^",
"@modelcontextprotocol/eslint-config": "workspace:^",
"@modelcontextprotocol/test-helpers": "workspace:^"
"@valibot/to-json-schema": "catalog:devTools",
"arktype": "catalog:devTools",
"supertest": "catalog:devTools",
"valibot": "catalog:devTools",
"vitest": "catalog:devTools",
"wrangler": "catalog:devTools",
"zod": "catalog:runtimeShared"
}
}

Some files were not shown because too many files have changed in this diff Show more