@@ -62,10 +62,21 @@ const EXAMPLE_COMPLETIONS = {
6262const GetTinyImageSchema = z . object ( { } ) ;
6363
6464const AnnotatedMessageSchema = z . object ( {
65- messageType : z . enum ( [ "error" , "success" , "debug" ] )
65+ messageType : z
66+ . enum ( [ "error" , "success" , "debug" ] )
6667 . describe ( "Type of message to demonstrate different annotation patterns" ) ,
67- includeImage : z . boolean ( ) . default ( false )
68- . describe ( "Whether to include an example image" )
68+ includeImage : z
69+ . boolean ( )
70+ . default ( false )
71+ . describe ( "Whether to include an example image" ) ,
72+ } ) ;
73+
74+ const GetResourceReferenceSchema = z . object ( {
75+ resourceId : z
76+ . number ( )
77+ . min ( 1 )
78+ . max ( 100 )
79+ . describe ( "ID of the resource to reference (1-100)" ) ,
6980} ) ;
7081
7182enum ToolName {
@@ -76,11 +87,13 @@ enum ToolName {
7687 SAMPLE_LLM = "sampleLLM" ,
7788 GET_TINY_IMAGE = "getTinyImage" ,
7889 ANNOTATED_MESSAGE = "annotatedMessage" ,
90+ GET_RESOURCE_REFERENCE = "getResourceReference" ,
7991}
8092
8193enum PromptName {
8294 SIMPLE = "simple_prompt" ,
8395 COMPLEX = "complex_prompt" ,
96+ RESOURCE = "resource_prompt" ,
8497}
8598
8699export const createServer = ( ) => {
@@ -96,7 +109,7 @@ export const createServer = () => {
96109 tools : { } ,
97110 logging : { } ,
98111 } ,
99- } ,
112+ }
100113 ) ;
101114
102115 let subscriptions : Set < string > = new Set ( ) ;
@@ -115,36 +128,37 @@ export const createServer = () => {
115128 let logLevel : LoggingLevel = "debug" ;
116129 let logsUpdateInterval : NodeJS . Timeout | undefined ;
117130 const messages = [
118- { level : "debug" , data : "Debug-level message" } ,
119- { level : "info" , data : "Info-level message" } ,
120- { level : "notice" , data : "Notice-level message" } ,
121- { level : "warning" , data : "Warning-level message" } ,
122- { level : "error" , data : "Error-level message" } ,
123- { level : "critical" , data : "Critical-level message" } ,
124- { level : "alert" , data : "Alert level-message" } ,
125- { level : "emergency" , data : "Emergency-level message" }
126- ]
127-
128- const isMessageIgnored = ( level :LoggingLevel ) :boolean => {
131+ { level : "debug" , data : "Debug-level message" } ,
132+ { level : "info" , data : "Info-level message" } ,
133+ { level : "notice" , data : "Notice-level message" } ,
134+ { level : "warning" , data : "Warning-level message" } ,
135+ { level : "error" , data : "Error-level message" } ,
136+ { level : "critical" , data : "Critical-level message" } ,
137+ { level : "alert" , data : "Alert level-message" } ,
138+ { level : "emergency" , data : "Emergency-level message" } ,
139+ ] ;
140+
141+ const isMessageIgnored = ( level : LoggingLevel ) : boolean => {
129142 const currentLevel = messages . findIndex ( ( msg ) => logLevel === msg . level ) ;
130- const messageLevel = messages . findIndex ( ( msg ) => level === msg . level ) ;
143+ const messageLevel = messages . findIndex ( ( msg ) => level === msg . level ) ;
131144 return messageLevel < currentLevel ;
132- }
145+ } ;
133146
134147 // Set up update interval for random log messages
135148 logsUpdateInterval = setInterval ( ( ) => {
136149 let message = {
137150 method : "notifications/message" ,
138151 params : messages [ Math . floor ( Math . random ( ) * messages . length ) ] ,
139- }
140- if ( ! isMessageIgnored ( message . params . level as LoggingLevel ) ) server . notification ( message ) ;
152+ } ;
153+ if ( ! isMessageIgnored ( message . params . level as LoggingLevel ) )
154+ server . notification ( message ) ;
141155 } , 15000 ) ;
142156
143157 // Helper method to request sampling from client
144158 const requestSampling = async (
145159 context : string ,
146160 uri : string ,
147- maxTokens : number = 100 ,
161+ maxTokens : number = 100
148162 ) => {
149163 const request : CreateMessageRequest = {
150164 method : "sampling/createMessage" ,
@@ -280,6 +294,17 @@ export const createServer = () => {
280294 } ,
281295 ] ,
282296 } ,
297+ {
298+ name : PromptName . RESOURCE ,
299+ description : "A prompt that includes an embedded resource reference" ,
300+ arguments : [
301+ {
302+ name : "resourceId" ,
303+ description : "Resource ID to include (1-100)" ,
304+ required : true ,
305+ } ,
306+ ] ,
307+ } ,
283308 ] ,
284309 } ;
285310 } ) ;
@@ -330,6 +355,37 @@ export const createServer = () => {
330355 } ;
331356 }
332357
358+ if ( name === PromptName . RESOURCE ) {
359+ const resourceId = parseInt ( args ?. resourceId as string , 10 ) ;
360+ if ( isNaN ( resourceId ) || resourceId < 1 || resourceId > 100 ) {
361+ throw new Error (
362+ `Invalid resourceId: ${ args ?. resourceId } . Must be a number between 1 and 100.`
363+ ) ;
364+ }
365+
366+ const resourceIndex = resourceId - 1 ;
367+ const resource = ALL_RESOURCES [ resourceIndex ] ;
368+
369+ return {
370+ messages : [
371+ {
372+ role : "user" ,
373+ content : {
374+ type : "text" ,
375+ text : `This prompt includes Resource ${ resourceId } . Please analyze the following resource:` ,
376+ } ,
377+ } ,
378+ {
379+ role : "user" ,
380+ content : {
381+ type : "resource" ,
382+ resource : resource ,
383+ } ,
384+ } ,
385+ ] ,
386+ } ;
387+ }
388+
333389 throw new Error ( `Unknown prompt: ${ name } ` ) ;
334390 } ) ;
335391
@@ -347,7 +403,8 @@ export const createServer = () => {
347403 } ,
348404 {
349405 name : ToolName . PRINT_ENV ,
350- description : "Prints all environment variables, helpful for debugging MCP server configuration" ,
406+ description :
407+ "Prints all environment variables, helpful for debugging MCP server configuration" ,
351408 inputSchema : zodToJsonSchema ( PrintEnvSchema ) as ToolInput ,
352409 } ,
353410 {
@@ -368,9 +425,16 @@ export const createServer = () => {
368425 } ,
369426 {
370427 name : ToolName . ANNOTATED_MESSAGE ,
371- description : "Demonstrates how annotations can be used to provide metadata about content" ,
428+ description :
429+ "Demonstrates how annotations can be used to provide metadata about content" ,
372430 inputSchema : zodToJsonSchema ( AnnotatedMessageSchema ) as ToolInput ,
373431 } ,
432+ {
433+ name : ToolName . GET_RESOURCE_REFERENCE ,
434+ description :
435+ "Returns a resource reference that can be used by MCP clients" ,
436+ inputSchema : zodToJsonSchema ( GetResourceReferenceSchema ) as ToolInput ,
437+ } ,
374438 ] ;
375439
376440 return { tools } ;
@@ -407,7 +471,7 @@ export const createServer = () => {
407471
408472 for ( let i = 1 ; i < steps + 1 ; i ++ ) {
409473 await new Promise ( ( resolve ) =>
410- setTimeout ( resolve , stepDuration * 1000 ) ,
474+ setTimeout ( resolve , stepDuration * 1000 )
411475 ) ;
412476
413477 if ( progressToken !== undefined ) {
@@ -450,10 +514,12 @@ export const createServer = () => {
450514 const result = await requestSampling (
451515 prompt ,
452516 ToolName . SAMPLE_LLM ,
453- maxTokens ,
517+ maxTokens
454518 ) ;
455519 return {
456- content : [ { type : "text" , text : `LLM sampling result: ${ result . content . text } ` } ] ,
520+ content : [
521+ { type : "text" , text : `LLM sampling result: ${ result . content . text } ` } ,
522+ ] ,
457523 } ;
458524 }
459525
@@ -478,6 +544,35 @@ export const createServer = () => {
478544 } ;
479545 }
480546
547+ if ( name === ToolName . GET_RESOURCE_REFERENCE ) {
548+ const validatedArgs = GetResourceReferenceSchema . parse ( args ) ;
549+ const resourceId = validatedArgs . resourceId ;
550+
551+ const resourceIndex = resourceId - 1 ;
552+ if ( resourceIndex < 0 || resourceIndex >= ALL_RESOURCES . length ) {
553+ throw new Error ( `Resource with ID ${ resourceId } does not exist` ) ;
554+ }
555+
556+ const resource = ALL_RESOURCES [ resourceIndex ] ;
557+
558+ return {
559+ content : [
560+ {
561+ type : "text" ,
562+ text : `Returning resource reference for Resource ${ resourceId } :` ,
563+ } ,
564+ {
565+ type : "resource" ,
566+ resource : resource ,
567+ } ,
568+ {
569+ type : "text" ,
570+ text : `You can access this resource using the URI: ${ resource . uri } ` ,
571+ } ,
572+ ] ,
573+ } ;
574+ }
575+
481576 if ( name === ToolName . ANNOTATED_MESSAGE ) {
482577 const { messageType, includeImage } = AnnotatedMessageSchema . parse ( args ) ;
483578
@@ -490,26 +585,26 @@ export const createServer = () => {
490585 text : "Error: Operation failed" ,
491586 annotations : {
492587 priority : 1.0 , // Errors are highest priority
493- audience : [ "user" , "assistant" ] // Both need to know about errors
494- }
588+ audience : [ "user" , "assistant" ] , // Both need to know about errors
589+ } ,
495590 } ) ;
496591 } else if ( messageType === "success" ) {
497592 content . push ( {
498593 type : "text" ,
499594 text : "Operation completed successfully" ,
500595 annotations : {
501596 priority : 0.7 , // Success messages are important but not critical
502- audience : [ "user" ] // Success mainly for user consumption
503- }
597+ audience : [ "user" ] , // Success mainly for user consumption
598+ } ,
504599 } ) ;
505600 } else if ( messageType === "debug" ) {
506601 content . push ( {
507602 type : "text" ,
508603 text : "Debug: Cache hit ratio 0.95, latency 150ms" ,
509604 annotations : {
510605 priority : 0.3 , // Debug info is low priority
511- audience : [ "assistant" ] // Technical details for assistant
512- }
606+ audience : [ "assistant" ] , // Technical details for assistant
607+ } ,
513608 } ) ;
514609 }
515610
@@ -521,8 +616,8 @@ export const createServer = () => {
521616 mimeType : "image/png" ,
522617 annotations : {
523618 priority : 0.5 ,
524- audience : [ "user" ] // Images primarily for user visualization
525- }
619+ audience : [ "user" ] , // Images primarily for user visualization
620+ } ,
526621 } ) ;
527622 }
528623
@@ -540,18 +635,19 @@ export const createServer = () => {
540635 if ( ! resourceId ) return { completion : { values : [ ] } } ;
541636
542637 // Filter resource IDs that start with the input value
543- const values = EXAMPLE_COMPLETIONS . resourceId . filter ( id =>
638+ const values = EXAMPLE_COMPLETIONS . resourceId . filter ( ( id ) =>
544639 id . startsWith ( argument . value )
545640 ) ;
546641 return { completion : { values, hasMore : false , total : values . length } } ;
547642 }
548643
549644 if ( ref . type === "ref/prompt" ) {
550645 // Handle completion for prompt arguments
551- const completions = EXAMPLE_COMPLETIONS [ argument . name as keyof typeof EXAMPLE_COMPLETIONS ] ;
646+ const completions =
647+ EXAMPLE_COMPLETIONS [ argument . name as keyof typeof EXAMPLE_COMPLETIONS ] ;
552648 if ( ! completions ) return { completion : { values : [ ] } } ;
553649
554- const values = completions . filter ( value =>
650+ const values = completions . filter ( ( value ) =>
555651 value . startsWith ( argument . value )
556652 ) ;
557653 return { completion : { values, hasMore : false , total : values . length } } ;
0 commit comments