forked from angular/angular-cli
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtool-registry.ts
More file actions
76 lines (65 loc) · 2.43 KB
/
tool-registry.ts
File metadata and controls
76 lines (65 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import type { McpServer, ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js';
import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types';
import type { ZodRawShape } from 'zod';
import type { AngularWorkspace } from '../../../utilities/config';
import type { DevServer } from '../dev-server';
export interface McpToolContext {
server: McpServer;
workspace?: AngularWorkspace;
logger: { warn(text: string): void };
exampleDatabasePath?: string;
devServers: Map<string, DevServer>;
}
export type McpToolFactory<TInput extends ZodRawShape> = (
context: McpToolContext,
) => ToolCallback<TInput> | Promise<ToolCallback<TInput>>;
export interface McpToolDeclaration<TInput extends ZodRawShape, TOutput extends ZodRawShape> {
name: string;
title?: string;
description: string;
annotations?: ToolAnnotations;
inputSchema?: TInput;
outputSchema?: TOutput;
factory: McpToolFactory<TInput>;
shouldRegister?: (context: McpToolContext) => boolean | Promise<boolean>;
isReadOnly?: boolean;
isLocalOnly?: boolean;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type AnyMcpToolDeclaration = McpToolDeclaration<any, any>;
export function declareTool<TInput extends ZodRawShape, TOutput extends ZodRawShape>(
declaration: McpToolDeclaration<TInput, TOutput>,
): McpToolDeclaration<TInput, TOutput> {
return declaration;
}
export async function registerTools(
server: McpServer,
context: Omit<McpToolContext, 'server'>,
declarations: AnyMcpToolDeclaration[],
): Promise<void> {
for (const declaration of declarations) {
const toolContext = { ...context, server };
if (declaration.shouldRegister && !(await declaration.shouldRegister(toolContext))) {
continue;
}
const { name, factory, shouldRegister, isReadOnly, isLocalOnly, ...config } = declaration;
const handler = await factory(toolContext);
// Add declarative characteristics to annotations
config.annotations ??= {};
if (isReadOnly !== undefined) {
config.annotations.readOnlyHint = isReadOnly;
}
if (isLocalOnly !== undefined) {
// openWorldHint: false means local only
config.annotations.openWorldHint = !isLocalOnly;
}
server.registerTool(name, config, handler);
}
}