delqhi/code-devops
0
1import { Server } from '@modelcontextprotocol/sdk/server/index.js';2import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';3import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';4import { z } from 'zod';5import { executeTemplateAgentAction } from './runtime.js';6 7const onboardingSaveSchema = z.object({8 ownerEmail: z.string().optional(),9 notes: z.string().optional(),10 confirm: z.boolean().optional(),11});12 13const TOOLS = [14 {15 name: 'sin-code-devops_help',16 description: 'Describe available agent actions.',17 inputSchema: { type: 'object', properties: {} },18 parse: () => ({}),19 handler: async () => executeTemplateAgentAction({ action: 'agent.help' }),20 },21 {22 name: 'sin-code-devops_health',23 description: 'Check base agent readiness.',24 inputSchema: { type: 'object', properties: {} },25 parse: () => ({}),26 handler: async () => executeTemplateAgentAction({ action: 'sin.code.devops.health' }),27 },28 {29 name: 'sin-code-devops_onboarding_status',30 description: 'Read onboarding state.',31 inputSchema: { type: 'object', properties: {} },32 parse: () => ({}),33 handler: async () => executeTemplateAgentAction({ action: 'sin.code.devops.onboarding.status' }),34 },35 {36 name: 'sin-code-devops_onboarding_save',37 description: 'Persist onboarding state. Requires confirm=true.',38 inputSchema: {39 type: 'object',40 properties: {41 ownerEmail: { type: 'string' },42 notes: { type: 'string' },43 confirm: { type: 'boolean' },44 },45 },46 parse: (input: unknown) => onboardingSaveSchema.parse(input ?? {}),47 handler: async (input: z.infer<typeof onboardingSaveSchema>) =>48 executeTemplateAgentAction({ action: 'sin.code.devops.onboarding.save', ...input }),49 },50] as const;51 52export async function startMcpServer(): Promise<void> {53 const server = new Server({ name: 'sin-code-devops', version: '0.1.0' }, { capabilities: { tools: {} } });54 55 server.setRequestHandler(ListToolsRequestSchema, async () => {56 return {57 tools: TOOLS.map((tool) => ({58 name: tool.name,59 description: tool.description,60 inputSchema: tool.inputSchema,61 })),62 };63 });64 65 server.setRequestHandler(CallToolRequestSchema, async (request) => {66 const tool = TOOLS.find((entry) => entry.name === request.params.name);67 if (!tool) {68 return {69 content: [{ type: 'text', text: `Unknown tool: ${request.params.name}` }],70 isError: true,71 };72 }73 const parsed = tool.parse(request.params.arguments ?? {});74 const result = await tool.handler(parsed);75 return {76 content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],77 };78 });79 80 const transport = new StdioServerTransport();81 await server.connect(transport);82}83 