Skip to content

Capability notification for the MCP Server #334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/examples/server/simpleStreamableHttp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ const server = new McpServer({
version: '1.0.0',
}, { capabilities: { logging: {} } });

// Log the capability invocation details
server.onCapabilityChange((event) => {
switch (event.action) {
case 'invoked':
console.log(`${event.capabilityType} invocation ${event.invocationIndex}: '${event.capabilityName}' started`);
break;
Copy link
Contributor

@cliffhall cliffhall Apr 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to be logging this to the console. The spec says:

The server MUST NOT write anything to its stdout that is not a valid MCP message.

Should be something like:

server.sendLoggingMessage{
  level: "debug",
  data: `${event.capabilityType} invocation ${event.invocationIndex}: '${event.capabilityName}' started`,
})

That means your client is responsible for logging it to a file if needed. There is the mcp-proxy which has a tapTransport functionality that you could possibly use to siphon off these messages.

Another consideration is respecting logging level. If the client sets the logging level on the server, and that level precludes sending 'debug' messages, then these messages should not be sent.

I'd like @jspahrsummers and/or @dsp-ant to weigh in on what the right way for this to be implemented is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review! I’m happy to revise the implementation as needed.

Just to clarify the intent a bit: the notification mechanism added here is independent of the MCP protocol or the client. It’s a lightweight, internal server-side feature intended for developers with access to the McpServer instance - for example, to hook into capability usage for debugging, monitoring, or performance analysis.

In the example, I went with console.log simply to keep things simple and non-prescriptive - the goal was to show that developers can observe these events, not to suggest they should forward them as MCP messages. That said, I’m happy to change how those messages are surfaced if the current approach is problematic.

Since the logs are essential to demonstrating the feature in action, it would be good to preserve some form of visible output. Would it make sense to redirect them to console.error, or would you prefer a different logging mechanism entirely? Btw, I can use the opportunity to also change the current references to console.log in simpleStreamableHttp.ts.

case 'completed':
console.log(`${event.capabilityType} invocation ${event.invocationIndex}: '${event.capabilityName}' completed in ${event.durationMs}ms`);
break;
case 'error':
console.log(`${event.capabilityType} invocation ${event.invocationIndex}: '${event.capabilityName}' failed in ${event.durationMs}ms: ${event.error}`);
break;
}
});

// Register a simple tool that returns a greeting
server.tool(
'greet',
Expand Down Expand Up @@ -291,4 +306,4 @@ process.on('SIGINT', async () => {
await server.close();
console.log('Server shutdown complete');
process.exit(0);
});
});
7 changes: 7 additions & 0 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ export class Server<
);
}

/**
* The server's name and version.
*/
getVersion(): { readonly name: string; readonly version: string } {
return this._serverInfo;
}

/**
* Registers new capabilities. This can only be called before connecting to a transport.
*
Expand Down
Loading