gitx.do 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/auth.d.ts +77 -0
- package/dist/mcp/auth.d.ts.map +1 -0
- package/dist/mcp/auth.js +278 -0
- package/dist/mcp/auth.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +19 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +200 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +275 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +47 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +284 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/mcp/tools.d.ts +136 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +759 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/types.d.ts +124 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +9 -0
- package/dist/mcp/types.js.map +1 -0
- package/package.json +9 -3
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git MCP Server Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates MCP server instances for git operations.
|
|
5
|
+
* Provides a high-level API compatible with the MCP specification.
|
|
6
|
+
*
|
|
7
|
+
* ## Architecture
|
|
8
|
+
*
|
|
9
|
+
* The MCP server exposes git operations through three primitives:
|
|
10
|
+
*
|
|
11
|
+
* 1. **search** - Search git history, branches, tags
|
|
12
|
+
* 2. **fetch** - Fetch specific commits, files, or refs
|
|
13
|
+
* 3. **do** - Execute git operations via sandboxed TypeScript
|
|
14
|
+
*
|
|
15
|
+
* Plus individual git tools (git_status, git_commit, etc.) for direct access.
|
|
16
|
+
*
|
|
17
|
+
* ## Usage
|
|
18
|
+
*
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { createGitMCPServer } from 'gitx.do/mcp'
|
|
21
|
+
*
|
|
22
|
+
* const server = createGitMCPServer({
|
|
23
|
+
* name: 'my-git-server',
|
|
24
|
+
* auth: {
|
|
25
|
+
* introspectionUrl: 'https://oauth.do/introspect',
|
|
26
|
+
* clientId: env.OAUTH_CLIENT_ID,
|
|
27
|
+
* clientSecret: env.OAUTH_CLIENT_SECRET,
|
|
28
|
+
* },
|
|
29
|
+
* repository: gitRepo, // GitRepoDO instance or context
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* // Start server with transport
|
|
33
|
+
* await server.connect(transport)
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @module mcp/server
|
|
37
|
+
*/
|
|
38
|
+
import { Hono } from 'hono';
|
|
39
|
+
import { gitAuthMiddleware, requireGitWrite } from './auth';
|
|
40
|
+
import { getToolRegistry, invokeTool } from './tool-registry';
|
|
41
|
+
import { requiresWriteAccess } from './tools';
|
|
42
|
+
/**
|
|
43
|
+
* Create a Git MCP server
|
|
44
|
+
*/
|
|
45
|
+
export function createGitMCPServer(options = {}) {
|
|
46
|
+
const { name = 'gitx.do', version = '1.0.0', auth, repository } = options;
|
|
47
|
+
const app = new Hono();
|
|
48
|
+
// Apply auth middleware if configured
|
|
49
|
+
if (auth) {
|
|
50
|
+
app.use('/*', gitAuthMiddleware(auth));
|
|
51
|
+
}
|
|
52
|
+
// ==========================================================================
|
|
53
|
+
// MCP Protocol Endpoints
|
|
54
|
+
// ==========================================================================
|
|
55
|
+
// MCP Initialize
|
|
56
|
+
app.post('/mcp/initialize', async (c) => {
|
|
57
|
+
return c.json({
|
|
58
|
+
protocolVersion: '2024-11-05',
|
|
59
|
+
serverInfo: { name, version },
|
|
60
|
+
capabilities: {
|
|
61
|
+
tools: {},
|
|
62
|
+
resources: {},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
// MCP List Tools
|
|
67
|
+
app.post('/mcp/tools/list', async (c) => {
|
|
68
|
+
const registry = getToolRegistry();
|
|
69
|
+
return c.json({
|
|
70
|
+
tools: registry.schemas().map(schema => ({
|
|
71
|
+
name: schema.name,
|
|
72
|
+
description: schema.description,
|
|
73
|
+
inputSchema: schema.inputSchema,
|
|
74
|
+
})),
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
// MCP Call Tool
|
|
78
|
+
app.post('/mcp/tools/call', async (c) => {
|
|
79
|
+
const body = await c.req.json();
|
|
80
|
+
const { name: toolName, arguments: args = {} } = body;
|
|
81
|
+
const gitAuth = auth ? c.get('gitAuth') : undefined;
|
|
82
|
+
// Check write access
|
|
83
|
+
if (gitAuth && requiresWriteAccess(toolName, args) && gitAuth.readonly) {
|
|
84
|
+
return c.json({
|
|
85
|
+
content: [{ type: 'text', text: `Tool "${toolName}" requires write access` }],
|
|
86
|
+
isError: true,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const result = await invokeTool(toolName, args, repository, { auth: gitAuth });
|
|
90
|
+
return c.json(result);
|
|
91
|
+
});
|
|
92
|
+
// ==========================================================================
|
|
93
|
+
// REST API Endpoints (for direct HTTP access)
|
|
94
|
+
// ==========================================================================
|
|
95
|
+
// Health check
|
|
96
|
+
app.get('/health', (c) => {
|
|
97
|
+
return c.json({ status: 'ok', name, version });
|
|
98
|
+
});
|
|
99
|
+
// Get repository status
|
|
100
|
+
app.get('/api/status', async (c) => {
|
|
101
|
+
if (!repository) {
|
|
102
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
103
|
+
}
|
|
104
|
+
const short = c.req.query('short') === 'true';
|
|
105
|
+
const result = await repository.status({ short });
|
|
106
|
+
return c.json(result);
|
|
107
|
+
});
|
|
108
|
+
// Get commit log
|
|
109
|
+
app.get('/api/log', async (c) => {
|
|
110
|
+
if (!repository) {
|
|
111
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
112
|
+
}
|
|
113
|
+
const maxCount = parseInt(c.req.query('max') || '20');
|
|
114
|
+
const oneline = c.req.query('oneline') === 'true';
|
|
115
|
+
const ref = c.req.query('ref');
|
|
116
|
+
const result = await repository.log({ maxCount, oneline, ref: ref || undefined });
|
|
117
|
+
return c.json(result);
|
|
118
|
+
});
|
|
119
|
+
// Get diff
|
|
120
|
+
app.get('/api/diff', async (c) => {
|
|
121
|
+
if (!repository) {
|
|
122
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
123
|
+
}
|
|
124
|
+
const staged = c.req.query('staged') === 'true';
|
|
125
|
+
const commit1 = c.req.query('commit1');
|
|
126
|
+
const commit2 = c.req.query('commit2');
|
|
127
|
+
const result = await repository.diff({
|
|
128
|
+
staged,
|
|
129
|
+
commit1: commit1 || undefined,
|
|
130
|
+
commit2: commit2 || undefined,
|
|
131
|
+
});
|
|
132
|
+
return c.json(result);
|
|
133
|
+
});
|
|
134
|
+
// Show object
|
|
135
|
+
app.get('/api/show/:revision', async (c) => {
|
|
136
|
+
if (!repository) {
|
|
137
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
138
|
+
}
|
|
139
|
+
const revision = c.req.param('revision');
|
|
140
|
+
const path = c.req.query('path');
|
|
141
|
+
const result = await repository.show(revision, { path: path || undefined });
|
|
142
|
+
return c.json(result);
|
|
143
|
+
});
|
|
144
|
+
// Create commit (requires write access)
|
|
145
|
+
app.post('/api/commit', requireGitWrite(), async (c) => {
|
|
146
|
+
if (!repository) {
|
|
147
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
148
|
+
}
|
|
149
|
+
const body = await c.req.json();
|
|
150
|
+
const { message, author, email, amend } = body;
|
|
151
|
+
const result = await repository.commit(message, { author, email, amend });
|
|
152
|
+
return c.json(result);
|
|
153
|
+
});
|
|
154
|
+
// Branch operations
|
|
155
|
+
app.get('/api/branches', async (c) => {
|
|
156
|
+
if (!repository) {
|
|
157
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
158
|
+
}
|
|
159
|
+
const all = c.req.query('all') === 'true';
|
|
160
|
+
const result = await repository.branch({ list: true, all });
|
|
161
|
+
return c.json(result);
|
|
162
|
+
});
|
|
163
|
+
app.post('/api/branches', requireGitWrite(), async (c) => {
|
|
164
|
+
if (!repository) {
|
|
165
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
166
|
+
}
|
|
167
|
+
const body = await c.req.json();
|
|
168
|
+
const { name: branchName } = body;
|
|
169
|
+
const result = await repository.branch({ name: branchName });
|
|
170
|
+
return c.json(result);
|
|
171
|
+
});
|
|
172
|
+
app.delete('/api/branches/:name', requireGitWrite(), async (c) => {
|
|
173
|
+
if (!repository) {
|
|
174
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
175
|
+
}
|
|
176
|
+
const branchName = c.req.param('name');
|
|
177
|
+
const result = await repository.branch({ name: branchName, delete: true });
|
|
178
|
+
return c.json(result);
|
|
179
|
+
});
|
|
180
|
+
// Checkout (requires write access)
|
|
181
|
+
app.post('/api/checkout', requireGitWrite(), async (c) => {
|
|
182
|
+
if (!repository) {
|
|
183
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
184
|
+
}
|
|
185
|
+
const body = await c.req.json();
|
|
186
|
+
const { ref, createBranch } = body;
|
|
187
|
+
await repository.checkout(ref, { createBranch });
|
|
188
|
+
return c.json({ success: true, ref });
|
|
189
|
+
});
|
|
190
|
+
// Add files (requires write access)
|
|
191
|
+
app.post('/api/add', requireGitWrite(), async (c) => {
|
|
192
|
+
if (!repository) {
|
|
193
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
194
|
+
}
|
|
195
|
+
const body = await c.req.json();
|
|
196
|
+
const { files, all } = body;
|
|
197
|
+
await repository.add({ files, all });
|
|
198
|
+
return c.json({ success: true });
|
|
199
|
+
});
|
|
200
|
+
// Reset (requires write access)
|
|
201
|
+
app.post('/api/reset', requireGitWrite(), async (c) => {
|
|
202
|
+
if (!repository) {
|
|
203
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
204
|
+
}
|
|
205
|
+
const body = await c.req.json();
|
|
206
|
+
const { mode, commit } = body;
|
|
207
|
+
await repository.reset({ mode, commit });
|
|
208
|
+
return c.json({ success: true });
|
|
209
|
+
});
|
|
210
|
+
// Merge (requires write access)
|
|
211
|
+
app.post('/api/merge', requireGitWrite(), async (c) => {
|
|
212
|
+
if (!repository) {
|
|
213
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
214
|
+
}
|
|
215
|
+
const body = await c.req.json();
|
|
216
|
+
const { branch, noFf, squash } = body;
|
|
217
|
+
const result = await repository.merge(branch, { noFf, squash });
|
|
218
|
+
return c.json(result);
|
|
219
|
+
});
|
|
220
|
+
// Blame
|
|
221
|
+
app.get('/api/blame/*', async (c) => {
|
|
222
|
+
if (!repository) {
|
|
223
|
+
return c.json({ error: 'No repository configured' }, 500);
|
|
224
|
+
}
|
|
225
|
+
const path = c.req.path.replace('/api/blame/', '');
|
|
226
|
+
const startLine = parseInt(c.req.query('start') || '1');
|
|
227
|
+
const endLine = c.req.query('end') ? parseInt(c.req.query('end')) : undefined;
|
|
228
|
+
const result = await repository.blame(path, { startLine, endLine });
|
|
229
|
+
return c.json(result);
|
|
230
|
+
});
|
|
231
|
+
// ==========================================================================
|
|
232
|
+
// OAuth 2.1 Endpoints (served by MCP server)
|
|
233
|
+
// ==========================================================================
|
|
234
|
+
// OAuth Authorization Server Metadata (RFC 8414)
|
|
235
|
+
app.get('/.well-known/oauth-authorization-server', (c) => {
|
|
236
|
+
const issuer = new URL(c.req.url).origin;
|
|
237
|
+
return c.json({
|
|
238
|
+
issuer,
|
|
239
|
+
authorization_endpoint: `${issuer}/authorize`,
|
|
240
|
+
token_endpoint: `${issuer}/token`,
|
|
241
|
+
registration_endpoint: `${issuer}/register`,
|
|
242
|
+
token_introspection_endpoint: `${issuer}/introspect`,
|
|
243
|
+
token_revocation_endpoint: `${issuer}/revoke`,
|
|
244
|
+
scopes_supported: ['read', 'write', 'admin', 'git:read', 'git:write', 'git:admin'],
|
|
245
|
+
response_types_supported: ['code'],
|
|
246
|
+
grant_types_supported: ['authorization_code', 'refresh_token'],
|
|
247
|
+
code_challenge_methods_supported: ['S256'],
|
|
248
|
+
token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post'],
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
// OAuth Protected Resource Metadata (RFC 9728)
|
|
252
|
+
app.get('/.well-known/oauth-protected-resource', (c) => {
|
|
253
|
+
const resource = new URL(c.req.url).origin;
|
|
254
|
+
return c.json({
|
|
255
|
+
resource,
|
|
256
|
+
authorization_servers: [resource], // Self-issued
|
|
257
|
+
scopes_supported: ['read', 'write', 'admin', 'git:read', 'git:write', 'git:admin'],
|
|
258
|
+
bearer_methods_supported: ['header'],
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
// Note: Actual /authorize, /token, /register endpoints would be implemented
|
|
262
|
+
// by oauth.do or @cloudflare/workers-oauth-provider
|
|
263
|
+
// These are placeholders that redirect to the upstream auth provider
|
|
264
|
+
return {
|
|
265
|
+
app,
|
|
266
|
+
info: { name, version },
|
|
267
|
+
getTools() {
|
|
268
|
+
return getToolRegistry().list();
|
|
269
|
+
},
|
|
270
|
+
async invokeTool(toolName, params, authContext) {
|
|
271
|
+
return invokeTool(toolName, params, repository, { auth: authContext });
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Registry for gitx.do
|
|
3
|
+
*
|
|
4
|
+
* Provides a central registry for MCP tools with:
|
|
5
|
+
* - Tool registration and unregistration
|
|
6
|
+
* - Tool invocation via dispatcher
|
|
7
|
+
* - Built-in git tools
|
|
8
|
+
* - Parameter validation
|
|
9
|
+
* - Middleware support
|
|
10
|
+
*
|
|
11
|
+
* @module mcp/tool-registry
|
|
12
|
+
*/
|
|
13
|
+
import type { McpToolResult, McpToolSchema, McpToolHandler, McpTool, ToolRegistry, ToolContext, ToolMiddleware, InvokeToolOptions, PropertySchema } from './types';
|
|
14
|
+
export type { McpToolResult, McpToolSchema, McpToolHandler, McpTool, ToolRegistry, ToolContext, ToolMiddleware, InvokeToolOptions, PropertySchema, };
|
|
15
|
+
/**
|
|
16
|
+
* Register a custom tool.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerTool(schema: McpToolSchema, handler: McpToolHandler): void;
|
|
19
|
+
/**
|
|
20
|
+
* Unregister a tool.
|
|
21
|
+
*/
|
|
22
|
+
export declare function unregisterTool(name: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Register middleware that runs on all tool invocations.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useMiddleware(middleware: ToolMiddleware): void;
|
|
27
|
+
/**
|
|
28
|
+
* Clear all registered middleware.
|
|
29
|
+
*/
|
|
30
|
+
export declare function clearMiddleware(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get the tool registry interface.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getToolRegistry(): ToolRegistry;
|
|
35
|
+
/**
|
|
36
|
+
* Clear all custom tools from the registry.
|
|
37
|
+
*/
|
|
38
|
+
export declare function clearToolRegistry(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Invoke a tool by name.
|
|
41
|
+
*/
|
|
42
|
+
export declare function invokeTool(name: string, params: Record<string, unknown>, storage?: unknown, options?: InvokeToolOptions): Promise<McpToolResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a tool is a builtin tool.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isBuiltinTool(name: string): boolean;
|
|
47
|
+
//# sourceMappingURL=tool-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/mcp/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,OAAO,EACP,YAAY,EACZ,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAA;AAIhB,YAAY,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,OAAO,EACP,YAAY,EACZ,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,GACf,CAAA;AA+DD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAYjF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CASjD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAE9D;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,CA0B9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAOxC;AAqGD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAmDxB;AAmBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Registry for gitx.do
|
|
3
|
+
*
|
|
4
|
+
* Provides a central registry for MCP tools with:
|
|
5
|
+
* - Tool registration and unregistration
|
|
6
|
+
* - Tool invocation via dispatcher
|
|
7
|
+
* - Built-in git tools
|
|
8
|
+
* - Parameter validation
|
|
9
|
+
* - Middleware support
|
|
10
|
+
*
|
|
11
|
+
* @module mcp/tool-registry
|
|
12
|
+
*/
|
|
13
|
+
import { gitTools, requiresWriteAccess } from './tools';
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Registry Storage
|
|
16
|
+
// =============================================================================
|
|
17
|
+
/** Internal tool registry map - normalized name to tool */
|
|
18
|
+
const toolRegistry = new Map();
|
|
19
|
+
/** Set of custom (non-builtin) tool names for cleanup */
|
|
20
|
+
const customTools = new Set();
|
|
21
|
+
/** Registered middleware stack */
|
|
22
|
+
const middlewareStack = [];
|
|
23
|
+
/** Set of builtin tool names */
|
|
24
|
+
const builtinToolNames = new Set();
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Tool Name Utilities
|
|
27
|
+
// =============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Normalize a tool name for registry lookup.
|
|
30
|
+
*/
|
|
31
|
+
function normalizeName(name) {
|
|
32
|
+
return name.toLowerCase().trim();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate a tool name.
|
|
36
|
+
*/
|
|
37
|
+
function validateToolName(name) {
|
|
38
|
+
if (!name || name.trim() === '') {
|
|
39
|
+
throw new Error('Tool name cannot be empty');
|
|
40
|
+
}
|
|
41
|
+
if (name.includes(' ')) {
|
|
42
|
+
throw new Error('Tool name cannot contain spaces');
|
|
43
|
+
}
|
|
44
|
+
if (/^\d/.test(name)) {
|
|
45
|
+
throw new Error('Tool name cannot start with a number');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate a tool schema.
|
|
50
|
+
*/
|
|
51
|
+
function validateSchema(schema) {
|
|
52
|
+
if (!schema.inputSchema) {
|
|
53
|
+
throw new Error('Tool schema must have inputSchema');
|
|
54
|
+
}
|
|
55
|
+
if (schema.inputSchema.type !== 'object') {
|
|
56
|
+
throw new Error('Tool inputSchema type must be "object"');
|
|
57
|
+
}
|
|
58
|
+
if (schema.inputSchema.properties === undefined) {
|
|
59
|
+
throw new Error('Tool inputSchema must have properties');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// =============================================================================
|
|
63
|
+
// Registry Operations
|
|
64
|
+
// =============================================================================
|
|
65
|
+
/**
|
|
66
|
+
* Register a custom tool.
|
|
67
|
+
*/
|
|
68
|
+
export function registerTool(schema, handler) {
|
|
69
|
+
validateToolName(schema.name);
|
|
70
|
+
validateSchema(schema);
|
|
71
|
+
const normalizedName = normalizeName(schema.name);
|
|
72
|
+
if (toolRegistry.has(normalizedName)) {
|
|
73
|
+
throw new Error(`Tool "${schema.name}" is already registered`);
|
|
74
|
+
}
|
|
75
|
+
toolRegistry.set(normalizedName, { schema, handler });
|
|
76
|
+
customTools.add(normalizedName);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Unregister a tool.
|
|
80
|
+
*/
|
|
81
|
+
export function unregisterTool(name) {
|
|
82
|
+
const normalizedName = normalizeName(name);
|
|
83
|
+
if (!toolRegistry.has(normalizedName)) {
|
|
84
|
+
throw new Error(`Tool "${name}" is not registered`);
|
|
85
|
+
}
|
|
86
|
+
toolRegistry.delete(normalizedName);
|
|
87
|
+
customTools.delete(normalizedName);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Register middleware that runs on all tool invocations.
|
|
91
|
+
*/
|
|
92
|
+
export function useMiddleware(middleware) {
|
|
93
|
+
middlewareStack.push(middleware);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Clear all registered middleware.
|
|
97
|
+
*/
|
|
98
|
+
export function clearMiddleware() {
|
|
99
|
+
middlewareStack.length = 0;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the tool registry interface.
|
|
103
|
+
*/
|
|
104
|
+
export function getToolRegistry() {
|
|
105
|
+
return {
|
|
106
|
+
has(name) {
|
|
107
|
+
return toolRegistry.has(normalizeName(name));
|
|
108
|
+
},
|
|
109
|
+
get(name) {
|
|
110
|
+
return toolRegistry.get(normalizeName(name));
|
|
111
|
+
},
|
|
112
|
+
list() {
|
|
113
|
+
return Array.from(toolRegistry.keys());
|
|
114
|
+
},
|
|
115
|
+
schemas() {
|
|
116
|
+
return Array.from(toolRegistry.values()).map((tool) => tool.schema);
|
|
117
|
+
},
|
|
118
|
+
count() {
|
|
119
|
+
return toolRegistry.size;
|
|
120
|
+
},
|
|
121
|
+
filter(predicate) {
|
|
122
|
+
return Array.from(toolRegistry.values()).filter(predicate);
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Clear all custom tools from the registry.
|
|
128
|
+
*/
|
|
129
|
+
export function clearToolRegistry() {
|
|
130
|
+
for (const name of customTools) {
|
|
131
|
+
toolRegistry.delete(name);
|
|
132
|
+
}
|
|
133
|
+
customTools.clear();
|
|
134
|
+
clearMiddleware();
|
|
135
|
+
registerBuiltinTools();
|
|
136
|
+
}
|
|
137
|
+
// =============================================================================
|
|
138
|
+
// Parameter Validation
|
|
139
|
+
// =============================================================================
|
|
140
|
+
/**
|
|
141
|
+
* Validate required parameters.
|
|
142
|
+
*/
|
|
143
|
+
function validateRequiredParams(params, schema) {
|
|
144
|
+
const required = schema.inputSchema.required ?? [];
|
|
145
|
+
for (const paramName of required) {
|
|
146
|
+
if (params[paramName] === undefined || params[paramName] === null) {
|
|
147
|
+
return `Missing required parameter: ${paramName}`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Validate parameter types.
|
|
154
|
+
*/
|
|
155
|
+
function validateParamTypes(params, schema) {
|
|
156
|
+
const properties = schema.inputSchema.properties;
|
|
157
|
+
for (const [paramName, value] of Object.entries(params)) {
|
|
158
|
+
const propSchema = properties[paramName];
|
|
159
|
+
if (!propSchema?.type)
|
|
160
|
+
continue;
|
|
161
|
+
const expectedType = propSchema.type;
|
|
162
|
+
const actualType = typeof value;
|
|
163
|
+
if (expectedType === 'number' && actualType !== 'number') {
|
|
164
|
+
return `Parameter "${paramName}" must be a number, got ${actualType}`;
|
|
165
|
+
}
|
|
166
|
+
if (expectedType === 'string' && actualType !== 'string') {
|
|
167
|
+
return `Parameter "${paramName}" must be a string, got ${actualType}`;
|
|
168
|
+
}
|
|
169
|
+
if (expectedType === 'boolean' && actualType !== 'boolean') {
|
|
170
|
+
return `Parameter "${paramName}" must be a boolean, got ${actualType}`;
|
|
171
|
+
}
|
|
172
|
+
if (expectedType === 'array' && !Array.isArray(value)) {
|
|
173
|
+
return `Parameter "${paramName}" must be an array, got ${actualType}`;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
// =============================================================================
|
|
179
|
+
// Tool Invocation
|
|
180
|
+
// =============================================================================
|
|
181
|
+
/**
|
|
182
|
+
* Create error result helper.
|
|
183
|
+
*/
|
|
184
|
+
function errorResult(message) {
|
|
185
|
+
return {
|
|
186
|
+
content: [{ type: 'text', text: message }],
|
|
187
|
+
isError: true,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Execute middleware chain with final handler.
|
|
192
|
+
*/
|
|
193
|
+
function executeWithMiddleware(context, params, handler) {
|
|
194
|
+
if (middlewareStack.length === 0) {
|
|
195
|
+
return handler();
|
|
196
|
+
}
|
|
197
|
+
let index = middlewareStack.length - 1;
|
|
198
|
+
const executeNext = () => {
|
|
199
|
+
if (index < 0) {
|
|
200
|
+
return handler();
|
|
201
|
+
}
|
|
202
|
+
const middleware = middlewareStack[index];
|
|
203
|
+
index--;
|
|
204
|
+
if (!middleware) {
|
|
205
|
+
return handler();
|
|
206
|
+
}
|
|
207
|
+
return middleware(context, params, executeNext);
|
|
208
|
+
};
|
|
209
|
+
index = middlewareStack.length - 1;
|
|
210
|
+
return executeNext();
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Invoke a tool by name.
|
|
214
|
+
*/
|
|
215
|
+
export async function invokeTool(name, params, storage, options) {
|
|
216
|
+
const safeParams = params ?? {};
|
|
217
|
+
const normalizedName = normalizeName(name);
|
|
218
|
+
const tool = toolRegistry.get(normalizedName);
|
|
219
|
+
if (!tool) {
|
|
220
|
+
return errorResult(`Unknown tool: ${name}`);
|
|
221
|
+
}
|
|
222
|
+
// Validate required parameters
|
|
223
|
+
const requiredError = validateRequiredParams(safeParams, tool.schema);
|
|
224
|
+
if (requiredError) {
|
|
225
|
+
return errorResult(requiredError);
|
|
226
|
+
}
|
|
227
|
+
// Validate parameter types (strict mode)
|
|
228
|
+
if (options?.strictValidation) {
|
|
229
|
+
const typeError = validateParamTypes(safeParams, tool.schema);
|
|
230
|
+
if (typeError) {
|
|
231
|
+
return errorResult(typeError);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Check write access if auth context provided
|
|
235
|
+
if (options?.auth) {
|
|
236
|
+
const needsWrite = requiresWriteAccess(normalizedName, safeParams);
|
|
237
|
+
if (needsWrite && options.auth.readonly) {
|
|
238
|
+
return errorResult(`Tool "${name}" requires write access, but context is readonly`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Create invocation context
|
|
242
|
+
const context = {
|
|
243
|
+
toolName: normalizedName,
|
|
244
|
+
timestamp: Date.now(),
|
|
245
|
+
metadata: options?.metadata,
|
|
246
|
+
auth: options?.auth,
|
|
247
|
+
};
|
|
248
|
+
// Handler function
|
|
249
|
+
const executeHandler = async () => {
|
|
250
|
+
try {
|
|
251
|
+
return await tool.handler(safeParams, storage, context);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
255
|
+
return errorResult(message);
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
// Execute with middleware chain
|
|
259
|
+
return executeWithMiddleware(context, safeParams, executeHandler);
|
|
260
|
+
}
|
|
261
|
+
// =============================================================================
|
|
262
|
+
// Builtin Tool Registration
|
|
263
|
+
// =============================================================================
|
|
264
|
+
/**
|
|
265
|
+
* Register all builtin git tools.
|
|
266
|
+
*/
|
|
267
|
+
function registerBuiltinTools() {
|
|
268
|
+
for (const tool of gitTools) {
|
|
269
|
+
const normalizedName = normalizeName(tool.schema.name);
|
|
270
|
+
builtinToolNames.add(normalizedName);
|
|
271
|
+
if (!toolRegistry.has(normalizedName)) {
|
|
272
|
+
toolRegistry.set(normalizedName, tool);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Check if a tool is a builtin tool.
|
|
278
|
+
*/
|
|
279
|
+
export function isBuiltinTool(name) {
|
|
280
|
+
return builtinToolNames.has(normalizeName(name));
|
|
281
|
+
}
|
|
282
|
+
// Initialize builtin tools on module load
|
|
283
|
+
registerBuiltinTools();
|
|
284
|
+
//# sourceMappingURL=tool-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../../src/mcp/tool-registry.ts"],"names":[],"mappings":"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"}
|