1+ #!/usr/bin/env node
2+ /**
3+ * Example MCP server demonstrating tool outputSchema support using the low-level Server API
4+ * This server manually handles tool listing and invocation requests to return structured data
5+ * For a simpler high-level API approach, see mcpServerOutputSchema.ts
6+ */
7+
8+ import { Server } from "../../server/index.js" ;
9+ import { StdioServerTransport } from "../../server/stdio.js" ;
10+ import { CallToolRequest , CallToolRequestSchema , ErrorCode , ListToolsRequestSchema , McpError } from "../../types.js" ;
11+
12+ const server = new Server (
13+ {
14+ name : "output-schema-low-level-example" ,
15+ version : "1.0.0" ,
16+ } ,
17+ {
18+ capabilities : {
19+ tools : { } ,
20+ } ,
21+ }
22+ ) ;
23+
24+ // Tool with structured output
25+ server . setRequestHandler ( ListToolsRequestSchema , async ( ) => ( {
26+ tools : [
27+ {
28+ name : "get_weather" ,
29+ description : "Get weather information for a city" ,
30+ inputSchema : {
31+ type : "object" ,
32+ properties : {
33+ city : { type : "string" , description : "City name" } ,
34+ country : { type : "string" , description : "Country code (e.g., US, UK)" }
35+ } ,
36+ required : [ "city" , "country" ]
37+ } ,
38+ outputSchema : {
39+ type : "object" ,
40+ properties : {
41+ temperature : {
42+ type : "object" ,
43+ properties : {
44+ celsius : { type : "number" } ,
45+ fahrenheit : { type : "number" }
46+ } ,
47+ required : [ "celsius" , "fahrenheit" ]
48+ } ,
49+ conditions : {
50+ type : "string" ,
51+ enum : [ "sunny" , "cloudy" , "rainy" , "stormy" , "snowy" ]
52+ } ,
53+ humidity : { type : "number" , minimum : 0 , maximum : 100 } ,
54+ wind : {
55+ type : "object" ,
56+ properties : {
57+ speed_kmh : { type : "number" } ,
58+ direction : { type : "string" }
59+ } ,
60+ required : [ "speed_kmh" , "direction" ]
61+ }
62+ } ,
63+ required : [ "temperature" , "conditions" , "humidity" , "wind" ]
64+ }
65+ }
66+ ]
67+ } ) ) ;
68+
69+ server . setRequestHandler ( CallToolRequestSchema , async ( request : CallToolRequest ) => {
70+ switch ( request . params . name ) {
71+ case "get_weather" : {
72+ const { city, country } = request . params . arguments as { city : string ; country: string } ;
73+
74+ // Parameters are available but not used in this example
75+ void city ;
76+ void country ;
77+
78+ // Simulate weather API call
79+ const temp_c = Math . round ( ( Math . random ( ) * 35 - 5 ) * 10 ) / 10 ;
80+ const conditions = [ "sunny" , "cloudy" , "rainy" , "stormy" , "snowy" ] [ Math . floor ( Math . random ( ) * 5 ) ] ;
81+
82+ // Return structured content matching the outputSchema
83+ return {
84+ structuredContent : {
85+ temperature : {
86+ celsius : temp_c ,
87+ fahrenheit : Math . round ( ( temp_c * 9 / 5 + 32 ) * 10 ) / 10
88+ } ,
89+ conditions,
90+ humidity : Math . round ( Math . random ( ) * 100 ) ,
91+ wind : {
92+ speed_kmh : Math . round ( Math . random ( ) * 50 ) ,
93+ direction : [ "N" , "NE" , "E" , "SE" , "S" , "SW" , "W" , "NW" ] [ Math . floor ( Math . random ( ) * 8 ) ]
94+ }
95+ }
96+ } ;
97+ }
98+
99+ default:
100+ throw new McpError (
101+ ErrorCode . MethodNotFound ,
102+ `Unknown tool: ${ request . params . name } `
103+ ) ;
104+ }
105+ } ) ;
106+
107+ async function main ( ) {
108+ const transport = new StdioServerTransport ( ) ;
109+ await server . connect ( transport ) ;
110+ console . error ( "Low-level Output Schema Example Server running on stdio" ) ;
111+ }
112+
113+ main ( ) . catch ( ( error ) => {
114+ console . error ( "Server error:" , error ) ;
115+ process . exit ( 1 ) ;
116+ } ) ;
0 commit comments