Skip to content

Commit f73a5af

Browse files
chughtapanclaudefelixweinberger
authored
Add _meta support to registerPrompt (#1629)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
1 parent 9bc9abc commit f73a5af

File tree

2 files changed

+105
-4
lines changed

2 files changed

+105
-4
lines changed

packages/server/src/server/mcp.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ export class McpServer {
530530
name,
531531
title: prompt.title,
532532
description: prompt.description,
533-
arguments: prompt.argsSchema ? promptArgumentsFromStandardSchema(prompt.argsSchema) : undefined
533+
arguments: prompt.argsSchema ? promptArgumentsFromStandardSchema(prompt.argsSchema) : undefined,
534+
_meta: prompt._meta
534535
};
535536
})
536537
})
@@ -699,7 +700,8 @@ export class McpServer {
699700
title: string | undefined,
700701
description: string | undefined,
701702
argsSchema: StandardSchemaWithJSON | undefined,
702-
callback: PromptCallback<StandardSchemaWithJSON | undefined>
703+
callback: PromptCallback<StandardSchemaWithJSON | undefined>,
704+
_meta: Record<string, unknown> | undefined
703705
): RegisteredPrompt {
704706
// Track current schema and callback for handler regeneration
705707
let currentArgsSchema = argsSchema;
@@ -709,6 +711,7 @@ export class McpServer {
709711
title,
710712
description,
711713
argsSchema,
714+
_meta,
712715
handler: createPromptHandler(name, argsSchema, callback),
713716
enabled: true,
714717
disable: () => registeredPrompt.update({ enabled: false }),
@@ -721,6 +724,7 @@ export class McpServer {
721724
}
722725
if (updates.title !== undefined) registeredPrompt.title = updates.title;
723726
if (updates.description !== undefined) registeredPrompt.description = updates.description;
727+
if (updates._meta !== undefined) registeredPrompt._meta = updates._meta;
724728

725729
// Track if we need to regenerate the handler
726730
let needsHandlerRegen = false;
@@ -921,21 +925,23 @@ export class McpServer {
921925
title?: string;
922926
description?: string;
923927
argsSchema?: Args;
928+
_meta?: Record<string, unknown>;
924929
},
925930
cb: PromptCallback<Args>
926931
): RegisteredPrompt {
927932
if (this._registeredPrompts[name]) {
928933
throw new Error(`Prompt ${name} is already registered`);
929934
}
930935

931-
const { title, description, argsSchema } = config;
936+
const { title, description, argsSchema, _meta } = config;
932937

933938
const registeredPrompt = this._createRegisteredPrompt(
934939
name,
935940
title,
936941
description,
937942
argsSchema,
938-
cb as PromptCallback<StandardSchemaWithJSON | undefined>
943+
cb as PromptCallback<StandardSchemaWithJSON | undefined>,
944+
_meta
939945
);
940946

941947
this.setPromptRequestHandlers();
@@ -1234,6 +1240,7 @@ export type RegisteredPrompt = {
12341240
title?: string;
12351241
description?: string;
12361242
argsSchema?: StandardSchemaWithJSON;
1243+
_meta?: Record<string, unknown>;
12371244
/** @hidden */
12381245
handler: PromptHandler;
12391246
enabled: boolean;
@@ -1244,6 +1251,7 @@ export type RegisteredPrompt = {
12441251
title?: string;
12451252
description?: string;
12461253
argsSchema?: Args;
1254+
_meta?: Record<string, unknown>;
12471255
callback?: PromptCallback<Args>;
12481256
enabled?: boolean;
12491257
}): void;

test/integration/test/server/mcp.test.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4253,6 +4253,99 @@ describe('Zod v4', () => {
42534253
}
42544254
]);
42554255
});
4256+
4257+
/***
4258+
* Test: Prompt Registration with _meta field
4259+
*/
4260+
test('should register prompt with _meta field and include it in list response', async () => {
4261+
const mcpServer = new McpServer({
4262+
name: 'test server',
4263+
version: '1.0'
4264+
});
4265+
const client = new Client({
4266+
name: 'test client',
4267+
version: '1.0'
4268+
});
4269+
4270+
const metaData = {
4271+
author: 'test-author',
4272+
version: '1.2.3',
4273+
category: 'utility',
4274+
tags: ['test', 'example']
4275+
};
4276+
4277+
mcpServer.registerPrompt(
4278+
'test-with-meta',
4279+
{
4280+
description: 'A prompt with _meta field',
4281+
_meta: metaData
4282+
},
4283+
async () => ({
4284+
messages: [
4285+
{
4286+
role: 'assistant',
4287+
content: {
4288+
type: 'text',
4289+
text: 'Test response'
4290+
}
4291+
}
4292+
]
4293+
})
4294+
);
4295+
4296+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
4297+
4298+
await Promise.all([client.connect(clientTransport), mcpServer.server.connect(serverTransport)]);
4299+
4300+
const result = await client.request({ method: 'prompts/list' });
4301+
4302+
expect(result.prompts).toHaveLength(1);
4303+
expect(result.prompts[0]!.name).toBe('test-with-meta');
4304+
expect(result.prompts[0]!.description).toBe('A prompt with _meta field');
4305+
expect(result.prompts[0]!._meta).toEqual(metaData);
4306+
});
4307+
4308+
/***
4309+
* Test: Prompt Registration without _meta field should have undefined _meta
4310+
*/
4311+
test('should register prompt without _meta field and have undefined _meta in response', async () => {
4312+
const mcpServer = new McpServer({
4313+
name: 'test server',
4314+
version: '1.0'
4315+
});
4316+
const client = new Client({
4317+
name: 'test client',
4318+
version: '1.0'
4319+
});
4320+
4321+
mcpServer.registerPrompt(
4322+
'test-without-meta',
4323+
{
4324+
description: 'A prompt without _meta field'
4325+
},
4326+
async () => ({
4327+
messages: [
4328+
{
4329+
role: 'assistant',
4330+
content: {
4331+
type: 'text',
4332+
text: 'Test response'
4333+
}
4334+
}
4335+
]
4336+
})
4337+
);
4338+
4339+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
4340+
4341+
await Promise.all([client.connect(clientTransport), mcpServer.server.connect(serverTransport)]);
4342+
4343+
const result = await client.request({ method: 'prompts/list' });
4344+
4345+
expect(result.prompts).toHaveLength(1);
4346+
expect(result.prompts[0]!.name).toBe('test-without-meta');
4347+
expect(result.prompts[0]!._meta).toBeUndefined();
4348+
});
42564349
});
42574350

42584351
describe('Tool title precedence', () => {

0 commit comments

Comments
 (0)