-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Description
I want the output data of the call to mcp to contain outSchema, which contains field descriptions and type definitions, just like the inputSchema specification, if we achieve such a solution, and then clearly state in the prompt or skill that outputShchema can be used as an inputSchema, can we achieve automatic calls to multiple mcps?
An example of simple code to define an outputSchema is shown below
`import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Define output schemas using Zod
const AlertInfoSchema = z.object({
event: z.string().describe("Type of weather event"),
area: z.string().describe("Affected area description"),
severity: z.string().describe("Severity level of the alert"),
description: z.string().describe("Detailed description of the alert")
});
const WeatherAlertsResponseSchema = z.object({
alerts: z.array(AlertInfoSchema).describe("List of active weather alerts"),
totalCount: z.number().describe("Total number of alerts"),
state: z.string().describe("State code for the alerts")
});
const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";
// Helper function for making NWS API requests
async function makeNWSRequest(url: string): Promise<T | null> {
const headers = {
"User-Agent": USER_AGENT,
Accept: "application/geo+json",
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
return (await response.json()) as T;
} catch (error) {
console.error("Error making NWS request:", error);
return null;
}
}
interface AlertFeature {
properties: {
event?: string;
areaDesc?: string;
severity?: string;
status?: string;
headline?: string;
};
}
// Create server instance
const server = new McpServer({
name: "weather",
version: "1.0.0",
});
// Register weather tools with outputSchema
server.registerTool(
"get-alerts",
{
title: "Get Weather Alerts",
description: "Get weather alerts for a state",
inputSchema: {
state: z.string().length(2).describe("Two-letter state code (e.g. CA, NY)"),
},
outputSchema: WeatherAlertsResponseSchema, // 添加outputSchema
},
async ({ state }) => {
const stateCode = state.toUpperCase();
const alertsUrl = ${NWS_API_BASE}/alerts?area=${stateCode};
const alertsData = await makeNWSRequest(alertsUrl);
if (!alertsData) {
return {
content: [
{
type: "text",
text: "Failed to retrieve alerts data",
},
],
structuredContent: {
alerts: [],
totalCount: 0,
state: stateCode
}
};
}
const features = alertsData.features || [];
if (features.length === 0) {
return {
content: [
{
type: "text",
text: `No active alerts for ${stateCode}`,
},
],
structuredContent: {
alerts: [],
totalCount: 0,
state: stateCode
}
};
}
// Transform alerts to match outputSchema
const alerts = features.map((feature: AlertFeature) => ({
event: feature.properties.event || "Unknown",
area: feature.properties.areaDesc || "Unknown",
severity: feature.properties.severity || "Unknown",
description: feature.properties.headline || "No description available"
}));
const alertsText = `Active alerts for ${stateCode}:\n\n${alerts.map(alert =>
`Event: ${alert.event}\nArea: ${alert.area}\nSeverity: ${alert.severity}\nDescription: ${alert.description}\n---`
).join("\n")}`;
return {
content: [
{
type: "text",
text: alertsText,
},
],
structuredContent: {
alerts,
totalCount: alerts.length,
state: stateCode
}
};
},
);
// Start the server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});`