diff --git a/src/everything/tools/add.ts b/src/everything/tools/add.ts index 42bc049c..261c117d 100644 --- a/src/everything/tools/add.ts +++ b/src/everything/tools/add.ts @@ -2,11 +2,13 @@ import { z } from "zod"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +// Tool input schema const AddSchema = z.object({ a: z.number().describe("First number"), b: z.number().describe("Second number"), }); +// Tool configuration const name = "add"; const config = { title: "Add Tool", @@ -14,6 +16,19 @@ const config = { inputSchema: AddSchema, }; +/** + * Registers a tool on the given server to handle addition operations. + * + * @param {McpServer} server - The server instance where the addition tool will be registered. + * + * The registered tool processes input arguments, validates them using a predefined schema, + * performs addition on two numeric values, and returns the result in a structured format. + * + * The tool expects input arguments to conform to a specific schema that includes two numeric properties, `a` and `b`. + * Validation is performed to ensure the input adheres to the expected structure before calculating the sum. + * + * The result is returned as a Promise resolving to an object containing the computed sum in a text format. + */ export const registerAddTool = (server: McpServer) => { server.registerTool(name, config, async (args): Promise => { const validatedArgs = AddSchema.parse(args); diff --git a/src/everything/tools/echo.ts b/src/everything/tools/echo.ts index 37d9a426..23501dc3 100644 --- a/src/everything/tools/echo.ts +++ b/src/everything/tools/echo.ts @@ -2,10 +2,12 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; +// Tool input schema export const EchoSchema = z.object({ message: z.string().describe("Message to echo"), }); +// Tool configuration const name = "echo"; const config = { title: "Echo Tool", @@ -13,6 +15,15 @@ const config = { inputSchema: EchoSchema, }; +/** + * Registers the Echo Tool with the provided McpServer instance. + * + * The Echo Tool validates input arguments using the EchoSchema and returns + * a response that echoes the message provided in the arguments. + * + * @param {McpServer} server - The server instance where the Echo Tool will be registered. + * @returns {void} + */ export const registerEchoTool = (server: McpServer) => { server.registerTool(name, config, async (args): Promise => { const validatedArgs = EchoSchema.parse(args); diff --git a/src/everything/tools/index.ts b/src/everything/tools/index.ts index 0c9f6aa4..ab12e5f4 100644 --- a/src/everything/tools/index.ts +++ b/src/everything/tools/index.ts @@ -3,6 +3,7 @@ import { registerEchoTool } from "./echo.js"; import { registerAddTool } from "./add.js"; import { registerToggleLoggingTool } from "./toggle-logging.js"; import { registerToggleSubscriberUpdatesTool } from "./toggle-subscriber-updates.js"; +import { registerLongRunningOperationTool } from "./long-running-operation.js"; /** * Register the tools with the MCP server. @@ -13,4 +14,5 @@ export const registerTools = (server: McpServer) => { registerAddTool(server); registerToggleLoggingTool(server); registerToggleSubscriberUpdatesTool(server); + registerLongRunningOperationTool(server); }; diff --git a/src/everything/tools/long-running-operation.ts b/src/everything/tools/long-running-operation.ts new file mode 100644 index 00000000..f2fff4af --- /dev/null +++ b/src/everything/tools/long-running-operation.ts @@ -0,0 +1,77 @@ +import { z } from "zod"; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; + +// Tool input schema +const LongRunningOperationSchema = 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 = "long-running-operation"; +const config = { + title: "Long Running Operation Tool", + description: "Demonstrates a long running operation with progress updates", + inputSchema: LongRunningOperationSchema, +}; + +/** + * Registers a tool to demonstrate long-running operations on the server. + * + * 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 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 registerLongRunningOperationTool = (server: McpServer) => { + server.registerTool( + name, + config, + async (args, extra): Promise => { + const validatedArgs = LongRunningOperationSchema.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}.`, + }, + ], + }; + } + ); +}; diff --git a/src/everything/tools/toggle-logging.ts b/src/everything/tools/toggle-logging.ts index 3ec71cd6..f14d7f3a 100644 --- a/src/everything/tools/toggle-logging.ts +++ b/src/everything/tools/toggle-logging.ts @@ -5,6 +5,7 @@ import { stopSimulatedLogging, } from "../server/logging.js"; +// Tool configuration const name = "toggle-logging"; const config = { title: "Toggle Logging", @@ -12,18 +13,19 @@ const config = { inputSchema: {}, }; +// Track enabled clients by session id const clients: Set = new Set(); /** - * Registers a tool that toggles simulated logging for a session on or off. + * Registers the `toggle-subscriber-updates` tool with the provided MCP server. + * This tool enables or disables sending of periodic, random-leveled logging + * messages the connected client. * - * This function allows the server to manage simulated logging for client sessions. * When invoked, it either starts or stops simulated logging based on the session's * current state. If logging for the specified session is active, it will be stopped; - * if it is inactive it will be started. + * if it is inactive, logging will be started. * * @param {McpServer} server - The server instance to which the tool is registered. - * @returns {void} */ export const registerToggleLoggingTool = (server: McpServer) => { server.registerTool( diff --git a/src/everything/tools/toggle-subscriber-updates.ts b/src/everything/tools/toggle-subscriber-updates.ts index 672be0fe..d99303e7 100644 --- a/src/everything/tools/toggle-subscriber-updates.ts +++ b/src/everything/tools/toggle-subscriber-updates.ts @@ -5,6 +5,7 @@ import { stopSimulatedResourceUpdates, } from "../resources/subscriptions.js"; +// Tool configuration const name = "toggle-subscriber-updates"; const config = { title: "Toggle Subscriber Updates", @@ -12,8 +13,23 @@ const config = { inputSchema: {}, }; +// Track enabled clients by session id const clients: Set = new Set(); +/** + * Registers the `toggle-subscriber-updates` tool with the provided MCP server. + * This tool enables or disables simulated resource update notifications for a client. + * + * + * Toggles the state of the updates based on whether the session is already active. + * When enabled, the simulated resource updates are sent to the client at a regular interval. + * When disabled, updates are stopped for the session. + * + * The response provides feedback indicating whether simulated updates were started or stopped, + * including the session ID. + * + * @param {McpServer} server - The MCP server instance on which the tool is registered. + */ export const registerToggleSubscriberUpdatesTool = (server: McpServer) => { server.registerTool( name,