@@ -2,6 +2,7 @@ import { McpAgent } from "agents/mcp";
22import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ;
33import { z } from "zod" ;
44import { createRequestHandler } from "react-router" ;
5+ import { createHtmlResource } from "@mcp-ui/server" ;
56
67declare module "react-router" {
78 export interface AppLoadContext {
@@ -26,6 +27,10 @@ export class MyMCP extends McpAgent {
2627 } ) ;
2728
2829 async init ( ) {
30+ const requestUrl = this . props . requestUrl as string ;
31+ const url = new URL ( requestUrl ) ;
32+ const requestHost = url . host ;
33+
2934 // Simple addition tool
3035 this . server . tool (
3136 "add" ,
@@ -37,46 +42,34 @@ export class MyMCP extends McpAgent {
3742
3843 // Calculator tool with multiple operations
3944 this . server . tool (
40- "calculate" ,
41- {
42- operation : z . enum ( [ "add" , "subtract" , "multiply" , "divide" ] ) ,
43- a : z . number ( ) ,
44- b : z . number ( ) ,
45- } ,
46- async ( { operation, a, b } ) => {
47- let result : number ;
48- switch ( operation ) {
49- case "add" :
50- result = a + b ;
51- break ;
52- case "subtract" :
53- result = a - b ;
54- break ;
55- case "multiply" :
56- result = a * b ;
57- break ;
58- case "divide" :
59- if ( b === 0 )
60- return {
61- content : [
62- {
63- type : "text" ,
64- text : "Error: Cannot divide by zero" ,
65- } ,
66- ] ,
67- } ;
68- result = a / b ;
69- break ;
70- }
71- return { content : [ { type : "text" , text : String ( result ) } ] } ;
72- }
45+ "show_task_status" ,
46+ "Displays a UI for the user to see the status of tasks" ,
47+ async ( ) => {
48+ const scheme = requestHost . includes ( 'localhost' ) || requestHost . includes ( '127.0.0.1' ) ? 'http' : 'https' ;
49+
50+ const pickerPageUrl = `${ scheme } ://${ requestHost } /task` ;
51+
52+ // Generate a unique URI for this specific invocation of the file picker UI.
53+ // This URI identifies the resource block itself, not the content of the iframe.
54+ const uniqueUiAppUri = `ui-app://task-manager/${ Date . now ( ) } ` ;
55+ const resourceBlock = createHtmlResource ( {
56+ uri : uniqueUiAppUri ,
57+ content : { type : "externalUrl" , iframeUrl : pickerPageUrl } ,
58+ delivery : "text" // The URL itself is delivered as text
59+ } ) ;
60+
61+ return {
62+ content : [ resourceBlock ]
63+ } ;
64+ }
7365 ) ;
7466 }
7567}
7668
7769export default {
7870 fetch ( request : Request , env : Env , ctx : ExecutionContext ) {
7971 const url = new URL ( request . url ) ;
72+ ctx . props . requestUrl = request . url ;
8073
8174 if ( url . pathname === "/sse" || url . pathname === "/sse/message" ) {
8275 return MyMCP . serveSSE ( "/sse" ) . fetch ( request , env , ctx ) ;
0 commit comments