feat: add _meta field support to tool definitions (#922)
Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com>
This commit is contained in:
parent
4de54fed0c
commit
5dd7a2b700
2 changed files with 103 additions and 2 deletions
|
|
@ -1633,6 +1633,99 @@ describe("tool()", () => {
|
|||
),
|
||||
).rejects.toThrow(/Tool nonexistent-tool not found/);
|
||||
});
|
||||
|
||||
/***
|
||||
* Test: Tool Registration with _meta field
|
||||
*/
|
||||
test("should register tool with _meta field and include it in list response", async () => {
|
||||
const mcpServer = new McpServer({
|
||||
name: "test server",
|
||||
version: "1.0",
|
||||
});
|
||||
const client = new Client({
|
||||
name: "test client",
|
||||
version: "1.0",
|
||||
});
|
||||
|
||||
const metaData = {
|
||||
author: "test-author",
|
||||
version: "1.2.3",
|
||||
category: "utility",
|
||||
tags: ["test", "example"]
|
||||
};
|
||||
|
||||
mcpServer.registerTool(
|
||||
"test-with-meta",
|
||||
{
|
||||
description: "A tool with _meta field",
|
||||
inputSchema: { name: z.string() },
|
||||
_meta: metaData,
|
||||
},
|
||||
async ({ name }) => ({
|
||||
content: [{ type: "text", text: `Hello, ${name}!` }]
|
||||
})
|
||||
);
|
||||
|
||||
const [clientTransport, serverTransport] =
|
||||
InMemoryTransport.createLinkedPair();
|
||||
|
||||
await Promise.all([
|
||||
client.connect(clientTransport),
|
||||
mcpServer.server.connect(serverTransport),
|
||||
]);
|
||||
|
||||
const result = await client.request(
|
||||
{ method: "tools/list" },
|
||||
ListToolsResultSchema,
|
||||
);
|
||||
|
||||
expect(result.tools).toHaveLength(1);
|
||||
expect(result.tools[0].name).toBe("test-with-meta");
|
||||
expect(result.tools[0].description).toBe("A tool with _meta field");
|
||||
expect(result.tools[0]._meta).toEqual(metaData);
|
||||
});
|
||||
|
||||
/***
|
||||
* Test: Tool Registration without _meta field should have undefined _meta
|
||||
*/
|
||||
test("should register tool without _meta field and have undefined _meta in response", async () => {
|
||||
const mcpServer = new McpServer({
|
||||
name: "test server",
|
||||
version: "1.0",
|
||||
});
|
||||
const client = new Client({
|
||||
name: "test client",
|
||||
version: "1.0",
|
||||
});
|
||||
|
||||
mcpServer.registerTool(
|
||||
"test-without-meta",
|
||||
{
|
||||
description: "A tool without _meta field",
|
||||
inputSchema: { name: z.string() },
|
||||
},
|
||||
async ({ name }) => ({
|
||||
content: [{ type: "text", text: `Hello, ${name}!` }]
|
||||
})
|
||||
);
|
||||
|
||||
const [clientTransport, serverTransport] =
|
||||
InMemoryTransport.createLinkedPair();
|
||||
|
||||
await Promise.all([
|
||||
client.connect(clientTransport),
|
||||
mcpServer.server.connect(serverTransport),
|
||||
]);
|
||||
|
||||
const result = await client.request(
|
||||
{ method: "tools/list" },
|
||||
ListToolsResultSchema,
|
||||
);
|
||||
|
||||
expect(result.tools).toHaveLength(1);
|
||||
expect(result.tools[0].name).toBe("test-without-meta");
|
||||
expect(result.tools[0]._meta).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resource()", () => {
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ export class McpServer {
|
|||
}) as Tool["inputSchema"])
|
||||
: EMPTY_OBJECT_JSON_SCHEMA,
|
||||
annotations: tool.annotations,
|
||||
_meta: tool._meta,
|
||||
};
|
||||
|
||||
if (tool.outputSchema) {
|
||||
|
|
@ -773,6 +774,7 @@ export class McpServer {
|
|||
inputSchema: ZodRawShape | undefined,
|
||||
outputSchema: ZodRawShape | undefined,
|
||||
annotations: ToolAnnotations | undefined,
|
||||
_meta: Record<string, unknown> | undefined,
|
||||
callback: ToolCallback<ZodRawShape | undefined>
|
||||
): RegisteredTool {
|
||||
const registeredTool: RegisteredTool = {
|
||||
|
|
@ -783,6 +785,7 @@ export class McpServer {
|
|||
outputSchema:
|
||||
outputSchema === undefined ? undefined : z.object(outputSchema),
|
||||
annotations,
|
||||
_meta,
|
||||
callback,
|
||||
enabled: true,
|
||||
disable: () => registeredTool.update({ enabled: false }),
|
||||
|
|
@ -798,6 +801,7 @@ export class McpServer {
|
|||
if (typeof updates.paramsSchema !== "undefined") registeredTool.inputSchema = z.object(updates.paramsSchema)
|
||||
if (typeof updates.callback !== "undefined") registeredTool.callback = updates.callback
|
||||
if (typeof updates.annotations !== "undefined") registeredTool.annotations = updates.annotations
|
||||
if (typeof updates._meta !== "undefined") registeredTool._meta = updates._meta
|
||||
if (typeof updates.enabled !== "undefined") registeredTool.enabled = updates.enabled
|
||||
this.sendToolListChanged()
|
||||
},
|
||||
|
|
@ -915,7 +919,7 @@ export class McpServer {
|
|||
}
|
||||
const callback = rest[0] as ToolCallback<ZodRawShape | undefined>;
|
||||
|
||||
return this._createRegisteredTool(name, undefined, description, inputSchema, outputSchema, annotations, callback)
|
||||
return this._createRegisteredTool(name, undefined, description, inputSchema, outputSchema, annotations, undefined, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -929,6 +933,7 @@ export class McpServer {
|
|||
inputSchema?: InputArgs;
|
||||
outputSchema?: OutputArgs;
|
||||
annotations?: ToolAnnotations;
|
||||
_meta?: Record<string, unknown>;
|
||||
},
|
||||
cb: ToolCallback<InputArgs>
|
||||
): RegisteredTool {
|
||||
|
|
@ -936,7 +941,7 @@ export class McpServer {
|
|||
throw new Error(`Tool ${name} is already registered`);
|
||||
}
|
||||
|
||||
const { title, description, inputSchema, outputSchema, annotations } = config;
|
||||
const { title, description, inputSchema, outputSchema, annotations, _meta } = config;
|
||||
|
||||
return this._createRegisteredTool(
|
||||
name,
|
||||
|
|
@ -945,6 +950,7 @@ export class McpServer {
|
|||
inputSchema,
|
||||
outputSchema,
|
||||
annotations,
|
||||
_meta,
|
||||
cb as ToolCallback<ZodRawShape | undefined>
|
||||
);
|
||||
}
|
||||
|
|
@ -1173,6 +1179,7 @@ export type RegisteredTool = {
|
|||
inputSchema?: AnyZodObject;
|
||||
outputSchema?: AnyZodObject;
|
||||
annotations?: ToolAnnotations;
|
||||
_meta?: Record<string, unknown>;
|
||||
callback: ToolCallback<undefined | ZodRawShape>;
|
||||
enabled: boolean;
|
||||
enable(): void;
|
||||
|
|
@ -1185,6 +1192,7 @@ export type RegisteredTool = {
|
|||
paramsSchema?: InputArgs,
|
||||
outputSchema?: OutputArgs,
|
||||
annotations?: ToolAnnotations,
|
||||
_meta?: Record<string, unknown>,
|
||||
callback?: ToolCallback<InputArgs>,
|
||||
enabled?: boolean
|
||||
}): void
|
||||
|
|
|
|||
Loading…
Reference in a new issue