@codemoot/mcp-server 0.2.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CodeMoot Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/server.ts
4
+ import { join } from "path";
5
+ import {
6
+ CancellationToken,
7
+ CostStore,
8
+ MemoryStore,
9
+ ModelRegistry,
10
+ Orchestrator,
11
+ MCP_CONTENT_MAX_LENGTH,
12
+ MCP_TASK_MAX_LENGTH,
13
+ loadConfig,
14
+ openDatabase
15
+ } from "@codemoot/core";
16
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
17
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
19
+
20
+ // src/tools/review.ts
21
+ import { reviewInputSchema } from "@codemoot/core";
22
+ async function handleReview(orchestrator, args, cancellationToken) {
23
+ const input = reviewInputSchema.parse(args);
24
+ const result = await orchestrator.review(
25
+ input.content,
26
+ {
27
+ criteria: input.criteria,
28
+ strict: input.strict,
29
+ timeout: input.timeout
30
+ },
31
+ cancellationToken
32
+ );
33
+ return {
34
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
35
+ };
36
+ }
37
+
38
+ // src/tools/plan.ts
39
+ import { planInputSchema } from "@codemoot/core";
40
+ async function handlePlan(orchestrator, args) {
41
+ const input = planInputSchema.parse(args);
42
+ const result = await orchestrator.plan(input.task, {
43
+ maxRounds: input.maxRounds,
44
+ stream: input.stream
45
+ });
46
+ return {
47
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
48
+ };
49
+ }
50
+
51
+ // src/tools/debate.ts
52
+ import { debateInputSchema } from "@codemoot/core";
53
+ async function handleDebate(orchestrator, args) {
54
+ const input = debateInputSchema.parse(args);
55
+ const result = await orchestrator.debateMultiRound(input.question, {
56
+ modelAliases: input.models,
57
+ maxRounds: input.maxRounds,
58
+ timeout: input.timeout
59
+ });
60
+ return {
61
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
62
+ };
63
+ }
64
+
65
+ // src/tools/memory.ts
66
+ import { memoryInputSchema } from "@codemoot/core";
67
+ async function handleMemory(memoryStore, projectId, args) {
68
+ const input = memoryInputSchema.parse(args);
69
+ let result;
70
+ switch (input.action) {
71
+ case "save": {
72
+ if (!input.content) {
73
+ throw new Error("content is required for save action");
74
+ }
75
+ const id = memoryStore.save({
76
+ projectId,
77
+ category: input.category ?? "convention",
78
+ content: input.content,
79
+ sourceSessionId: null,
80
+ importance: input.importance
81
+ });
82
+ result = { id, saved: true };
83
+ break;
84
+ }
85
+ case "search": {
86
+ if (!input.query) {
87
+ throw new Error("query is required for search action");
88
+ }
89
+ const records = memoryStore.search(input.query, projectId);
90
+ result = { records, count: records.length };
91
+ break;
92
+ }
93
+ case "get": {
94
+ if (input.memoryId === void 0) {
95
+ throw new Error("memoryId is required for get action");
96
+ }
97
+ const record = memoryStore.getById(input.memoryId);
98
+ if (record) {
99
+ memoryStore.recordAccess(input.memoryId);
100
+ }
101
+ result = record ?? { error: "Not found" };
102
+ break;
103
+ }
104
+ case "delete": {
105
+ if (input.memoryId === void 0) {
106
+ throw new Error("memoryId is required for delete action");
107
+ }
108
+ memoryStore.delete(input.memoryId);
109
+ result = { deleted: true, memoryId: input.memoryId };
110
+ break;
111
+ }
112
+ default: {
113
+ throw new Error(`Unknown memory action: ${String(input.action)}`);
114
+ }
115
+ }
116
+ return {
117
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
118
+ };
119
+ }
120
+
121
+ // src/tools/cost.ts
122
+ import { DAYS_PER_YEAR, costInputSchema } from "@codemoot/core";
123
+ async function handleCost(costStore, args) {
124
+ const input = costInputSchema.parse(args);
125
+ let result;
126
+ switch (input.scope) {
127
+ case "session": {
128
+ const sessionId = input.sessionId ?? "";
129
+ result = costStore.getSessionSummary(sessionId);
130
+ break;
131
+ }
132
+ case "daily": {
133
+ result = costStore.getDailySummary(input.days);
134
+ break;
135
+ }
136
+ case "all": {
137
+ result = costStore.getDailySummary(DAYS_PER_YEAR);
138
+ break;
139
+ }
140
+ default: {
141
+ throw new Error(`Unknown cost scope: ${String(input.scope)}`);
142
+ }
143
+ }
144
+ return {
145
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
146
+ };
147
+ }
148
+
149
+ // src/server.ts
150
+ var TOOL_DEFINITIONS = [
151
+ {
152
+ name: "codemoot_review",
153
+ description: "Review code or content with a configured AI model. Returns score, verdict, and feedback.",
154
+ inputSchema: {
155
+ type: "object",
156
+ properties: {
157
+ content: {
158
+ type: "string",
159
+ description: "Content to review",
160
+ minLength: 1,
161
+ maxLength: MCP_CONTENT_MAX_LENGTH
162
+ },
163
+ criteria: { type: "array", items: { type: "string" }, description: "Review criteria" },
164
+ model: { type: "string", description: "Model alias override" },
165
+ strict: { type: "boolean", description: "Enable strict DLP mode", default: true },
166
+ timeout: { type: "number", description: "Timeout in seconds", default: 600 }
167
+ },
168
+ required: ["content"]
169
+ }
170
+ },
171
+ {
172
+ name: "codemoot_plan",
173
+ description: "Generate and iterate on a plan using multi-model review loops. Returns the refined plan.",
174
+ inputSchema: {
175
+ type: "object",
176
+ properties: {
177
+ task: { type: "string", description: "Task to plan", minLength: 1, maxLength: MCP_TASK_MAX_LENGTH },
178
+ maxRounds: { type: "integer", description: "Max review rounds", default: 3 },
179
+ stream: { type: "boolean", description: "Enable streaming", default: false },
180
+ timeout: { type: "number", description: "Timeout in seconds", default: 600 }
181
+ },
182
+ required: ["task"]
183
+ }
184
+ },
185
+ {
186
+ name: "codemoot_debate",
187
+ description: "Debate a question across multiple AI models concurrently. Returns per-model responses and optional synthesis.",
188
+ inputSchema: {
189
+ type: "object",
190
+ properties: {
191
+ question: {
192
+ type: "string",
193
+ description: "Question to debate",
194
+ minLength: 1,
195
+ maxLength: MCP_TASK_MAX_LENGTH
196
+ },
197
+ models: {
198
+ type: "array",
199
+ items: { type: "string" },
200
+ minItems: 1,
201
+ maxItems: 5,
202
+ description: "Model aliases"
203
+ },
204
+ synthesize: { type: "boolean", description: "Synthesize responses", default: false },
205
+ maxRounds: {
206
+ type: "integer",
207
+ description: "Max review rounds",
208
+ default: 3,
209
+ minimum: 1,
210
+ maximum: 10
211
+ },
212
+ timeout: { type: "number", description: "Timeout in seconds", default: 600 }
213
+ },
214
+ required: ["question"]
215
+ }
216
+ },
217
+ {
218
+ name: "codemoot_memory",
219
+ description: "Save, search, retrieve, or delete project memories (decisions, conventions, patterns).",
220
+ inputSchema: {
221
+ type: "object",
222
+ properties: {
223
+ action: {
224
+ type: "string",
225
+ enum: ["save", "search", "get", "delete"],
226
+ description: "Memory operation"
227
+ },
228
+ content: { type: "string", description: "Content to save" },
229
+ query: { type: "string", description: "Search query" },
230
+ memoryId: { type: "integer", description: "Memory record ID" },
231
+ category: {
232
+ type: "string",
233
+ enum: ["decision", "convention", "pattern", "issue", "preference"],
234
+ description: "Memory category"
235
+ },
236
+ importance: { type: "number", description: "Importance 0-1", default: 0.5 },
237
+ timeout: { type: "number", description: "Timeout in seconds", default: 5 }
238
+ },
239
+ required: ["action"]
240
+ }
241
+ },
242
+ {
243
+ name: "codemoot_cost",
244
+ description: "Query cost and token usage data. Supports session, daily, and all-time scopes.",
245
+ inputSchema: {
246
+ type: "object",
247
+ properties: {
248
+ scope: {
249
+ type: "string",
250
+ enum: ["session", "daily", "all"],
251
+ description: "Cost scope",
252
+ default: "session"
253
+ },
254
+ sessionId: { type: "string", description: "Session ID for session scope" },
255
+ days: { type: "integer", description: "Number of days for daily scope", default: 30 },
256
+ timeout: { type: "number", description: "Timeout in seconds", default: 5 }
257
+ }
258
+ }
259
+ }
260
+ ];
261
+ async function startServer() {
262
+ const projectDir = process.env.CODEMOOT_PROJECT_DIR ?? process.cwd();
263
+ const config = loadConfig({ projectDir });
264
+ const dbPath = process.env.CODEMOOT_DB_PATH ?? join(projectDir, ".cowork", "db", "cowork.db");
265
+ const db = openDatabase(dbPath);
266
+ const registry = ModelRegistry.fromConfig(config, projectDir);
267
+ await registry.resolveAutoMode();
268
+ const orchestrator = new Orchestrator({ registry, db, config, projectDir });
269
+ const memoryStore = new MemoryStore(db);
270
+ const costStore = new CostStore(db);
271
+ const projectId = config.project.name || "default";
272
+ const server = new Server(
273
+ { name: "codemoot", version: "0.2.0" },
274
+ { capabilities: { tools: {} } }
275
+ );
276
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
277
+ return { tools: TOOL_DEFINITIONS };
278
+ });
279
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
280
+ const toolName = request.params.name;
281
+ const args = request.params.arguments ?? {};
282
+ try {
283
+ switch (toolName) {
284
+ case "codemoot_review": {
285
+ const token = new CancellationToken();
286
+ return await handleReview(orchestrator, args, token);
287
+ }
288
+ case "codemoot_plan": {
289
+ return await handlePlan(orchestrator, args);
290
+ }
291
+ case "codemoot_debate": {
292
+ return await handleDebate(orchestrator, args);
293
+ }
294
+ case "codemoot_memory": {
295
+ return await handleMemory(memoryStore, projectId, args);
296
+ }
297
+ case "codemoot_cost": {
298
+ return await handleCost(costStore, args);
299
+ }
300
+ default: {
301
+ return {
302
+ content: [{ type: "text", text: `Unknown tool: ${toolName}` }],
303
+ isError: true
304
+ };
305
+ }
306
+ }
307
+ } catch (err) {
308
+ const message = err instanceof Error ? err.message : String(err);
309
+ return {
310
+ content: [{ type: "text", text: `Error: ${message}` }],
311
+ isError: true
312
+ };
313
+ }
314
+ });
315
+ const transport = new StdioServerTransport();
316
+ await server.connect(transport);
317
+ const shutdown = () => {
318
+ try {
319
+ db.close();
320
+ } catch {
321
+ }
322
+ process.exit(0);
323
+ };
324
+ process.on("SIGTERM", shutdown);
325
+ process.on("SIGINT", shutdown);
326
+ console.error("CodeMoot MCP server started");
327
+ }
328
+
329
+ // src/index.ts
330
+ startServer().catch((err) => {
331
+ console.error("Failed to start CodeMoot MCP server:", err);
332
+ process.exit(1);
333
+ });
334
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/tools/review.ts","../src/tools/plan.ts","../src/tools/debate.ts","../src/tools/memory.ts","../src/tools/cost.ts","../src/index.ts"],"sourcesContent":["// packages/mcp-server/src/server.ts — MCP server setup with 5 tool handlers\r\n\r\nimport { join } from 'node:path';\r\nimport {\r\n CancellationToken,\r\n CostStore,\r\n MemoryStore,\r\n ModelRegistry,\r\n Orchestrator,\r\n MCP_CONTENT_MAX_LENGTH,\r\n MCP_TASK_MAX_LENGTH,\r\n loadConfig,\r\n openDatabase,\r\n} from '@codemoot/core';\r\nimport type { ProjectConfig } from '@codemoot/core';\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';\r\nimport { handleCost, handleDebate, handleMemory, handlePlan, handleReview } from './tools/index.js';\r\n\r\nconst TOOL_DEFINITIONS = [\r\n {\r\n name: 'codemoot_review',\r\n description:\r\n 'Review code or content with a configured AI model. Returns score, verdict, and feedback.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n content: {\r\n type: 'string',\r\n description: 'Content to review',\r\n minLength: 1,\r\n maxLength: MCP_CONTENT_MAX_LENGTH,\r\n },\r\n criteria: { type: 'array', items: { type: 'string' }, description: 'Review criteria' },\r\n model: { type: 'string', description: 'Model alias override' },\r\n strict: { type: 'boolean', description: 'Enable strict DLP mode', default: true },\r\n timeout: { type: 'number', description: 'Timeout in seconds', default: 600 },\r\n },\r\n required: ['content'],\r\n },\r\n },\r\n {\r\n name: 'codemoot_plan',\r\n description:\r\n 'Generate and iterate on a plan using multi-model review loops. Returns the refined plan.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n task: { type: 'string', description: 'Task to plan', minLength: 1, maxLength: MCP_TASK_MAX_LENGTH },\r\n maxRounds: { type: 'integer', description: 'Max review rounds', default: 3 },\r\n stream: { type: 'boolean', description: 'Enable streaming', default: false },\r\n timeout: { type: 'number', description: 'Timeout in seconds', default: 600 },\r\n },\r\n required: ['task'],\r\n },\r\n },\r\n {\r\n name: 'codemoot_debate',\r\n description:\r\n 'Debate a question across multiple AI models concurrently. Returns per-model responses and optional synthesis.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n question: {\r\n type: 'string',\r\n description: 'Question to debate',\r\n minLength: 1,\r\n maxLength: MCP_TASK_MAX_LENGTH,\r\n },\r\n models: {\r\n type: 'array',\r\n items: { type: 'string' },\r\n minItems: 1,\r\n maxItems: 5,\r\n description: 'Model aliases',\r\n },\r\n synthesize: { type: 'boolean', description: 'Synthesize responses', default: false },\r\n maxRounds: {\r\n type: 'integer',\r\n description: 'Max review rounds',\r\n default: 3,\r\n minimum: 1,\r\n maximum: 10,\r\n },\r\n timeout: { type: 'number', description: 'Timeout in seconds', default: 600 },\r\n },\r\n required: ['question'],\r\n },\r\n },\r\n {\r\n name: 'codemoot_memory',\r\n description:\r\n 'Save, search, retrieve, or delete project memories (decisions, conventions, patterns).',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n action: {\r\n type: 'string',\r\n enum: ['save', 'search', 'get', 'delete'],\r\n description: 'Memory operation',\r\n },\r\n content: { type: 'string', description: 'Content to save' },\r\n query: { type: 'string', description: 'Search query' },\r\n memoryId: { type: 'integer', description: 'Memory record ID' },\r\n category: {\r\n type: 'string',\r\n enum: ['decision', 'convention', 'pattern', 'issue', 'preference'],\r\n description: 'Memory category',\r\n },\r\n importance: { type: 'number', description: 'Importance 0-1', default: 0.5 },\r\n timeout: { type: 'number', description: 'Timeout in seconds', default: 5 },\r\n },\r\n required: ['action'],\r\n },\r\n },\r\n {\r\n name: 'codemoot_cost',\r\n description: 'Query cost and token usage data. Supports session, daily, and all-time scopes.',\r\n inputSchema: {\r\n type: 'object' as const,\r\n properties: {\r\n scope: {\r\n type: 'string',\r\n enum: ['session', 'daily', 'all'],\r\n description: 'Cost scope',\r\n default: 'session',\r\n },\r\n sessionId: { type: 'string', description: 'Session ID for session scope' },\r\n days: { type: 'integer', description: 'Number of days for daily scope', default: 30 },\r\n timeout: { type: 'number', description: 'Timeout in seconds', default: 5 },\r\n },\r\n },\r\n },\r\n];\r\n\r\nexport async function startServer(): Promise<void> {\r\n // Load config\r\n const projectDir = process.env.CODEMOOT_PROJECT_DIR ?? process.cwd();\r\n const config: ProjectConfig = loadConfig({ projectDir });\r\n\r\n // Open SQLite (WAL mode + busy_timeout set by openDatabase)\r\n const dbPath = process.env.CODEMOOT_DB_PATH ?? join(projectDir, '.cowork', 'db', 'cowork.db');\r\n const db = openDatabase(dbPath);\r\n\r\n // Create model registry and resolve auto mode (pass projectDir for CLI repo awareness)\r\n const registry = ModelRegistry.fromConfig(config, projectDir);\r\n await registry.resolveAutoMode();\r\n\r\n // Create orchestrator and stores (pass projectDir for context building)\r\n const orchestrator = new Orchestrator({ registry, db, config, projectDir });\r\n const memoryStore = new MemoryStore(db);\r\n const costStore = new CostStore(db);\r\n const projectId = config.project.name || 'default';\r\n\r\n // Create MCP server\r\n const server = new Server(\r\n { name: 'codemoot', version: '0.2.0' },\r\n { capabilities: { tools: {} } },\r\n );\r\n\r\n // Register tool listing handler\r\n server.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return { tools: TOOL_DEFINITIONS };\r\n });\r\n\r\n // Register tool call handler\r\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n const toolName = request.params.name;\r\n const args = request.params.arguments ?? {};\r\n\r\n try {\r\n switch (toolName) {\r\n case 'codemoot_review': {\r\n const token = new CancellationToken();\r\n return await handleReview(orchestrator, args, token);\r\n }\r\n case 'codemoot_plan': {\r\n return await handlePlan(orchestrator, args);\r\n }\r\n case 'codemoot_debate': {\r\n return await handleDebate(orchestrator, args);\r\n }\r\n case 'codemoot_memory': {\r\n return await handleMemory(memoryStore, projectId, args);\r\n }\r\n case 'codemoot_cost': {\r\n return await handleCost(costStore, args);\r\n }\r\n default: {\r\n return {\r\n content: [{ type: 'text', text: `Unknown tool: ${toolName}` }],\r\n isError: true,\r\n };\r\n }\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Error: ${message}` }],\r\n isError: true,\r\n };\r\n }\r\n });\r\n\r\n // Connect via stdio transport\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n\r\n // Graceful shutdown: close db and server on termination signals\r\n const shutdown = () => {\r\n try {\r\n db.close();\r\n } catch {\r\n // db may already be closed\r\n }\r\n process.exit(0);\r\n };\r\n process.on('SIGTERM', shutdown);\r\n process.on('SIGINT', shutdown);\r\n\r\n // Log to stderr so it does not interfere with stdio MCP transport\r\n console.error('CodeMoot MCP server started');\r\n}\r\n","// packages/mcp-server/src/tools/review.ts — codemoot_review tool handler\n\nimport { reviewInputSchema } from '@codemoot/core';\nimport type { CancellationToken, Orchestrator } from '@codemoot/core';\n\nexport async function handleReview(\n orchestrator: Orchestrator,\n args: unknown,\n cancellationToken?: CancellationToken,\n) {\n const input = reviewInputSchema.parse(args);\n const result = await orchestrator.review(\n input.content,\n {\n criteria: input.criteria,\n strict: input.strict,\n timeout: input.timeout,\n },\n cancellationToken,\n );\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n}\n","// packages/mcp-server/src/tools/plan.ts — codemoot_plan tool handler\n\nimport { planInputSchema } from '@codemoot/core';\nimport type { Orchestrator } from '@codemoot/core';\n\nexport async function handlePlan(orchestrator: Orchestrator, args: unknown) {\n const input = planInputSchema.parse(args);\n const result = await orchestrator.plan(input.task, {\n maxRounds: input.maxRounds,\n stream: input.stream,\n });\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n}\n","// packages/mcp-server/src/tools/debate.ts — codemoot_debate tool handler\n\nimport { debateInputSchema } from '@codemoot/core';\nimport type { Orchestrator } from '@codemoot/core';\n\nexport async function handleDebate(orchestrator: Orchestrator, args: unknown) {\n const input = debateInputSchema.parse(args);\n const result = await orchestrator.debateMultiRound(input.question, {\n modelAliases: input.models,\n maxRounds: input.maxRounds,\n timeout: input.timeout,\n });\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n}\n","// packages/mcp-server/src/tools/memory.ts — codemoot_memory tool handler\n\nimport { memoryInputSchema } from '@codemoot/core';\nimport type { MemoryStore } from '@codemoot/core';\n\nexport async function handleMemory(memoryStore: MemoryStore, projectId: string, args: unknown) {\n const input = memoryInputSchema.parse(args);\n let result: unknown;\n\n switch (input.action) {\n case 'save': {\n if (!input.content) {\n throw new Error('content is required for save action');\n }\n const id = memoryStore.save({\n projectId,\n category: input.category ?? 'convention',\n content: input.content,\n sourceSessionId: null,\n importance: input.importance,\n });\n result = { id, saved: true };\n break;\n }\n case 'search': {\n if (!input.query) {\n throw new Error('query is required for search action');\n }\n const records = memoryStore.search(input.query, projectId);\n result = { records, count: records.length };\n break;\n }\n case 'get': {\n if (input.memoryId === undefined) {\n throw new Error('memoryId is required for get action');\n }\n const record = memoryStore.getById(input.memoryId);\n if (record) {\n memoryStore.recordAccess(input.memoryId);\n }\n result = record ?? { error: 'Not found' };\n break;\n }\n case 'delete': {\n if (input.memoryId === undefined) {\n throw new Error('memoryId is required for delete action');\n }\n memoryStore.delete(input.memoryId);\n result = { deleted: true, memoryId: input.memoryId };\n break;\n }\n default: {\n throw new Error(`Unknown memory action: ${String(input.action)}`);\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n}\n","// packages/mcp-server/src/tools/cost.ts — codemoot_cost tool handler\n\nimport { DAYS_PER_YEAR, costInputSchema } from '@codemoot/core';\nimport type { CostStore } from '@codemoot/core';\n\nexport async function handleCost(costStore: CostStore, args: unknown) {\n const input = costInputSchema.parse(args);\n let result: unknown;\n\n switch (input.scope) {\n case 'session': {\n const sessionId = input.sessionId ?? '';\n result = costStore.getSessionSummary(sessionId);\n break;\n }\n case 'daily': {\n result = costStore.getDailySummary(input.days);\n break;\n }\n case 'all': {\n result = costStore.getDailySummary(DAYS_PER_YEAR);\n break;\n }\n default: {\n throw new Error(`Unknown cost scope: ${String(input.scope)}`);\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\n };\n}\n","import { startServer } from './server.js';\n\nstartServer().catch((err) => {\n console.error('Failed to start CodeMoot MCP server:', err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@codemoot/mcp-server",
3
+ "version": "0.2.1",
4
+ "description": "MCP server for multi-model AI code review, planning, debate, and memory (experimental)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/katarmal-ram/codemoot.git",
10
+ "directory": "packages/mcp-server"
11
+ },
12
+ "homepage": "https://github.com/katarmal-ram/codemoot#readme",
13
+ "bugs": "https://github.com/katarmal-ram/codemoot/issues",
14
+ "keywords": [
15
+ "mcp",
16
+ "ai",
17
+ "code-review",
18
+ "multi-model",
19
+ "model-context-protocol"
20
+ ],
21
+ "engines": {
22
+ "node": ">=20.0.0"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ }
34
+ },
35
+ "bin": {
36
+ "codemoot-mcp": "./dist/index.js"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.26.0",
43
+ "zod": "^3.24.0",
44
+ "@codemoot/core": "0.2.1"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^22.0.0",
48
+ "tsup": "^8.3.0",
49
+ "tsx": "^4.21.0",
50
+ "typescript": "^5.7.0",
51
+ "vitest": "^3.0.0"
52
+ },
53
+ "scripts": {
54
+ "build": "tsup",
55
+ "dev": "tsup --watch",
56
+ "typecheck": "tsc --noEmit",
57
+ "test": "vitest run",
58
+ "test:e2e": "tsx tests/e2e-harness.ts",
59
+ "test:e2e:quick": "tsx tests/e2e-harness.ts --quick",
60
+ "clean": "rm -rf dist"
61
+ }
62
+ }