diff --git a/src/tools/BaseTool.ts b/src/tools/BaseTool.ts index 1531109..ffae642 100644 --- a/src/tools/BaseTool.ts +++ b/src/tools/BaseTool.ts @@ -115,6 +115,11 @@ export interface ToolExecution { taskSupport?: 'forbidden' | 'optional' | 'required'; } +export interface ToolPricing { + perCall?: number; + freeTier?: number; +} + export interface ContentAnnotations { audience?: ('user' | 'assistant')[]; priority?: number; @@ -177,6 +182,7 @@ export interface ToolProtocol extends SDKTool { icons?: MCPIcon[]; annotations?: ToolAnnotations; execution?: ToolExecution; + pricing?: ToolPricing; outputSchema?: Record; _meta?: Record; }; @@ -227,6 +233,7 @@ export abstract class MCPTool = any, TSchema icons?: MCPIcon[]; annotations?: ToolAnnotations; execution?: ToolExecution; + pricing?: ToolPricing; protected outputSchemaShape?: z.ZodObject; [key: string]: unknown; @@ -861,6 +868,7 @@ export abstract class MCPTool = any, TSchema ...(this.icons && this.icons.length > 0 && { icons: this.icons }), ...(this.annotations && Object.keys(this.annotations).length > 0 && { annotations: this.annotations }), ...(this.execution && Object.keys(this.execution).length > 0 && { execution: this.execution }), + ...(this.pricing && Object.keys(this.pricing).length > 0 && { pricing: this.pricing }), ...(this.outputSchemaShape && { outputSchema: this.generateOutputSchema() }), ...(this.app && { _meta: { diff --git a/tests/tools/tool-metadata.test.ts b/tests/tools/tool-metadata.test.ts index b5396c6..0023c88 100644 --- a/tests/tools/tool-metadata.test.ts +++ b/tests/tools/tool-metadata.test.ts @@ -42,6 +42,22 @@ class ToolWithEmptyIcons extends MCPTool { async execute() { return 'ok'; } } +class ToolWithPricing extends MCPTool { + name = 'priced_tool'; + description = 'A tool with pricing'; + pricing = { perCall: 0.001, freeTier: 100 }; + schema = schema; + async execute() { return 'ok'; } +} + +class ToolWithPartialPricing extends MCPTool { + name = 'partial_priced_tool'; + description = 'A tool with partial pricing'; + pricing = { perCall: 0.005 }; + schema = schema; + async execute() { return 'ok'; } +} + describe('Tool Metadata', () => { describe('title', () => { it('should include title in toolDefinition when set', () => { @@ -72,4 +88,21 @@ describe('Tool Metadata', () => { expect('icons' in tool.toolDefinition).toBe(false); }); }); + + describe('pricing', () => { + it('should include pricing in toolDefinition when set', () => { + const tool = new ToolWithPricing(); + expect(tool.toolDefinition.pricing).toEqual({ perCall: 0.001, freeTier: 100 }); + }); + + it('should include partial pricing in toolDefinition', () => { + const tool = new ToolWithPartialPricing(); + expect(tool.toolDefinition.pricing).toEqual({ perCall: 0.005 }); + }); + + it('should not include pricing key when not set', () => { + const tool = new BasicTool(); + expect('pricing' in tool.toolDefinition).toBe(false); + }); + }); });