diff options
| author | Tommaso Sciortino <[email protected]> | 2025-07-18 15:21:46 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-18 22:21:46 +0000 |
| commit | 04bbc60b97809b4200c5dd09ba849e4d097d1d1f (patch) | |
| tree | 3b2646421eb4bb1f24080f21c6d5a6e37d678524 /packages/examples/background_agent/demo-background-agent.ts | |
| parent | 73745ecd0323882fc951e387250fe2efef374e81 (diff) | |
Demo background agent (#4409)
Co-authored-by: Bryan Morgan <[email protected]>
Diffstat (limited to 'packages/examples/background_agent/demo-background-agent.ts')
| -rw-r--r-- | packages/examples/background_agent/demo-background-agent.ts | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/packages/examples/background_agent/demo-background-agent.ts b/packages/examples/background_agent/demo-background-agent.ts new file mode 100644 index 00000000..9ac568f4 --- /dev/null +++ b/packages/examples/background_agent/demo-background-agent.ts @@ -0,0 +1,217 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { z } from 'zod'; + +const BackgroundAgentMessageSchema = z.object({ + role: z.enum(['user', 'agent']), + parts: z.array(z.any()), +}); + +const BackgroundAgentTaskStatusSchema = z.object({ + state: z.enum([ + 'submitted', + 'working', + 'input-required', + 'completed', + 'canceled', + 'failed', + ]), + message: BackgroundAgentMessageSchema.optional(), +}); + +const BackgroundAgentTaskSchema = z.object({ + id: z.string(), + status: BackgroundAgentTaskStatusSchema, + history: z.array(BackgroundAgentMessageSchema).optional(), +}); +type BackgroundAgentTask = z.infer<typeof BackgroundAgentTaskSchema>; + +const server = new McpServer({ + name: 'demo-background-agent', + version: '1.0.0', +}); + +const idToTask = new Map<string, BackgroundAgentTask>(); + +server.registerTool( + 'startTask', + { + title: 'Start a new task', + description: 'Launches a new task asynchronously.', + inputSchema: { prompt: BackgroundAgentMessageSchema }, + outputSchema: BackgroundAgentTaskSchema.shape, + }, + ({ prompt }) => { + const task: BackgroundAgentTask = { + id: crypto.randomUUID(), + status: { + state: 'submitted', + message: prompt, + }, + history: [], + }; + + idToTask.set(task.id, task); + + return { + content: [], + structuredContent: task, + }; + }, +); + +server.registerTool( + 'getTask', + { + title: 'Get a task', + inputSchema: { id: z.string() }, + outputSchema: BackgroundAgentTaskSchema.shape, + }, + ({ id }) => { + const task = idToTask.get(id); + if (!task) { + return { + isError: true, + content: [ + { + type: 'text', + text: 'No such task', + }, + ], + }; + } + + return { + content: [], + structuredContent: task, + }; + }, +); + +server.registerTool( + 'listTasks', + { + title: 'Lists tasks', + outputSchema: { + tasks: z.array(BackgroundAgentTaskSchema), + }, + }, + () => { + const out = { + tasks: Array.from(idToTask.values()), + }; + return { + content: [], + structuredContent: out, + }; + }, +); + +server.registerTool( + 'messageTask', + { + title: 'Send a message to a task', + inputSchema: { + id: z.string(), + message: BackgroundAgentMessageSchema, + }, + }, + ({ id, message }) => { + const task = idToTask.get(id); + if (!task) { + return { + isError: true, + content: [ + { + type: 'text', + text: 'No such task', + }, + ], + }; + } + + task.history?.push(message); + task.status.message = message; + + const statuses = BackgroundAgentTaskStatusSchema.shape.state.options; + const randomStatus = statuses[Math.floor(Math.random() * statuses.length)]; + task.status.state = randomStatus; + + return { + content: [], + }; + }, +); + +server.registerTool( + 'deleteTask', + { + title: 'Delete a task', + inputSchema: { id: z.string() }, + }, + ({ id }) => { + const task = idToTask.get(id); + if (!task) { + return { + isError: true, + content: [ + { + type: 'text', + text: 'No such task', + }, + ], + }; + } + idToTask.delete(id); + + return { + content: [ + { + type: 'text', + text: 'Task deleted', + }, + ], + }; + }, +); + +server.registerTool( + 'cancelTask', + { + title: 'Cancels a task', + inputSchema: { id: z.string() }, + }, + ({ id }) => { + const task = idToTask.get(id); + if (!task) { + return { + isError: true, + content: [ + { + type: 'text', + text: 'No such task', + }, + ], + }; + } + task.status.state = 'canceled'; + + return { + content: [ + { + type: 'text', + text: 'Task cancelled', + }, + ], + }; + }, +); + +const transport = new StdioServerTransport(); +await server.connect(transport); |
