MCPcopy Create free account
hub / github.com/sourcebot-dev/sourcebot / registerMcpTool

Function registerMcpTool

packages/web/src/features/tools/adapters.ts:37–74  ·  view source on GitHub ↗
(
    server: McpServer,
    def: ToolDefinition<TName, TShape, TMetadata>,
    context: ToolContext,
)

Source from the content-addressed store, hash-verified

35}
36
37export function registerMcpTool<TName extends string, TShape extends z.ZodRawShape, TMetadata>(
38 server: McpServer,
39 def: ToolDefinition<TName, TShape, TMetadata>,
40 context: ToolContext,
41) {
42 // Widening .shape to z.ZodRawShape (its base constraint) gives TypeScript a
43 // concrete InputArgs so it can fully resolve BaseToolCallback's conditional
44 // type. def.inputSchema.parse() recovers the correctly typed value inside.
45 server.registerTool(
46 def.name,
47 {
48 description: def.description,
49 inputSchema: def.inputSchema.shape as z.ZodRawShape,
50 annotations: {
51 readOnlyHint: def.isReadOnly,
52 idempotentHint: def.isIdempotent,
53 },
54 },
55 async (input) => {
56 let success = true;
57 try {
58 const parsed = def.inputSchema.parse(input);
59 const result = await def.execute(parsed, context);
60 return { content: [{ type: "text" as const, text: result.output }] };
61 } catch (error) {
62 success = false;
63 const message = error instanceof Error ? error.message : String(error);
64 return { content: [{ type: "text" as const, text: `Tool "${def.name}" failed: ${message}` }], isError: true };
65 } finally {
66 captureEvent('tool_used', {
67 toolName: def.name,
68 source: context.source ?? 'unknown',
69 success,
70 });
71 }
72 },
73 );
74}

Callers 1

createMcpServerFunction · 0.90

Calls 1

captureEventFunction · 0.90

Tested by

no test coverage detected