Files
servers-modelcontextprotocol-1/src/everything/tools/trigger-long-running-operation.ts

79 lines
2.7 KiB
TypeScript

import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
// Tool input schema
const TriggerLongRunningOperationSchema = z.object({
duration: z
.number()
.default(10)
.describe("Duration of the operation in seconds"),
steps: z.number().default(5).describe("Number of steps in the operation"),
});
// Tool configuration
const name = "trigger-long-running-operation";
const config = {
title: "Trigger Long Running Operation Tool",
description: "Demonstrates a long running operation with progress updates.",
inputSchema: TriggerLongRunningOperationSchema,
};
/**
* Registers the 'trigger-tong-running-operation' tool with the provided McpServer instance.
*
* This function defines and registers a tool with the provided server instance that performs a
* long-running operation defined by a specific duration and number of steps. The progress
* of the operation is reported back to the client through notifications.
*
* The registered tool processes the operation in steps, with each step having equal duration.
*
* Progress notifications are sent back to the client at each step, if a `progressToken`
* is provided in the metadata. At the end of the operation, the tool returns a message
* indicating the completion of the operation, including the total duration and steps.
*
* @param {McpServer} server - The server instance where the tool should be registered.
* The server is responsible for receiving and handling requests, as well as sending progress notifications.
*/
export const registerTriggerLongRunningOperationTool = (server: McpServer) => {
server.registerTool(
name,
config,
async (args, extra): Promise<CallToolResult> => {
const validatedArgs = TriggerLongRunningOperationSchema.parse(args);
const { duration, steps } = validatedArgs;
const stepDuration = duration / steps;
const progressToken = extra._meta?.progressToken;
for (let i = 1; i < steps + 1; i++) {
await new Promise((resolve) =>
setTimeout(resolve, stepDuration * 1000)
);
if (progressToken !== undefined) {
await server.server.notification(
{
method: "notifications/progress",
params: {
progress: i,
total: steps,
progressToken,
},
},
{ relatedRequestId: extra.requestId }
);
}
}
return {
content: [
{
type: "text",
text: `Long running operation completed. Duration: ${duration} seconds, Steps: ${steps}.`,
},
],
};
}
);
};