@@ -2,10 +2,19 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
22import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' ;
33import {
44 CallToolRequestSchema ,
5+ ListResourcesRequestSchema ,
6+ ListResourceTemplatesRequestSchema ,
57 ListToolsRequestSchema ,
8+ ReadResourceRequestSchema ,
69} from '@modelcontextprotocol/sdk/types.js' ;
710import { zodToJsonSchema } from 'zod-to-json-schema' ;
811import { PageIndexMcpClient } from './client/mcp-client.js' ;
12+ import {
13+ listResources ,
14+ listResourceTemplates ,
15+ readResource ,
16+ updateResourcesWithRemote ,
17+ } from './resources/index.js' ;
918import {
1019 executeTool ,
1120 getTools ,
@@ -30,6 +39,7 @@ class PageIndexStdioServer {
3039 {
3140 capabilities : {
3241 tools : { } ,
42+ resources : { } ,
3343 } ,
3444 } ,
3545 ) ;
@@ -94,6 +104,89 @@ class PageIndexStdioServer {
94104 }
95105 } ) ;
96106
107+ // Resource handlers
108+ this . server . setRequestHandler (
109+ ListResourcesRequestSchema ,
110+ async ( request ) => {
111+ // Initialize remote connection on first list resources request
112+ if ( ! this . mcpClient ) {
113+ await this . connectToRemoteServer ( ) ;
114+ }
115+
116+ // biome-ignore lint/style/noNonNullAssertion: mcpClient is ensured to be non-null here
117+ updateResourcesWithRemote ( this . mcpClient ! ) ;
118+
119+ try {
120+ return await listResources ( request . params ) ;
121+ } catch ( error ) {
122+ throw {
123+ code : - 32603 ,
124+ message :
125+ error instanceof Error
126+ ? error . message
127+ : 'Failed to list resources' ,
128+ data : { cursor : request . params ?. cursor } ,
129+ } ;
130+ }
131+ } ,
132+ ) ;
133+
134+ this . server . setRequestHandler (
135+ ReadResourceRequestSchema ,
136+ async ( request ) => {
137+ // Ensure connection is established
138+ if ( ! this . mcpClient ) {
139+ await this . connectToRemoteServer ( ) ;
140+ }
141+
142+ // biome-ignore lint/style/noNonNullAssertion: mcpClient is ensured to be non-null here
143+ updateResourcesWithRemote ( this . mcpClient ! ) ;
144+
145+ try {
146+ return await readResource ( request . params ) ;
147+ } catch ( error ) {
148+ // Re-throw MCP-formatted errors directly
149+ if ( typeof error === 'object' && error !== null && 'code' in error ) {
150+ throw error ;
151+ }
152+
153+ throw {
154+ code : - 32603 ,
155+ message :
156+ error instanceof Error
157+ ? error . message
158+ : 'Failed to read resource' ,
159+ data : { uri : request . params . uri } ,
160+ } ;
161+ }
162+ } ,
163+ ) ;
164+
165+ this . server . setRequestHandler (
166+ ListResourceTemplatesRequestSchema ,
167+ async ( ) => {
168+ // Ensure connection is established
169+ if ( ! this . mcpClient ) {
170+ await this . connectToRemoteServer ( ) ;
171+ }
172+
173+ // biome-ignore lint/style/noNonNullAssertion: mcpClient is ensured to be non-null here
174+ updateResourcesWithRemote ( this . mcpClient ! ) ;
175+
176+ try {
177+ return await listResourceTemplates ( ) ;
178+ } catch ( error ) {
179+ throw {
180+ code : - 32603 ,
181+ message :
182+ error instanceof Error
183+ ? error . message
184+ : 'Failed to list resource templates' ,
185+ } ;
186+ }
187+ } ,
188+ ) ;
189+
97190 this . server . onerror = ( error ) => {
98191 console . error ( `MCP Server error: ${ error } \n` ) ;
99192 } ;
0 commit comments