1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js" ;
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" ;
3
+ import { CallToolRequestSchema , ListResourcesRequestSchema , ListToolsRequestSchema , ReadResourceRequestSchema , } from "@modelcontextprotocol/sdk/types.js" ;
4
+ import fs from 'node:fs/promises' ;
5
+
6
+ const logFilePath = '/temp/proxy_server.log' ;
7
+
8
+ const SERVER_BASE_URL = process . env . SERVER_BASE_URL || "http://localhost:7860" ;
9
+
10
+ // Create server
11
+ const server = new Server ( {
12
+ name : "springboot-proxy" ,
13
+ version : "1.0.0" ,
14
+ } , {
15
+ capabilities : {
16
+ tools : { } , // We'll load tools dynamically from Spring Boot
17
+ } ,
18
+ } ) ;
19
+
20
+ // Handler: List tools from Spring Boot
21
+ server . setRequestHandler ( ListToolsRequestSchema , async ( ) => {
22
+ try {
23
+ const response = await fetch ( "http://localhost:7860/mcp/list-tools" , {
24
+ method : "GET" ,
25
+ headers : { "Content-Type" : "application/json" }
26
+ } ) ;
27
+
28
+ if ( ! response . ok ) {
29
+ const errorMessage = `Failed to fetch tools: ${ response . statusText } ` ;
30
+ // await logToFile(errorMessage);
31
+ throw new Error ( errorMessage ) ;
32
+ }
33
+
34
+ const data = await response . json ( ) ;
35
+ // await logToFile(`Available tools from Spring Boot: ${JSON.stringify(data, null, 2)}`);
36
+ return {
37
+ tools : data . tools ,
38
+ } ;
39
+ } catch ( error ) {
40
+ console . error ( "Error listing tools:" , error ) ;
41
+ throw error ;
42
+ }
43
+ } ) ;
44
+ // Handler: Call a tool by proxying to Spring Boot
45
+ server . setRequestHandler ( CallToolRequestSchema , async ( request ) => {
46
+ try {
47
+ fs . appendFile ( logFilePath , "receivedResponseLog" , 'utf8' ) ;
48
+ // 🔍 Log the outgoing request
49
+ const outgoingRequestLog = "➡️ Sending request to Spring Boot:\n" + JSON . stringify ( {
50
+ name : request . params . name ,
51
+ arguments : request . params . arguments ?? { } ,
52
+ } , null , 2 ) ;
53
+ // await logToFile(outgoingRequestLog);
54
+
55
+ const response = await fetch ( "http://localhost:7860/mcp/call-tool" , {
56
+ method : "POST" ,
57
+ headers : { "Content-Type" : "application/json" } ,
58
+ body : JSON . stringify ( {
59
+ name : request . params . name ,
60
+ arguments : request . params . arguments ?? { } ,
61
+ } ) ,
62
+ } ) ;
63
+
64
+ // ❌ Log failure if not OK
65
+ if ( ! response . ok ) {
66
+ const errorText = await response . text ( ) ; // Read error body
67
+ const errorMessage = `❌ Tool call failed: ${ response . statusText } \n🔻 Error response body: ${ errorText } ` ;
68
+ await logToFile ( errorMessage ) ;
69
+ throw new Error ( `Tool call failed: ${ response . statusText } ` ) ;
70
+ }
71
+
72
+ // console.log(response.json());
73
+ // ✅ Log the response data
74
+ const data = await response . json ( ) ;
75
+ fs . appendFile ( logFilePath , "-----------------------------" , 'utf8' ) ;
76
+ fs . appendFile ( logFilePath , JSON . stringify ( data [ "result" ] ) , 'utf8' ) ;
77
+ fs . appendFile ( logFilePath , "-----------------------------" , 'utf8' ) ;
78
+
79
+ // Log the received response
80
+ // console.log("------------------------------------------");
81
+ // console.log("Received response from Spring Boot:", data);
82
+ // console.log("------------------------------------------");
83
+ // const receivedResponseLog = "✅ Received response from Spring Boot:\n" + JSON.stringify(data, null, 2);
84
+ // fs.appendFile(logFilePath, receivedResponseLog, 'utf8');
85
+ // let res = {"content":[{"annotations":null,"text":"Temprature for toronto is 18.0","type":"text"}],"isError":false,"_meta":null};
86
+ // json remove attribute _meta
87
+
88
+ const res = data . result ;
89
+ delete res . _meta ;
90
+ delete res . isError ;
91
+ // console.log("Received response from Spring Boot:", res);
92
+ return res ; // Must match CallToolResponseSchema
93
+ } catch ( error ) {
94
+ console . error ( "Error calling tool:" , error ) ;
95
+ throw error ;
96
+ }
97
+ } ) ;
98
+
99
+
100
+
101
+ // Launch server over stdio
102
+ async function runServer ( ) {
103
+ const transport = new StdioServerTransport ( ) ;
104
+ await server . connect ( transport ) ;
105
+ // await logToFile("Proxy server is running on stdio...");
106
+ }
107
+
108
+ runServer ( ) . catch ( console . error ) ;
0 commit comments