Skip to content

Commit b9420c4

Browse files
authored
Merge pull request #40 from seuros/main
fix: follow spec
2 parents 8a05c48 + 938a13b commit b9420c4

File tree

4 files changed

+49
-34
lines changed

4 files changed

+49
-34
lines changed

package-lock.json

+8-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"name": "mcp-framework",
33
"version": "0.2.4",
4-
54
"description": "Framework for building Model Context Protocol (MCP) servers in Typescript",
65
"type": "module",
76
"author": "Alex Andru <[email protected]>",
@@ -58,7 +57,7 @@
5857
"@types/content-type": "^1.1.8",
5958
"@types/jest": "^29.5.12",
6059
"@types/jsonwebtoken": "^9.0.8",
61-
"@types/node": "^20.11.24",
60+
"@types/node": "^20.17.28",
6261
"jest": "^29.7.0",
6362
"ts-jest": "^29.1.2"
6463
}

src/core/MCPServer.ts

+30-25
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,16 @@ export interface MCPServerConfig {
6161

6262
export type ServerCapabilities = {
6363
tools?: {
64-
enabled: true;
65-
};
66-
schemas?: {
67-
enabled: true;
64+
listChanged?: true; // Optional: Indicates support for list change notifications
6865
};
6966
prompts?: {
70-
enabled: true;
67+
listChanged?: true; // Optional: Indicates support for list change notifications
7168
};
7269
resources?: {
73-
enabled: true;
70+
listChanged?: true; // Optional: Indicates support for list change notifications
71+
subscribe?: true; // Optional: Indicates support for resource subscriptions
7472
};
73+
// Other standard capabilities like 'logging' or 'completion' could be added here if supported
7574
};
7675

7776
export class MCPServer {
@@ -86,9 +85,7 @@ export class MCPServer {
8685
private serverVersion: string;
8786
private basePath: string;
8887
private transportConfig: TransportConfig;
89-
private capabilities: ServerCapabilities = {
90-
tools: { enabled: true }
91-
};
88+
private capabilities: ServerCapabilities = {}; // Initialize as empty
9289
private isRunning: boolean = false;
9390
private transport?: BaseTransport;
9491
private shutdownPromise?: Promise<void>;
@@ -191,11 +188,11 @@ export class MCPServer {
191188
});
192189
}
193190
};
191+
// Removed misplaced semicolon from previous line
194192

195-
transport.onerror = (error) => {
196-
logger.error(`Transport (${transport.type}) error: ${error.message}\n${error.stack}`);
197-
};
198-
193+
transport.onerror = (error: Error) => {
194+
logger.error(`Transport (${transport.type}) error: ${error.message}\n${error.stack}`);
195+
};
199196
return transport;
200197
}
201198

@@ -237,26 +234,28 @@ export class MCPServer {
237234
}
238235

