feature: Add a tool with Structured Content and an Output Schema
Tools gained Structured Content in Specification 2025-16-18 https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content The MCP Inspector is able to handle these outputs.
This commit is contained in:
parent
9e28ac7fd1
commit
84a872145c
2 changed files with 63 additions and 0 deletions
|
|
@ -80,6 +80,15 @@ This MCP server attempts to exercise all the features of the MCP protocol. It is
|
||||||
- `pets` (enum): Favorite pet
|
- `pets` (enum): Favorite pet
|
||||||
- Returns: Confirmation of the elicitation demo with selection summary.
|
- Returns: Confirmation of the elicitation demo with selection summary.
|
||||||
|
|
||||||
|
10. `structuredContent`
|
||||||
|
- Demonstrates a tool returning structured content using the example in the specification
|
||||||
|
- Provides an output schema to allow testing of client SHOULD advisory to validate the result using the schema
|
||||||
|
- Inputs:
|
||||||
|
- `location` (string): A location or ZIP code, mock data is returned regardless of value
|
||||||
|
- Returns: a response with
|
||||||
|
- `structuredContent` field conformant to the output schema
|
||||||
|
- A backward compatible Text Content field, a SHOULD advisory in the specification
|
||||||
|
|
||||||
### Resources
|
### Resources
|
||||||
|
|
||||||
The server provides 100 test resources in two formats:
|
The server provides 100 test resources in two formats:
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ const instructions = readFileSync(join(__dirname, "instructions.md"), "utf-8");
|
||||||
const ToolInputSchema = ToolSchema.shape.inputSchema;
|
const ToolInputSchema = ToolSchema.shape.inputSchema;
|
||||||
type ToolInput = z.infer<typeof ToolInputSchema>;
|
type ToolInput = z.infer<typeof ToolInputSchema>;
|
||||||
|
|
||||||
|
const ToolOutputSchema = ToolSchema.shape.outputSchema;
|
||||||
|
type ToolOutput = z.infer<typeof ToolOutputSchema>;
|
||||||
|
|
||||||
/* Input schemas for tools implemented in this server */
|
/* Input schemas for tools implemented in this server */
|
||||||
const EchoSchema = z.object({
|
const EchoSchema = z.object({
|
||||||
message: z.string().describe("Message to echo"),
|
message: z.string().describe("Message to echo"),
|
||||||
|
|
@ -93,6 +96,28 @@ const GetResourceLinksSchema = z.object({
|
||||||
.describe("Number of resource links to return (1-10)"),
|
.describe("Number of resource links to return (1-10)"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const StructuredContentSchema = {
|
||||||
|
input: z.object({
|
||||||
|
location: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(1)
|
||||||
|
.describe("City name or zip code"),
|
||||||
|
}),
|
||||||
|
|
||||||
|
output: z.object({
|
||||||
|
temperature: z
|
||||||
|
.number()
|
||||||
|
.describe("Temperature in celsius"),
|
||||||
|
conditions: z
|
||||||
|
.string()
|
||||||
|
.describe("Weather conditions description"),
|
||||||
|
humidity: z
|
||||||
|
.number()
|
||||||
|
.describe("Humidity percentage"),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
enum ToolName {
|
enum ToolName {
|
||||||
ECHO = "echo",
|
ECHO = "echo",
|
||||||
ADD = "add",
|
ADD = "add",
|
||||||
|
|
@ -104,6 +129,7 @@ enum ToolName {
|
||||||
GET_RESOURCE_REFERENCE = "getResourceReference",
|
GET_RESOURCE_REFERENCE = "getResourceReference",
|
||||||
ELICITATION = "startElicitation",
|
ELICITATION = "startElicitation",
|
||||||
GET_RESOURCE_LINKS = "getResourceLinks",
|
GET_RESOURCE_LINKS = "getResourceLinks",
|
||||||
|
STRUCTURED_CONTENT = "structuredContent"
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PromptName {
|
enum PromptName {
|
||||||
|
|
@ -503,6 +529,13 @@ export const createServer = () => {
|
||||||
"Returns multiple resource links that reference different types of resources",
|
"Returns multiple resource links that reference different types of resources",
|
||||||
inputSchema: zodToJsonSchema(GetResourceLinksSchema) as ToolInput,
|
inputSchema: zodToJsonSchema(GetResourceLinksSchema) as ToolInput,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: ToolName.STRUCTURED_CONTENT,
|
||||||
|
description:
|
||||||
|
"Returns structured content along with an output schema for client data validation",
|
||||||
|
inputSchema: zodToJsonSchema(StructuredContentSchema.input) as ToolInput,
|
||||||
|
outputSchema: zodToJsonSchema(StructuredContentSchema.output) as ToolOutput,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return { tools };
|
return { tools };
|
||||||
|
|
@ -777,6 +810,27 @@ export const createServer = () => {
|
||||||
return { content };
|
return { content };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name === ToolName.STRUCTURED_CONTENT) {
|
||||||
|
// The same response is returned for every input.
|
||||||
|
const validatedArgs = StructuredContentSchema.input.parse(args);
|
||||||
|
|
||||||
|
const weather = {
|
||||||
|
temperature: 22.5,
|
||||||
|
conditions: "Partly cloudy",
|
||||||
|
humidity: 65
|
||||||
|
}
|
||||||
|
|
||||||
|
const backwardCompatiblecontent = {
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify(weather)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [ backwardCompatiblecontent ],
|
||||||
|
structuredContent: weather
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(`Unknown tool: ${name}`);
|
throw new Error(`Unknown tool: ${name}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue