@@ -31,6 +31,9 @@ const instructions = readFileSync(join(__dirname, "instructions.md"), "utf-8");
3131const ToolInputSchema = ToolSchema . shape . inputSchema ;
3232type ToolInput = z . infer < typeof ToolInputSchema > ;
3333
34+ const ToolOutputSchema = ToolSchema . shape . outputSchema ;
35+ type ToolOutput = z . infer < typeof ToolOutputSchema > ;
36+
3437/* Input schemas for tools implemented in this server */
3538const EchoSchema = z . object ( {
3639 message : z . string ( ) . describe ( "Message to echo" ) ,
@@ -46,7 +49,10 @@ const LongRunningOperationSchema = z.object({
4649 . number ( )
4750 . default ( 10 )
4851 . describe ( "Duration of the operation in seconds" ) ,
49- steps : z . number ( ) . default ( 5 ) . describe ( "Number of steps in the operation" ) ,
52+ steps : z
53+ . number ( )
54+ . default ( 5 )
55+ . describe ( "Number of steps in the operation" ) ,
5056} ) ;
5157
5258const PrintEnvSchema = z . object ( { } ) ;
@@ -59,13 +65,6 @@ const SampleLLMSchema = z.object({
5965 . describe ( "Maximum number of tokens to generate" ) ,
6066} ) ;
6167
62- // Example completion values
63- const EXAMPLE_COMPLETIONS = {
64- style : [ "casual" , "formal" , "technical" , "friendly" ] ,
65- temperature : [ "0" , "0.5" , "0.7" , "1.0" ] ,
66- resourceId : [ "1" , "2" , "3" , "4" , "5" ] ,
67- } ;
68-
6968const GetTinyImageSchema = z . object ( { } ) ;
7069
7170const AnnotatedMessageSchema = z . object ( {
@@ -97,6 +96,28 @@ const GetResourceLinksSchema = z.object({
9796 . describe ( "Number of resource links to return (1-10)" ) ,
9897} ) ;
9998
99+ const StructuredContentSchema = {
100+ input : z . object ( {
101+ location : z
102+ . string ( )
103+ . trim ( )
104+ . min ( 1 )
105+ . describe ( "City name or zip code" ) ,
106+ } ) ,
107+
108+ output : z . object ( {
109+ temperature : z
110+ . number ( )
111+ . describe ( "Temperature in celsius" ) ,
112+ conditions : z
113+ . string ( )
114+ . describe ( "Weather conditions description" ) ,
115+ humidity : z
116+ . number ( )
117+ . describe ( "Humidity percentage" ) ,
118+ } )
119+ } ;
120+
100121enum ToolName {
101122 ECHO = "echo" ,
102123 ADD = "add" ,
@@ -108,6 +129,7 @@ enum ToolName {
108129 GET_RESOURCE_REFERENCE = "getResourceReference" ,
109130 ELICITATION = "startElicitation" ,
110131 GET_RESOURCE_LINKS = "getResourceLinks" ,
132+ STRUCTURED_CONTENT = "structuredContent"
111133}
112134
113135enum PromptName {
@@ -116,10 +138,18 @@ enum PromptName {
116138 RESOURCE = "resource_prompt" ,
117139}
118140
141+ // Example completion values
142+ const EXAMPLE_COMPLETIONS = {
143+ style : [ "casual" , "formal" , "technical" , "friendly" ] ,
144+ temperature : [ "0" , "0.5" , "0.7" , "1.0" ] ,
145+ resourceId : [ "1" , "2" , "3" , "4" , "5" ] ,
146+ } ;
147+
119148export const createServer = ( ) => {
120149 const server = new Server (
121150 {
122151 name : "example-servers/everything" ,
152+ title : "Everything Example Server" ,
123153 version : "1.0.0" ,
124154 } ,
125155 {
@@ -179,18 +209,6 @@ export const createServer = () => {
179209 } , 20000 ) ;
180210
181211
182- // Set up update interval for stderr messages
183- stdErrUpdateInterval = setInterval ( ( ) => {
184- const shortTimestamp = new Date ( ) . toLocaleTimeString ( [ ] , {
185- hour : "2-digit" ,
186- minute : "2-digit" ,
187- second : "2-digit"
188- } ) ;
189- server . notification ( {
190- method : "notifications/stderr" ,
191- params : { content : `${ shortTimestamp } : A stderr message` } ,
192- } ) ;
193- } , 30000 ) ;
194212
195213 // Helper method to request sampling from client
196214 const requestSampling = async (
@@ -454,18 +472,18 @@ export const createServer = () => {
454472 description : "Adds two numbers" ,
455473 inputSchema : zodToJsonSchema ( AddSchema ) as ToolInput ,
456474 } ,
457- {
458- name : ToolName . PRINT_ENV ,
459- description :
460- "Prints all environment variables, helpful for debugging MCP server configuration" ,
461- inputSchema : zodToJsonSchema ( PrintEnvSchema ) as ToolInput ,
462- } ,
463475 {
464476 name : ToolName . LONG_RUNNING_OPERATION ,
465477 description :
466478 "Demonstrates a long running operation with progress updates" ,
467479 inputSchema : zodToJsonSchema ( LongRunningOperationSchema ) as ToolInput ,
468480 } ,
481+ {
482+ name : ToolName . PRINT_ENV ,
483+ description :
484+ "Prints all environment variables, helpful for debugging MCP server configuration" ,
485+ inputSchema : zodToJsonSchema ( PrintEnvSchema ) as ToolInput ,
486+ } ,
469487 {
470488 name : ToolName . SAMPLE_LLM ,
471489 description : "Samples from an LLM using MCP's sampling feature" ,
@@ -499,6 +517,13 @@ export const createServer = () => {
499517 "Returns multiple resource links that reference different types of resources" ,
500518 inputSchema : zodToJsonSchema ( GetResourceLinksSchema ) as ToolInput ,
501519 } ,
520+ {
521+ name : ToolName . STRUCTURED_CONTENT ,
522+ description :
523+ "Returns structured content along with an output schema for client data validation" ,
524+ inputSchema : zodToJsonSchema ( StructuredContentSchema . input ) as ToolInput ,
525+ outputSchema : zodToJsonSchema ( StructuredContentSchema . output ) as ToolOutput ,
526+ } ,
502527 ] ;
503528
504529 return { tools } ;
@@ -608,35 +633,6 @@ export const createServer = () => {
608633 } ;
609634 }
610635
611- if ( name === ToolName . GET_RESOURCE_REFERENCE ) {
612- const validatedArgs = GetResourceReferenceSchema . parse ( args ) ;
613- const resourceId = validatedArgs . resourceId ;
614-
615- const resourceIndex = resourceId - 1 ;
616- if ( resourceIndex < 0 || resourceIndex >= ALL_RESOURCES . length ) {
617- throw new Error ( `Resource with ID ${ resourceId } does not exist` ) ;
618- }
619-
620- const resource = ALL_RESOURCES [ resourceIndex ] ;
621-
622- return {
623- content : [
624- {
625- type : "text" ,
626- text : `Returning resource reference for Resource ${ resourceId } :` ,
627- } ,
628- {
629- type : "resource" ,
630- resource : resource ,
631- } ,
632- {
633- type : "text" ,
634- text : `You can access this resource using the URI: ${ resource . uri } ` ,
635- } ,
636- ] ,
637- } ;
638- }
639-
640636 if ( name === ToolName . ANNOTATED_MESSAGE ) {
641637 const { messageType, includeImage } = AnnotatedMessageSchema . parse ( args ) ;
642638
@@ -688,6 +684,35 @@ export const createServer = () => {
688684 return { content } ;
689685 }
690686
687+ if ( name === ToolName . GET_RESOURCE_REFERENCE ) {
688+ const validatedArgs = GetResourceReferenceSchema . parse ( args ) ;
689+ const resourceId = validatedArgs . resourceId ;
690+
691+ const resourceIndex = resourceId - 1 ;
692+ if ( resourceIndex < 0 || resourceIndex >= ALL_RESOURCES . length ) {
693+ throw new Error ( `Resource with ID ${ resourceId } does not exist` ) ;
694+ }
695+
696+ const resource = ALL_RESOURCES [ resourceIndex ] ;
697+
698+ return {
699+ content : [
700+ {
701+ type : "text" ,
702+ text : `Returning resource reference for Resource ${ resourceId } :` ,
703+ } ,
704+ {
705+ type : "resource" ,
706+ resource : resource ,
707+ } ,
708+ {
709+ type : "text" ,
710+ text : `You can access this resource using the URI: ${ resource . uri } ` ,
711+ } ,
712+ ] ,
713+ } ;
714+ }
715+
691716 if ( name === ToolName . ELICITATION ) {
692717 ElicitationSchema . parse ( args ) ;
693718
@@ -709,13 +734,13 @@ export const createServer = () => {
709734
710735 // Handle different response actions
711736 const content = [ ] ;
712-
737+
713738 if ( elicitationResult . action === 'accept' && elicitationResult . content ) {
714739 content . push ( {
715740 type : "text" ,
716741 text : `✅ User provided their favorite things!` ,
717742 } ) ;
718-
743+
719744 // Only access elicitationResult.content when action is accept
720745 const { color, number, pets } = elicitationResult . content ;
721746 content . push ( {
@@ -733,7 +758,7 @@ export const createServer = () => {
733758 text : `⚠️ User cancelled the elicitation dialog.` ,
734759 } ) ;
735760 }
736-
761+
737762 // Include raw result for debugging
738763 content . push ( {
739764 type : "text" ,
@@ -742,7 +767,7 @@ export const createServer = () => {
742767
743768 return { content } ;
744769 }
745-
770+
746771 if ( name === ToolName . GET_RESOURCE_LINKS ) {
747772 const { count } = GetResourceLinksSchema . parse ( args ) ;
748773 const content = [ ] ;
@@ -773,6 +798,27 @@ export const createServer = () => {
773798 return { content } ;
774799 }
775800
801+ if ( name === ToolName . STRUCTURED_CONTENT ) {
802+ // The same response is returned for every input.
803+ const validatedArgs = StructuredContentSchema . input . parse ( args ) ;
804+
805+ const weather = {
806+ temperature : 22.5 ,
807+ conditions : "Partly cloudy" ,
808+ humidity : 65
809+ }
810+
811+ const backwardCompatiblecontent = {
812+ type : "text" ,
813+ text : JSON . stringify ( weather )
814+ }
815+
816+ return {
817+ content : [ backwardCompatiblecontent ] ,
818+ structuredContent : weather
819+ } ;
820+ }
821+
776822 throw new Error ( `Unknown tool: ${ name } ` ) ;
777823 } ) ;
778824
0 commit comments