239236
private setupHandlers() {
240-
this.server.setRequestHandler(ListToolsRequestSchema, async (request) => {
237+
// TODO: Replace 'any' with the specific inferred request type from the SDK schema if available
238+
this.server.setRequestHandler(ListToolsRequestSchema, async (request: any) => {
241239
logger.debug(`Received ListTools request: ${JSON.stringify(request)}`);
242-
240+
243241
const tools = Array.from(this.toolsMap.values()).map(
244242
(tool) => tool.toolDefinition
245243
);
246-
244+
247245
logger.debug(`Found ${tools.length} tools to return`);
248246
logger.debug(`Tool definitions: ${JSON.stringify(tools)}`);
249-
247+
250248
const response = {
251249
tools: tools,
252250
nextCursor: undefined
253251
};
254-
252+
255253
logger.debug(`Sending ListTools response: ${JSON.stringify(response)}`);
256254
return response;
257255
});
258256

259-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
257+
// TODO: Replace 'any' with the specific inferred request type from the SDK schema if available
258+
this.server.setRequestHandler(CallToolRequestSchema, async (request: any) => {
260259
logger.debug(`Tool call request received for: ${request.params.name}`);
261260
logger.debug(`Tool call arguments: ${JSON.stringify(request.params.arguments)}`);
262261

@@ -286,6 +285,7 @@ export class MCPServer {
286285
});
287286

288287
if (this.capabilities.prompts) {
288+
// No request parameter for ListPrompts
289289
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
290290
return {
291291
prompts: Array.from(this.promptsMap.values()).map(
@@ -294,7 +294,8 @@ export class MCPServer {
294294
};
295295
});
296296

297-
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
297+
// TODO: Replace 'any' with the specific inferred request type from the SDK schema if available
298+
this.server.setRequestHandler(GetPromptRequestSchema, async (request: any) => {
298299
const prompt = this.promptsMap.get(request.params.name);
299300
if (!prompt) {
300301
throw new Error(
@@ -313,6 +314,7 @@ export class MCPServer {
313314
}
314315

315316
if (this.capabilities.resources) {
317+
// No request parameter for ListResources
316318
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
317319
return {
318320
resources: Array.from(this.resourcesMap.values()).map(
@@ -321,9 +323,10 @@ export class MCPServer {
321323
};
322324
});
323325

326+
// TODO: Replace 'any' with the specific inferred request type from the SDK schema if available
324327
this.server.setRequestHandler(
325328
ReadResourceRequestSchema,
326-
async (request) => {
329+
async (request: any) => {
327330
const resource = this.resourcesMap.get(request.params.uri);
328331
if (!resource) {
329332
throw new Error(
@@ -341,7 +344,8 @@ export class MCPServer {
341344
}
342345
);
343346

344-
this.server.setRequestHandler(SubscribeRequestSchema, async (request) => {
347+
// TODO: Replace 'any' with the specific inferred request type from the SDK schema if available
348+
this.server.setRequestHandler(SubscribeRequestSchema, async (request: any) => {
345349
const resource = this.resourcesMap.get(request.params.uri);
346350
if (!resource) {
347351
throw new Error(`Unknown resource: ${request.params.uri}`);
@@ -357,7 +361,8 @@ export class MCPServer {
357361
return {};
358362
});
359363

360-
this.server.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
364+
// TODO: Replace 'any' with the specific inferred request type from the SDK schema if available
365+
this.server.setRequestHandler(UnsubscribeRequestSchema, async (request: any) => {
361366
const resource = this.resourcesMap.get(request.params.uri);
362367
if (!resource) {
363368
throw new Error(`Unknown resource: ${request.params.uri}`);
@@ -377,12 +382,12 @@ export class MCPServer {
377382

378383
private async detectCapabilities(): Promise<ServerCapabilities> {
379384
if (await this.promptLoader.hasPrompts()) {
380-
this.capabilities.prompts = { enabled: true };
385+
this.capabilities.prompts = {}; // Indicate capability exists, but don't claim listChanged
381386
logger.debug("Prompts capability enabled");
382387
}
383388

384389
if (await this.resourceLoader.hasResources()) {
385-
this.capabilities.resources = { enabled: true };
390+
this.capabilities.resources = {}; // Indicate capability exists, but don't claim listChanged/subscribe
386391
logger.debug("Resources capability enabled");
387392
}
388393

src/transports/base.ts

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ import { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
55
* Base transport interface
66
*/
77
export interface BaseTransport extends Transport {
8+
// Properties from SDK Transport (explicitly listed for clarity/safety)
9+
onclose?: (() => void) | undefined;
10+
onerror?: ((error: Error) => void) | undefined;
11+
onmessage?: ((message: JSONRPCMessage) => void) | undefined;
12+
13+
// Methods from SDK Transport (explicitly listed for clarity/safety)
14+
send(message: JSONRPCMessage): Promise<void>;
15+
close(): Promise<void>;
16+
start(): Promise<void>; // Assuming start is also needed, mirroring AbstractTransport
17+
818
/**
919
* The type of transport (e.g., "stdio", "sse")
1020
*/

0 commit comments

Comments
 (0)