1- import { useState , useEffect } from "react" ;
1+ import { Client } from "mcp-typescript/client/index.js" ;
2+ import { SSEClientTransport } from "mcp-typescript/client/sse.js" ;
3+ import {
4+ ListResourcesResultSchema ,
5+ GetPromptResultSchema ,
6+ ListToolsResultSchema ,
7+ ReadResourceResultSchema ,
8+ CallToolResultSchema ,
9+ ListPromptsResultSchema ,
10+ } from "mcp-typescript/types.js" ;
11+ import { useState } from "react" ;
212import {
313 Send ,
414 Bell ,
@@ -22,7 +32,6 @@ import ToolsTab, { Tool as ToolType } from "./components/ToolsTab";
2232import History from "./components/History" ;
2333
2434const App = ( ) => {
25- const [ socket , setSocket ] = useState < WebSocket | null > ( null ) ;
2635 const [ connectionStatus , setConnectionStatus ] = useState <
2736 "disconnected" | "connected" | "error"
2837 > ( "disconnected" ) ;
@@ -39,121 +48,132 @@ const App = () => {
3948 const [ args , setArgs ] = useState < string > (
4049 "/Users/ashwin/code/example-servers/build/everything/index.js" ,
4150 ) ;
42- const [ mcpConnected , setMcpConnected ] = useState < boolean > ( false ) ;
4351 const [ requestHistory , setRequestHistory ] = useState <
44- Array < { request : string ; response : string | null } >
52+ { request : string ; response : string } [ ]
4553 > ( [ ] ) ;
54+ const [ mcpClient , setMcpClient ] = useState < Client | null > ( null ) ;
4655
47- useEffect ( ( ) => {
48- const ws = new WebSocket ( "ws://localhost:3000" ) ;
49-
50- ws . onopen = ( ) => {
51- console . log ( "Connected to WebSocket server" ) ;
52- setConnectionStatus ( "connected" ) ;
53- setSocket ( ws ) ;
54- } ;
55-
56- ws . onmessage = ( event ) => {
57- const message = JSON . parse ( event . data ) ;
58- console . log ( "Received message:" , message ) ;
59- if ( message . type === "resources" ) {
60- setResources ( message . data . resources ) ;
61- setError ( null ) ;
62- } else if ( message . type === "resource" ) {
63- setResourceContent ( JSON . stringify ( message . data , null , 2 ) ) ;
64- setError ( null ) ;
65- } else if ( message . type === "prompts" ) {
66- setPrompts ( message . data . prompts ) ;
67- setError ( null ) ;
68- } else if ( message . type === "prompt" ) {
69- setPromptContent ( JSON . stringify ( message . data , null , 2 ) ) ;
70- setError ( null ) ;
71- } else if ( message . type === "tools" ) {
72- setTools ( message . data . tools ) ;
73- setError ( null ) ;
74- } else if ( message . type === "toolResult" ) {
75- setToolResult ( JSON . stringify ( message . data , null , 2 ) ) ;
76- setError ( null ) ;
77- } else if ( message . type === "error" ) {
78- setError ( message . message ) ;
79- } else if ( message . type === "connected" ) {
80- setMcpConnected ( true ) ;
81- }
82-
83- updateRequestHistory ( message ) ;
84- } ;
85-
86- ws . onerror = ( ) => {
87- setConnectionStatus ( "error" ) ;
88- } ;
56+ const [ selectedResource , setSelectedResource ] = useState < Resource | null > (
57+ null ,
58+ ) ;
59+ const [ selectedPrompt , setSelectedPrompt ] = useState < Prompt | null > ( null ) ;
60+ const [ selectedTool , setSelectedTool ] = useState < ToolType | null > ( null ) ;
8961
90- ws . onclose = ( ) => {
91- setConnectionStatus ( "disconnected" ) ;
92- setMcpConnected ( false ) ;
93- } ;
62+ const pushHistory = ( request : object , response : object ) => {
63+ setRequestHistory ( ( prev ) => [
64+ ...prev ,
65+ { request : JSON . stringify ( request ) , response : JSON . stringify ( response ) } ,
66+ ] ) ;
67+ } ;
9468
95- return ( ) => ws . close ( ) ;
96- } , [ ] ) ;
69+ const makeRequest = async (
70+ request : Parameters < Client [ "request" ] > [ 0 ] ,
71+ schema : Parameters < Client [ "request" ] > [ 1 ] ,
72+ ) : Promise < ReturnType < Client [ "request" ] > > => {
73+ if ( ! mcpClient ) {
74+ throw new Error ( "MCP client not connected" ) ;
75+ }
9776
98- const updateRequestHistory = ( response : unknown ) => {
99- setRequestHistory ( ( prev ) => {
100- const lastRequest = prev [ prev . length - 1 ] ;
101- if ( lastRequest && lastRequest . response === null ) {
102- const updatedHistory = [ ...prev ] ;
103- updatedHistory [ updatedHistory . length - 1 ] = {
104- ...lastRequest ,
105- response : JSON . stringify ( response ) ,
106- } ;
107- return updatedHistory ;
108- }
109- return prev ;
110- } ) ;
77+ try {
78+ const response = await mcpClient . request ( request , schema ) ;
79+ pushHistory ( request , response ) ;
80+ return response ;
81+ } catch ( e : unknown ) {
82+ setError ( ( e as Error ) . message ) ;
83+ throw e ;
84+ }
11185 } ;
11286
113- const sendWebSocketMessage = ( message : object ) => {
114- if ( socket ) {
115- console . log ( "Sending WebSocket message:" , message ) ;
116- socket . send ( JSON . stringify ( message ) ) ;
117- setRequestHistory ( ( prev ) => [
118- ...prev ,
119- { request : JSON . stringify ( message ) , response : null } ,
120- ] ) ;
87+ const listResources = async ( ) => {
88+ const response = await makeRequest (
89+ {
90+ method : "resources/list" as const ,
91+ } ,
92+ ListResourcesResultSchema ,
93+ ) ;
94+ if ( response . resources ) {
95+ setResources ( response . resources ) ;
12196 }
12297 } ;
12398
124- const [ selectedResource , setSelectedResource ] = useState < Resource | null > (
125- null ,
126- ) ;
127- const [ selectedPrompt , setSelectedPrompt ] = useState < Prompt | null > ( null ) ;
128- const [ selectedTool , setSelectedTool ] = useState < ToolType | null > ( null ) ;
129-
130- const listResources = ( ) => {
131- sendWebSocketMessage ( { type : "listResources" } ) ;
99+ const readResource = async ( uri : string ) => {
100+ const response = await makeRequest (
101+ {
102+ method : "resources/read" as const ,
103+ params : { uri } ,
104+ } ,
105+ ReadResourceResultSchema ,
106+ ) ;
107+ setResourceContent ( JSON . stringify ( response , null , 2 ) ) ;
132108 } ;
133109
134- const readResource = ( uri : string ) => {
135- sendWebSocketMessage ( { type : "readResource" , uri } ) ;
110+ const listPrompts = async ( ) => {
111+ const response = await makeRequest (
112+ {
113+ method : "prompts/list" as const ,
114+ } ,
115+ ListPromptsResultSchema ,
116+ ) ;
117+ if ( response . prompts ) {
118+ setPrompts ( response . prompts ) ;
119+ }
136120 } ;
137121
138- const listPrompts = ( ) => {
139- sendWebSocketMessage ( { type : "listPrompts" } ) ;
122+ const getPrompt = async ( name : string , args : Record < string , string > = { } ) => {
123+ const response = await makeRequest (
124+ {
125+ method : "prompts/get" as const ,
126+ params : { name, arguments : args } ,
127+ } ,
128+ GetPromptResultSchema ,
129+ ) ;
130+ setPromptContent ( JSON . stringify ( response , null , 2 ) ) ;
140131 } ;
141132
142- const getPrompt = ( name : string , args : Record < string , unknown > = { } ) => {
143- sendWebSocketMessage ( { type : "getPrompt" , name, args } ) ;
133+ const listTools = async ( ) => {
134+ const response = await makeRequest (
135+ {
136+ method : "tools/list" as const ,
137+ } ,
138+ ListToolsResultSchema ,
139+ ) ;
140+ if ( response . tools ) {
141+ setTools ( response . tools ) ;
142+ }
144143 } ;
145144
146- const listTools = ( ) => {
147- sendWebSocketMessage ( { type : "listTools" } ) ;
145+ const callTool = async ( name : string , params : Record < string , unknown > ) => {
146+ const response = await makeRequest (
147+ {
148+ method : "tools/call" as const ,
149+ params : { name, arguments : params } ,
150+ } ,
151+ CallToolResultSchema ,
152+ ) ;
153+ setToolResult ( JSON . stringify ( response . toolResult , null , 2 ) ) ;
148154 } ;
149155
150- const callTool = ( name : string , params : Record < string , unknown > ) => {
151- sendWebSocketMessage ( { type : "callTool" , name, params } ) ;
152- } ;
156+ const connectMcpServer = async ( ) => {
157+ try {
158+ const client = new Client ( {
159+ name : "mcp-inspector" ,
160+ version : "0.0.1" ,
161+ } ) ;
162+
163+ const clientTransport = new SSEClientTransport ( ) ;
164+ const url = new URL ( "http://localhost:3000/sse" ) ;
165+ url . searchParams . append ( "command" , encodeURIComponent ( command ) ) ;
166+ url . searchParams . append ( "args" , encodeURIComponent ( args ) ) ;
167+ await clientTransport . connect ( url ) ;
168+
169+ await client . connect ( clientTransport ) ;
153170
154- const connectMcpServer = ( ) => {
155- const argsArray = args . split ( " " ) . filter ( ( arg ) => arg . trim ( ) !== "" ) ;
156- sendWebSocketMessage ( { type : "connect" , command, args : argsArray } ) ;
171+ setMcpClient ( client ) ;
172+ setConnectionStatus ( "connected" ) ;
173+ } catch ( e ) {
174+ console . error ( e ) ;
175+ setConnectionStatus ( "error" ) ;
176+ }
157177 } ;
158178
159179 return (
@@ -182,7 +202,7 @@ const App = () => {
182202 </ Button >
183203 </ div >
184204 </ div >
185- { mcpConnected ? (
205+ { mcpClient ? (
186206 < Tabs defaultValue = "resources" className = "w-full p-4" >
187207 < TabsList className = "mb-4 p-0" >
188208 < TabsTrigger value = "resources" >
0 commit comments