Skip to content

Commit 9085fcf

Browse files
committed
use mcp handler extra to send notifications, this is needed so the streamable post sse notifications are sent correctly
1 parent e517837 commit 9085fcf

File tree

3 files changed

+10
-6
lines changed

3 files changed

+10
-6
lines changed

src/mcp/server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ export class ActorsMcpServer {
342342
/**
343343
* Handles the request to call a tool.
344344
* @param {object} request - The request object containing tool name and arguments.
345+
* @param {object} extra - Extra data given to the request handler, such as sendNotification function.
345346
* @throws {McpError} - based on the McpServer class code from the typescript MCP SDK
346347
*/
347348
this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {

src/tools/helpers.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const addTool: ToolEntry = {
7878
ajvValidate: ajv.compile(zodToJsonSchema(addToolArgsSchema)),
7979
// TODO: I don't like that we are passing apifyMcpServer and mcpServer to the tool
8080
call: async (toolArgs) => {
81-
const { apifyMcpServer, apifyToken, args, extra } = toolArgs;
81+
const { apifyMcpServer, apifyToken, args, extra: { sendNotification } } = toolArgs;
8282
const parsed = addToolArgsSchema.parse(args);
8383
if (apifyMcpServer.listAllToolNames().includes(parsed.actorName)) {
8484
return {
@@ -90,7 +90,7 @@ export const addTool: ToolEntry = {
9090
}
9191
const tools = await getActorsAsTools([parsed.actorName], apifyToken);
9292
const toolsAdded = apifyMcpServer.upsertTools(tools, true);
93-
await extra.sendNotification({ method: 'notifications/tools/list_changed' });
93+
await sendNotification({ method: 'notifications/tools/list_changed' });
9494

9595
return {
9696
content: [{
@@ -121,13 +121,13 @@ export const removeTool: ToolEntry = {
121121
ajvValidate: ajv.compile(zodToJsonSchema(removeToolArgsSchema)),
122122
// TODO: I don't like that we are passing apifyMcpServer and mcpServer to the tool
123123
call: async (toolArgs) => {
124-
const { apifyMcpServer, args, extra } = toolArgs;
124+
const { apifyMcpServer, args, extra: { sendNotification } } = toolArgs;
125125
const parsed = removeToolArgsSchema.parse(args);
126126
// Check if tool exists before attempting removal
127127
if (!apifyMcpServer.tools.has(parsed.toolName)) {
128128
// Send notification so client can update its tool list
129129
// just in case the client tool list is out of sync
130-
await extra.sendNotification({ method: 'notifications/tools/list_changed' });
130+
await sendNotification({ method: 'notifications/tools/list_changed' });
131131
return {
132132
content: [{
133133
type: 'text',
@@ -136,7 +136,7 @@ export const removeTool: ToolEntry = {
136136
};
137137
}
138138
const removedTools = apifyMcpServer.removeToolsByName([parsed.toolName], true);
139-
await extra.sendNotification({ method: 'notifications/tools/list_changed' });
139+
await sendNotification({ method: 'notifications/tools/list_changed' });
140140
return { content: [{ type: 'text', text: `Tools removed: ${removedTools.join(', ')}` }] };
141141
},
142142
} as InternalTool,

src/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,11 @@ export interface ActorTool extends ToolBase {
8282
export type InternalToolArgs = {
8383
/** Arguments passed to the tool */
8484
args: Record<string, unknown>;
85-
/** MCP server extra args.
85+
/** Extra data given to request handlers.
86+
*
8687
* Can be used to send notifications from the server to the client.
88+
*
89+
* For more details see: https://github.com/modelcontextprotocol/typescript-sdk/blob/f822c1255edcf98c4e73b9bf17a9dd1b03f86716/src/shared/protocol.ts#L102
8790
*/
8891
extra: RequestHandlerExtra<Request, Notification>;
8992
/** Reference to the Apify MCP server instance */

0 commit comments

Comments
 (0)