@promptprojectmanager/mcp-server 4.9.8 → 4.9.10
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/README.md +3 -0
- package/dist/index.js +105 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,8 +70,11 @@ Each project gets ticket management tools:
|
|
|
70
70
|
| Tool | Description |
|
|
71
71
|
|------|-------------|
|
|
72
72
|
| `{project}_tickets_work` | Get next ticket or open specific ticket |
|
|
73
|
+
| `{project}_tickets_plan` | Get next plan-status ticket for planning work |
|
|
73
74
|
| `{project}_tickets_close` | Mark a ticket as completed |
|
|
75
|
+
| `{project}_tickets_pause` | Pause working ticket with checkpoint content |
|
|
74
76
|
| `{project}_tickets_update` | Append content to a ticket |
|
|
77
|
+
| `{project}_tickets_replace` | Replace ticket content (plan status only, archives old) |
|
|
75
78
|
| `{project}_tickets_create` | Create a new ticket |
|
|
76
79
|
| `{project}_tickets_list` | List active tickets |
|
|
77
80
|
| `{project}_tickets_get` | Get a specific ticket |
|
package/dist/index.js
CHANGED
|
@@ -230,6 +230,25 @@ function getTicketToolDefinitions(projectSlug) {
|
|
|
230
230
|
},
|
|
231
231
|
required: ["ticketSlug", "content"]
|
|
232
232
|
}
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "tickets_replace",
|
|
236
|
+
type: "replace",
|
|
237
|
+
description: `Replace ticket content in the "${projectSlug}" project. Archives old content. Only works on 'plan' status tickets.`,
|
|
238
|
+
inputSchema: {
|
|
239
|
+
type: "object",
|
|
240
|
+
properties: {
|
|
241
|
+
ticketSlug: {
|
|
242
|
+
type: "string",
|
|
243
|
+
description: "Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')"
|
|
244
|
+
},
|
|
245
|
+
content: {
|
|
246
|
+
type: "string",
|
|
247
|
+
description: "New content to replace with (old content is archived in HTML comment)"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
required: ["ticketSlug", "content"]
|
|
251
|
+
}
|
|
233
252
|
}
|
|
234
253
|
];
|
|
235
254
|
}
|
|
@@ -329,17 +348,17 @@ function getPromptToolDefinitions() {
|
|
|
329
348
|
},
|
|
330
349
|
{
|
|
331
350
|
name: "prompts_update",
|
|
332
|
-
description: "Read or update a prompt
|
|
351
|
+
description: "Read or update a prompt. Without content: returns resource with context. With content: saves new version.",
|
|
333
352
|
inputSchema: {
|
|
334
353
|
type: "object",
|
|
335
354
|
properties: {
|
|
336
355
|
slug: {
|
|
337
356
|
type: "string",
|
|
338
|
-
description: "
|
|
357
|
+
description: "Prompt slug to read or update. Supports fuzzy matching."
|
|
339
358
|
},
|
|
340
359
|
content: {
|
|
341
360
|
type: "string",
|
|
342
|
-
description: "New
|
|
361
|
+
description: "New prompt content (omit for read-only mode)"
|
|
343
362
|
}
|
|
344
363
|
},
|
|
345
364
|
required: ["slug"]
|
|
@@ -440,6 +459,13 @@ function parsePlanArgs(args) {
|
|
|
440
459
|
agent: typeof parsed?.agent === "string" ? parsed.agent : void 0
|
|
441
460
|
};
|
|
442
461
|
}
|
|
462
|
+
function parseReplaceArgs(args) {
|
|
463
|
+
const parsed = args;
|
|
464
|
+
const ticketSlug = typeof parsed?.ticketSlug === "string" ? parsed.ticketSlug : void 0;
|
|
465
|
+
const content = typeof parsed?.content === "string" ? parsed.content : void 0;
|
|
466
|
+
if (!ticketSlug || !content) return null;
|
|
467
|
+
return { ticketSlug, content };
|
|
468
|
+
}
|
|
443
469
|
function parsePromptsRunArgs(args) {
|
|
444
470
|
const parsed = args;
|
|
445
471
|
const slug = typeof parsed?.slug === "string" ? parsed.slug : void 0;
|
|
@@ -689,11 +715,10 @@ _Note: Matched via ${readResult.matchType} match_` : "";
|
|
|
689
715
|
const aiTagNotice = readResult.hasAiTags ? `
|
|
690
716
|
|
|
691
717
|
## \u26A1 AI Tags Detected
|
|
692
|
-
This
|
|
718
|
+
This prompt contains AI tags that need processing: **${readResult.aiTags?.join(", ")}**
|
|
693
719
|
|
|
694
720
|
Process these tags by reading the instructions in each tag, generating appropriate content, and saving the result with the content parameter.` : "";
|
|
695
721
|
const versionInfo = readResult.version !== void 0 ? ` (v${readResult.version})` : "";
|
|
696
|
-
const resourceLabel = readResult.resourceType.charAt(0).toUpperCase() + readResult.resourceType.slice(1);
|
|
697
722
|
const contextSection = readResult.context ? `
|
|
698
723
|
|
|
699
724
|
## Available Resources
|
|
@@ -704,7 +729,7 @@ ${JSON.stringify(readResult.context, null, 2)}
|
|
|
704
729
|
content: [
|
|
705
730
|
{
|
|
706
731
|
type: "text",
|
|
707
|
-
text: `#
|
|
732
|
+
text: `# Prompt: ${readResult.slug}${versionInfo}${matchNote}${aiTagNotice}
|
|
708
733
|
|
|
709
734
|
## Description
|
|
710
735
|
${readResult.description || "No description"}
|
|
@@ -717,14 +742,13 @@ ${readResult.content}
|
|
|
717
742
|
${readResult.editingGuidance}
|
|
718
743
|
|
|
719
744
|
---
|
|
720
|
-
_To update this
|
|
745
|
+
_To update this prompt, call prompts_update with content parameter._`
|
|
721
746
|
}
|
|
722
747
|
]
|
|
723
748
|
};
|
|
724
749
|
}
|
|
725
750
|
if (result.mode === "write") {
|
|
726
751
|
const writeResult = result;
|
|
727
|
-
const resourceLabel = writeResult.resourceType.charAt(0).toUpperCase() + writeResult.resourceType.slice(1);
|
|
728
752
|
const versionInfo = writeResult.version !== void 0 ? `
|
|
729
753
|
Version: ${writeResult.version}` : "";
|
|
730
754
|
const updatedInfo = writeResult.updatedAt ? `
|
|
@@ -735,7 +759,7 @@ Updated: ${writeResult.updatedAt}` : "";
|
|
|
735
759
|
type: "text",
|
|
736
760
|
text: `\u2705 ${writeResult.message}
|
|
737
761
|
|
|
738
|
-
|
|
762
|
+
Prompt: ${writeResult.slug}${versionInfo}${updatedInfo}`
|
|
739
763
|
}
|
|
740
764
|
]
|
|
741
765
|
};
|
|
@@ -1315,6 +1339,71 @@ _Ticket content has been appended with your update._`
|
|
|
1315
1339
|
};
|
|
1316
1340
|
}
|
|
1317
1341
|
}
|
|
1342
|
+
async function handleTicketsReplace(args, config, convexClient, projectSlug) {
|
|
1343
|
+
const parsedArgs = parseReplaceArgs(args);
|
|
1344
|
+
if (!parsedArgs) {
|
|
1345
|
+
const rawArgs = args;
|
|
1346
|
+
const hasTicketSlug = typeof rawArgs?.ticketSlug === "string" && rawArgs.ticketSlug;
|
|
1347
|
+
const hasContent = typeof rawArgs?.content === "string" && rawArgs.content;
|
|
1348
|
+
if (!hasTicketSlug) {
|
|
1349
|
+
return {
|
|
1350
|
+
content: [
|
|
1351
|
+
{
|
|
1352
|
+
type: "text",
|
|
1353
|
+
text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., "102") or full slug.`
|
|
1354
|
+
}
|
|
1355
|
+
],
|
|
1356
|
+
isError: true
|
|
1357
|
+
};
|
|
1358
|
+
}
|
|
1359
|
+
if (!hasContent) {
|
|
1360
|
+
return {
|
|
1361
|
+
content: [
|
|
1362
|
+
{
|
|
1363
|
+
type: "text",
|
|
1364
|
+
text: `Error: Missing content parameter. Provide the new content to replace the ticket with.`
|
|
1365
|
+
}
|
|
1366
|
+
],
|
|
1367
|
+
isError: true
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
return {
|
|
1371
|
+
content: [{ type: "text", text: `Error: Missing required parameters.` }],
|
|
1372
|
+
isError: true
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
const { ticketSlug, content } = parsedArgs;
|
|
1376
|
+
const typedClient = convexClient;
|
|
1377
|
+
try {
|
|
1378
|
+
const result = await typedClient.mutation("mcp_tickets:replaceMcpTicket", {
|
|
1379
|
+
...buildAuthArgs(config),
|
|
1380
|
+
projectSlug,
|
|
1381
|
+
ticketSlug,
|
|
1382
|
+
content
|
|
1383
|
+
});
|
|
1384
|
+
return {
|
|
1385
|
+
content: [
|
|
1386
|
+
{
|
|
1387
|
+
type: "text",
|
|
1388
|
+
text: `\u2705 Ticket [${result.slug}] content replaced in project "${projectSlug}".
|
|
1389
|
+
|
|
1390
|
+
Replaced at: ${new Date(result.replacedAt).toISOString()}
|
|
1391
|
+
Archived: ${result.archivedContentLength} characters
|
|
1392
|
+
New content: ${result.newContentLength} characters
|
|
1393
|
+
|
|
1394
|
+
_Old content has been archived in an HTML comment block. Ticket remains in plan status._`
|
|
1395
|
+
}
|
|
1396
|
+
]
|
|
1397
|
+
};
|
|
1398
|
+
} catch (error) {
|
|
1399
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1400
|
+
console.error(`[MCP] tickets_replace error:`, error);
|
|
1401
|
+
return {
|
|
1402
|
+
content: [{ type: "text", text: `Error replacing ticket content: ${errorMessage}` }],
|
|
1403
|
+
isError: true
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1318
1407
|
|
|
1319
1408
|
// src/handlers/memories.ts
|
|
1320
1409
|
async function handleMemoriesLoad(args, config, convexClient, projectSlug) {
|
|
@@ -1572,7 +1661,7 @@ async function startServer(config, convexClient) {
|
|
|
1572
1661
|
{ name: "ppm-mcp-server", version: "3.1.0" },
|
|
1573
1662
|
{ capabilities: { prompts: {}, tools: {} } }
|
|
1574
1663
|
);
|
|
1575
|
-
server.setRequestHandler(ListPromptsRequestSchema, async (
|
|
1664
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
1576
1665
|
return {
|
|
1577
1666
|
prompts: [
|
|
1578
1667
|
// Global prompt tools (prompts_run, prompts_list, prompts_update)
|
|
@@ -1589,7 +1678,7 @@ async function startServer(config, convexClient) {
|
|
|
1589
1678
|
]
|
|
1590
1679
|
};
|
|
1591
1680
|
});
|
|
1592
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request
|
|
1681
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
1593
1682
|
const promptName = request.params.name;
|
|
1594
1683
|
const ticketWorkMatch = promptName.match(/^tickets_work\s+(.+)$/);
|
|
1595
1684
|
if (ticketWorkMatch) {
|
|
@@ -1721,7 +1810,7 @@ This will execute the "code-review" prompt.`
|
|
|
1721
1810
|
}
|
|
1722
1811
|
throw new Error(`Unknown prompt: ${promptName}. Use prompts_run to execute prompts.`);
|
|
1723
1812
|
});
|
|
1724
|
-
server.setRequestHandler(ListToolsRequestSchema, async (
|
|
1813
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1725
1814
|
return {
|
|
1726
1815
|
tools: [
|
|
1727
1816
|
// Ticket tools
|
|
@@ -1751,7 +1840,7 @@ This will execute the "code-review" prompt.`
|
|
|
1751
1840
|
]
|
|
1752
1841
|
};
|
|
1753
1842
|
});
|
|
1754
|
-
server.setRequestHandler(CallToolRequestSchema, async (request
|
|
1843
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1755
1844
|
const toolName = request.params.name;
|
|
1756
1845
|
const args = request.params.arguments;
|
|
1757
1846
|
if (toolName === "prompts_run") {
|
|
@@ -1790,6 +1879,9 @@ This will execute the "code-review" prompt.`
|
|
|
1790
1879
|
if (toolName === "tickets_update") {
|
|
1791
1880
|
return handleTicketsUpdate(args, config, convexClient, projectSlug);
|
|
1792
1881
|
}
|
|
1882
|
+
if (toolName === "tickets_replace") {
|
|
1883
|
+
return handleTicketsReplace(args, config, convexClient, projectSlug);
|
|
1884
|
+
}
|
|
1793
1885
|
if (toolName === "memories_load") {
|
|
1794
1886
|
return handleMemoriesLoad(args, config, convexClient, projectSlug);
|
|
1795
1887
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/convex-client.ts","../src/server.ts","../src/auth/agent-resolver.ts","../src/auth/token-validator.ts","../src/tools/registry.ts","../src/types.ts","../src/prompt-builder.ts","../src/handlers/prompts.ts","../src/handlers/tickets.ts","../src/handlers/memories.ts"],"sourcesContent":["import minimist from \"minimist\";\nimport { createConvexClient } from \"./convex-client.js\";\nimport { startServer } from \"./server.js\";\nimport type { ServerConfig } from \"./types.js\";\n\n/**\n * Main entry point for the MCP server\n */\nasync function main() {\n try {\n // Parse CLI arguments\n const argv = minimist(process.argv.slice(2));\n const isDev = argv.dev === true;\n\n // Check for project token authentication\n const projectToken = process.env.PPM_PROJECT_TOKEN;\n\n if (!projectToken) {\n console.error(\n \"[MCP] ERROR: Missing authentication. Set PPM_PROJECT_TOKEN environment variable.\"\n );\n console.error(\n \"[MCP] Example:\"\n );\n console.error(\"[MCP] export PPM_PROJECT_TOKEN=wst_... # Get from project settings\");\n process.exit(1);\n }\n\n console.error(\"[MCP] Auth mode: Project Token\");\n\n // Create Convex client\n const convexClient = createConvexClient(isDev);\n const convexUrl = isDev\n ? \"https://hallowed-shrimp-344.convex.cloud\"\n : \"https://trustworthy-squirrel-735.convex.cloud\";\n\n // Build server config\n const config: ServerConfig = {\n projectToken,\n isDev,\n convexUrl,\n };\n\n // Start server - this will keep the process alive via stdio transport\n await startServer(config, convexClient);\n\n // This line should never be reached if the promise in startServer never resolves\n console.error(\"[MCP] WARNING: startServer promise resolved unexpectedly!\");\n } catch (error) {\n console.error(\n \"[MCP] FATAL ERROR:\",\n error instanceof Error ? error.message : \"Unknown error\"\n );\n if (error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n}\n\n// Handle graceful shutdown\nprocess.on(\"SIGINT\", () => {\n console.error(\"[MCP] Received SIGINT, shutting down gracefully...\");\n process.exit(0);\n});\n\nprocess.on(\"SIGTERM\", () => {\n console.error(\"[MCP] Received SIGTERM, shutting down gracefully...\");\n process.exit(0);\n});\n\nmain();\n","import { ConvexHttpClient } from \"convex/browser\";\n\nconst PROD_URL = \"https://trustworthy-squirrel-735.convex.cloud\";\nconst DEV_URL = \"https://hallowed-shrimp-344.convex.cloud\";\n\n/**\n * Create a Convex HTTP client for the appropriate deployment\n */\nexport function createConvexClient(isDev: boolean): ConvexHttpClient {\n const url = isDev ? DEV_URL : PROD_URL;\n return new ConvexHttpClient(url);\n}\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ConvexHttpClient } from \"convex/browser\";\nimport type { ServerConfig } from \"./types.js\";\n\n// Auth module\nimport { validateProjectToken } from \"./auth/index.js\";\n\n// Tools module\nimport {\n getTicketToolDefinitions,\n getMemoryToolDefinitions,\n getPromptToolDefinitions,\n} from \"./tools/index.js\";\n\n// Handlers module\nimport {\n handlePromptsRun,\n handlePromptsList,\n handlePromptsUpdate,\n handleTicketsWork,\n handleTicketsPlan,\n handleTicketsCreate,\n handleTicketsClose,\n handleTicketsPause,\n handleTicketsSearch,\n handleTicketsGet,\n handleTicketsList,\n handleTicketsUpdate,\n handleMemoriesLoad,\n handleMemoriesLoadExtreme,\n handleMemoriesAdd,\n handleMemoriesListAll,\n} from \"./handlers/index.js\";\n\n// Prompt builder for per-prompt tools and slash commands\nimport {\n fetchAndExecuteAccountScopedPrompt,\n fetchAccountScopedPromptMetadataByToken,\n} from \"./prompt-builder.js\";\n\n/**\n * Initialize and start the MCP server\n */\nexport async function startServer(\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<void> {\n // Validate project token authentication\n console.error(\"[MCP] Validating project token...\");\n const validation = await validateProjectToken(convexClient, config.projectToken);\n if (!validation.valid) {\n throw new Error(`Invalid project token: ${validation.error}`);\n }\n const projectSlug = validation.projectSlug!;\n console.error(`[MCP] Project token validated for project \"${projectSlug}\"`);\n\n // Fetch account-scoped prompts (global MCP tools)\n console.error(\"[MCP] Fetching prompt metadata...\");\n const accountScopedPrompts = await fetchAccountScopedPromptMetadataByToken(\n convexClient,\n config.projectToken\n );\n console.error(`[MCP] Project token mode: loaded ${accountScopedPrompts.length} prompts`);\n\n // Filter prompts with slashCommand: true for slash command registration\n const slashCommandPrompts = accountScopedPrompts.filter((p) => p.slashCommand === true);\n console.error(`[MCP] ${slashCommandPrompts.length} prompts registered as slash commands`);\n\n if (accountScopedPrompts.length === 0) {\n console.error(\n \"[MCP] WARNING: No prompts found. Create prompts in the 'prompts' section to expose them via MCP.\"\n );\n }\n\n // Get tool definitions from registry\n const ticketTools = getTicketToolDefinitions(projectSlug);\n const memoryTools = getMemoryToolDefinitions();\n const promptTools = getPromptToolDefinitions();\n\n console.error(`[MCP] Registering ${ticketTools.length} ticket tools...`);\n console.error(`[MCP] Registering ${memoryTools.length} memory tools...`);\n console.error(`[MCP] Registering ${promptTools.length} global prompt tools...`);\n\n // Build dynamic per-prompt tools\n const dynamicPromptTools = accountScopedPrompts.map((prompt) => {\n const folderPrefix = prompt.folderPath ? `[${prompt.folderPath}] ` : \"\";\n const baseDescription = prompt.description || `Execute the \"${prompt.slug}\" prompt`;\n return {\n name: prompt.slug,\n description: folderPrefix + baseDescription,\n promptSlug: prompt.slug,\n };\n });\n\n console.error(`[MCP] Registering ${dynamicPromptTools.length} per-prompt tools (global)...`);\n\n // Check for duplicate prompt names\n const promptNames = new Set<string>();\n const duplicates: string[] = [];\n accountScopedPrompts.forEach((p) => {\n if (promptNames.has(p.slug)) {\n duplicates.push(p.slug);\n }\n promptNames.add(p.slug);\n });\n\n if (duplicates.length > 0) {\n console.error(\n `[MCP] WARNING: Duplicate prompt slugs detected: ${duplicates.join(\", \")}. Only the first occurrence will be registered.`\n );\n }\n\n // Create MCP server\n const server = new Server(\n { name: \"ppm-mcp-server\", version: \"3.1.0\" },\n { capabilities: { prompts: {}, tools: {} } }\n );\n\n // ============================================================================\n // LIST PROMPTS HANDLER\n // ============================================================================\n server.setRequestHandler(ListPromptsRequestSchema, async (_request, _extra) => {\n return {\n prompts: [\n // Global prompt tools (prompts_run, prompts_list, prompts_update)\n ...promptTools.map((t) => ({ name: t.name, description: t.description })),\n // Ticket tools\n ...ticketTools.map((t) => ({ name: t.name, description: t.description })),\n // Memory tools\n ...memoryTools.map((t) => ({ name: t.name, description: t.description })),\n // User prompts with slashCommand: true\n ...slashCommandPrompts.map((p) => ({\n name: p.slug,\n description: p.description || `Execute the \"${p.slug}\" prompt`,\n })),\n ],\n };\n });\n\n // ============================================================================\n // GET PROMPT HANDLER (slash command content)\n // ============================================================================\n server.setRequestHandler(GetPromptRequestSchema, async (request, _extra) => {\n const promptName = request.params.name;\n\n // Handle tickets_work with optional argument (e.g., \"tickets_work 102\")\n const ticketWorkMatch = promptName.match(/^tickets_work\\s+(.+)$/);\n if (ticketWorkMatch) {\n const ticketArg = ticketWorkMatch[1].trim();\n return {\n description: `Work on ticket \"${ticketArg}\" from \"${projectSlug}\"`,\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Get work on ticket \"${ticketArg}\" from the \"${projectSlug}\" project.\\n\\nCall the \\`tickets_work\\` tool with ticketSlug: \"${ticketArg}\".\\n\\nThis will open the ticket if it's in the open queue, or resume it if already working.`,\n },\n },\n ],\n };\n }\n\n // Handle tickets_plan with optional argument (e.g., \"tickets_plan 102\")\n const ticketPlanMatch = promptName.match(/^tickets_plan\\s+(.+)$/);\n if (ticketPlanMatch) {\n const ticketArg = ticketPlanMatch[1].trim();\n return {\n description: `Plan ticket \"${ticketArg}\" from \"${projectSlug}\"`,\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Get planning work on ticket \"${ticketArg}\" from the \"${projectSlug}\" project.\\n\\nCall the \\`tickets_plan\\` tool with ticketSlug: \"${ticketArg}\".\\n\\nThis ticket is in PLAN status. You may ONLY:\\n• Create/update plan files\\n• Update this ticket with planning notes\\n• Create sub-tickets for implementation\\n\\nDO NOT: Write code or make implementation changes.`,\n },\n },\n ],\n };\n }\n\n // Handle ticket tools\n const ticketTool = ticketTools.find((t) => t.name === promptName);\n if (ticketTool) {\n return buildTicketPromptResponse(ticketTool.type, ticketTool.name, projectSlug);\n }\n\n // Handle prompts_list\n if (promptName === \"prompts_list\") {\n return {\n description: \"List all available prompts\",\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `List all available prompts.\\n\\nCall the \\`prompts_list\\` tool with optional \\`search\\` parameter to filter results.`,\n },\n },\n ],\n };\n }\n\n // Handle prompts_run with optional argument\n const runPromptMatch = promptName.match(/^prompts_run\\s+(.+)$/);\n if (promptName === \"prompts_run\" || runPromptMatch) {\n if (runPromptMatch) {\n const promptSlug = runPromptMatch[1].trim();\n return {\n description: `Execute prompt \"${promptSlug}\"`,\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Execute the \"${promptSlug}\" prompt.\\n\\nCall the \\`prompts_run\\` tool with slug: \"${promptSlug}\".`,\n },\n },\n ],\n };\n }\n return {\n description: \"Execute a prompt by slug\",\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Execute a prompt by slug.\\n\\n## Usage\\nCall the \\`prompts_run\\` tool with the prompt slug.\\n\\n## Available Prompts\\nUse \\`prompts_list\\` to list all available prompts.\\n\\n## Example\\n/ppm:prompts_run code-review\\n\\nThis will execute the \"code-review\" prompt.`,\n },\n },\n ],\n };\n }\n\n // Handle user slash command prompts\n const userSlashCommand = slashCommandPrompts.find((p) => p.slug === promptName);\n if (userSlashCommand) {\n try {\n const result = await fetchAndExecuteAccountScopedPrompt(\n userSlashCommand.slug,\n config,\n convexClient\n );\n return {\n description: userSlashCommand.description || `Execute \"${userSlashCommand.slug}\"`,\n messages: result.messages.map((msg) => ({\n role: msg.role as \"user\",\n content: { type: \"text\" as const, text: msg.content.text },\n })),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n throw new Error(`Error executing slash command \"${promptName}\": ${errorMessage}`);\n }\n }\n\n // Unknown prompt\n throw new Error(`Unknown prompt: ${promptName}. Use prompts_run to execute prompts.`);\n });\n\n // ============================================================================\n // LIST TOOLS HANDLER\n // ============================================================================\n server.setRequestHandler(ListToolsRequestSchema, async (_request, _extra) => {\n return {\n tools: [\n // Ticket tools\n ...ticketTools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n // Prompt tools (global)\n ...promptTools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n // Memory tools\n ...memoryTools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n // Per-prompt tools\n ...dynamicPromptTools.map((pt) => ({\n name: pt.name,\n description: pt.description,\n inputSchema: { type: \"object\" as const, properties: {}, required: [] },\n })),\n ],\n };\n });\n\n // ============================================================================\n // CALL TOOL HANDLER - Main dispatcher\n // ============================================================================\n server.setRequestHandler(CallToolRequestSchema, async (request, _extra) => {\n const toolName = request.params.name;\n const args = request.params.arguments;\n\n // --- Global Prompt Tools ---\n if (toolName === \"prompts_run\") {\n return handlePromptsRun(args, config, convexClient);\n }\n if (toolName === \"prompts_list\") {\n return handlePromptsList(args, config, convexClient, accountScopedPrompts);\n }\n if (toolName === \"prompts_update\") {\n return handlePromptsUpdate(args, config, convexClient);\n }\n\n // --- Ticket Tools ---\n if (toolName === \"tickets_work\") {\n return handleTicketsWork(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_plan\") {\n return handleTicketsPlan(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_create\") {\n return handleTicketsCreate(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_close\") {\n return handleTicketsClose(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_pause\") {\n return handleTicketsPause(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_search\") {\n return handleTicketsSearch(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_get\") {\n return handleTicketsGet(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_list\") {\n return handleTicketsList(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_update\") {\n return handleTicketsUpdate(args, config, convexClient, projectSlug);\n }\n\n // --- Memory Tools ---\n if (toolName === \"memories_load\") {\n return handleMemoriesLoad(args, config, convexClient, projectSlug);\n }\n if (toolName === \"memories_load_extreme\") {\n return handleMemoriesLoadExtreme(args, config, convexClient, projectSlug);\n }\n if (toolName === \"memories_add\") {\n return handleMemoriesAdd(args, config, convexClient, projectSlug);\n }\n if (toolName === \"memories_list_all\") {\n return handleMemoriesListAll(args, config, convexClient, projectSlug);\n }\n\n // --- Per-Prompt Tools (dynamic) ---\n const promptTool = dynamicPromptTools.find((pt) => pt.name === toolName);\n if (promptTool) {\n try {\n const result = await fetchAndExecuteAccountScopedPrompt(\n promptTool.promptSlug,\n config,\n convexClient\n );\n const promptText = result.messages.map((msg) => msg.content.text).join(\"\\n\\n\");\n return { content: [{ type: \"text\", text: promptText }] };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] ${toolName} error:`, error);\n return {\n content: [{ type: \"text\", text: `Error executing prompt: ${errorMessage}` }],\n isError: true,\n };\n }\n }\n\n // --- Unknown Tool ---\n return {\n content: [\n {\n type: \"text\",\n text: `Unknown tool: ${toolName}. Use prompts_run to execute prompts by name, or check available tools.`,\n },\n ],\n isError: true,\n };\n });\n\n // ============================================================================\n // START SERVER\n // ============================================================================\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error(\"[MCP] Server started successfully\");\n console.error(`[MCP] Deployment: ${config.isDev ? \"DEVELOPMENT\" : \"PRODUCTION\"}`);\n console.error(`[MCP] Convex URL: ${config.convexUrl}`);\n console.error(`[MCP] Data mode: REAL-TIME (fetches fresh data on each invocation)`);\n\n const allPromptNames = [...Array.from(promptNames)].sort();\n console.error(`[MCP] Prompts available: ${allPromptNames.join(\", \")}`);\n console.error(`[MCP] - Total prompts: ${promptNames.size}`);\n\n // Keep the event loop alive with a heartbeat\n setInterval(() => {\n // Heartbeat every 60 seconds to keep process alive\n }, 60000);\n\n // Return a promise that never resolves to keep the server running\n return new Promise<void>(() => {\n // The transport handles stdin/stdout communication\n });\n}\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Build prompt response for ticket tools (used by GetPromptRequestSchema)\n */\nfunction buildTicketPromptResponse(\n type: string,\n toolName: string,\n projectSlug: string\n): { description: string; messages: Array<{ role: \"user\"; content: { type: \"text\"; text: string } }> } {\n let promptContent: string;\n let description: string;\n\n if (type === \"work\") {\n description = `Get work from the \"${projectSlug}\" project`;\n promptContent = `Get work from the \"${projectSlug}\" project.\\n\\nCall the \\`tickets_work\\` tool to get the next ticket from the open queue.\\n\\nYou can also specify a ticket: /ppm:tickets_work <number-or-slug>\\n\\nThis unified command handles both opening new tickets and resuming in-progress work.`;\n } else if (type === \"plan\") {\n description = `Get planning work from the \"${projectSlug}\" project`;\n promptContent = `Get planning work from the \"${projectSlug}\" project.\n\nCall the \\`tickets_plan\\` tool to get the next ticket from the plan queue.\n\nYou can also specify a ticket: /ppm:tickets_plan <number-or-slug>\n\nThis unified command handles both opening new plan tickets and resuming in-progress planning work.\n\n**IMPORTANT**: This ticket is in PLAN status. You may ONLY:\n• Create/update plan files\n• Update this ticket with planning notes\n• Create sub-tickets for implementation\n\nDO NOT: Write code or make implementation changes.`;\n } else if (type === \"create\") {\n description = `Create a new ticket in \"${projectSlug}\"`;\n promptContent = `Create a new ticket in the \"${projectSlug}\" project queue.\n\n## How This Works\nThe user provides **instructions** (not raw content). You interpret those instructions to generate the ticket.\n\n## Instructions\n1. **Read the user's request** - they may reference a file, ask you to summarize a session, or describe what they want\n2. **Process the input** - read files, extract relevant sections, summarize as needed\n3. **Generate ticket content** with a clear, descriptive title as the first line\n4. **Call the tool** with the generated content\n\n## Content Format\n\\`\\`\\`\n[Clear descriptive title - this becomes the slug]\n\n[Body content - tasks, description, context, etc.]\n\\`\\`\\`\n\n## Examples\n- \"create a ticket from /path/to/plan.md\" → Read file, use as ticket content\n- \"summarize our brainstorm into a ticket\" → Extract key points from conversation\n- \"create a ticket for the auth bug we discussed\" → Generate from session context\n- \"just the tasks from this file\" → Extract only task items\n\nCall the \\`${toolName}\\` tool with the final generated content.`;\n } else if (type === \"close\") {\n description = `Close a working ticket in \"${projectSlug}\"`;\n promptContent = `Close a working ticket in the \"${projectSlug}\" project.\\n\\nCall the \\`${toolName}\\` tool with the ticket number or slug.`;\n } else {\n // Fallback for other types\n description = `Use the ${toolName} tool`;\n promptContent = `Use the \\`${toolName}\\` tool.`;\n }\n\n return {\n description,\n messages: [\n {\n role: \"user\" as const,\n content: { type: \"text\" as const, text: promptContent },\n },\n ],\n };\n}\n","import type { ServerConfig } from \"../types.js\";\n\n/**\n * Build authentication arguments for Convex mutations/queries.\n * All auth is now via project token.\n */\nexport function buildAuthArgs(config: ServerConfig): { projectToken: string } {\n return { projectToken: config.projectToken };\n}\n\n/**\n * Resolve agent for ticket operations (implement-agent-routing)\n * Priority: explicit param > PPM_AGENT_NAME env var > undefined (owner mode)\n *\n * @param paramAgent - Agent slug passed as tool parameter\n * @returns Resolved agent slug or undefined for owner mode\n */\nexport function resolveAgent(paramAgent?: string): string | undefined {\n // Explicit parameter takes priority\n if (paramAgent) return paramAgent;\n\n // Fall back to environment variable\n const envAgent = process.env.PPM_AGENT_NAME;\n if (envAgent) return envAgent;\n\n // Owner mode - no filtering\n return undefined;\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type { ProjectTokenValidation } from \"../types.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n * This allows us to use string function names while maintaining type safety\n * for the response types through explicit casting.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * Response type from validateProjectToken query\n */\ninterface ValidateProjectTokenResponse {\n valid: boolean;\n projectId?: string;\n projectSlug?: string;\n ownerId?: string;\n}\n\n/**\n * Validate project token with Convex\n *\n * Project tokens are now stored directly on the projects table.\n * Returns project details if valid, null if invalid.\n */\nexport async function validateProjectToken(\n client: ConvexHttpClient,\n token: string\n): Promise<ProjectTokenValidation> {\n try {\n // Cast to our typed client for string-based function references\n const typedClient = client as ConvexClientWithStringRefs;\n const result = await typedClient.query<ValidateProjectTokenResponse | null>(\n \"projects:validateProjectToken\",\n { token }\n );\n\n if (result && result.valid) {\n return {\n valid: true,\n projectId: result.projectId,\n projectSlug: result.projectSlug,\n ownerId: result.ownerId,\n };\n }\n return { valid: false, error: \"Invalid project token\" };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n","/**\n * Unified Tool Registry - Single source of truth for all MCP tools\n *\n * Each tool is defined once with: name, description, inputSchema\n * Handler mapping happens at runtime in server.ts since handlers need\n * dynamic context (projectSlug, accountScopedPrompts)\n *\n * This ensures ListTools and CallTool are always in sync.\n */\n\n/**\n * Tool definition entry (without handler - handlers are mapped at runtime)\n */\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/**\n * Ticket tool types for type-safe tool identification\n */\nexport type TicketToolType =\n | \"work\"\n | \"plan\"\n | \"close\"\n | \"pause\"\n | \"create\"\n | \"search\"\n | \"get\"\n | \"list\"\n | \"update\";\n\n/**\n * Memory tool types for type-safe tool identification\n */\nexport type MemoryToolType = \"load\" | \"load_extreme\" | \"add\" | \"list_all\";\n\n/**\n * Get ticket tool definitions with project-specific descriptions\n */\nexport function getTicketToolDefinitions(projectSlug: string): Array<ToolDefinition & { type: TicketToolType }> {\n return [\n {\n name: \"tickets_work\",\n type: \"work\",\n description: `Get work from the \"${projectSlug}\" project. With no args: gets next ticket from open queue. With ticket slug/number: opens or resumes that specific ticket.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description:\n \"Optional: Ticket number (e.g., '102') or full slug. If not provided, gets next ticket from open queue.\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter queue. Overrides PPM_AGENT_NAME env var. Omit for owner mode (no filtering).\",\n },\n },\n required: [],\n },\n },\n {\n name: \"tickets_plan\",\n type: \"plan\",\n description: `Get planning work from the \"${projectSlug}\" project. With no args: gets next ticket from plan queue. With ticket slug/number: opens that specific plan ticket. Status stays as 'plan' - no code changes allowed, only planning files and ticket updates.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description:\n \"Optional: Ticket number (e.g., '102') or full slug. If not provided, gets next ticket from plan queue.\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter queue. Overrides PPM_AGENT_NAME env var. Omit for owner mode (no filtering).\",\n },\n },\n required: [],\n },\n },\n {\n name: \"tickets_close\",\n type: \"close\",\n description: `Mark a working ticket as completed in the \"${projectSlug}\" project. If a hook is configured, first call returns instructions - then call again with metadata.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n metadata: {\n type: \"object\",\n description:\n \"Optional: Key-value metadata to store with the closed ticket (e.g., evaluation scores, completion notes).\",\n additionalProperties: {\n oneOf: [{ type: \"string\" }, { type: \"number\" }, { type: \"boolean\" }],\n },\n },\n },\n required: [\"ticketSlug\"],\n },\n },\n {\n name: \"tickets_pause\",\n type: \"pause\",\n description: `Pause a working ticket and return to queue. Before calling, review the full session context and generate comprehensive checkpoint content that enables seamless handoff to another agent. Include: completed tasks with specifics, key decisions and rationale, sticking points and resolutions, user preferences discovered, remaining work with file:line references, and open questions.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n content: {\n type: \"string\",\n description:\n 'Comprehensive checkpoint for handoff. Review the session and include: ## Progress (completed tasks with specifics, decisions made and why) ## Context (user preferences, edge cases discovered, key feedback received) ## Remaining (specific next steps, file:line references if applicable) ## Blockers (unresolved issues, open questions). This enables the next agent to continue seamlessly.',\n },\n },\n required: [\"ticketSlug\", \"content\"],\n },\n },\n {\n name: \"tickets_create\",\n type: \"create\",\n description: `Create a new ticket in the \"${projectSlug}\" project queue`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n content: {\n type: \"string\",\n description:\n \"The generated ticket content. First line should be a clear descriptive title (becomes the slug). Body contains tasks, description, context as needed.\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to assign ticket to. Overrides PPM_AGENT_NAME env var. Omit for unassigned.\",\n },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"tickets_search\",\n type: \"search\",\n description: `Search for tickets by content in the \"${projectSlug}\" project`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description: \"Search query (min 3 characters)\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter results. Overrides PPM_AGENT_NAME env var. Omit for all tickets.\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"tickets_get\",\n type: \"get\",\n description: `Get a specific ticket by number or slug from \"${projectSlug}\" (read-only)`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug\",\n },\n },\n required: [\"ticketSlug\"],\n },\n },\n {\n name: \"tickets_list\",\n type: \"list\",\n description: `List active tickets in the \"${projectSlug}\" project (plan + open + working)`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter tickets. Overrides PPM_AGENT_NAME env var. Omit for all tickets.\",\n },\n },\n required: [],\n },\n },\n {\n name: \"tickets_update\",\n type: \"update\",\n description: `Update a ticket in the \"${projectSlug}\" project by appending content with timestamp`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n content: {\n type: \"string\",\n description: \"Update content to append to the ticket (markdown supported)\",\n },\n agent: {\n type: \"string\",\n description: \"Optional: Reassign ticket to this agent. Use empty string '' to unassign.\",\n },\n },\n required: [\"ticketSlug\", \"content\"],\n },\n },\n ];\n}\n\n/**\n * Get memory tool definitions with project-specific context\n */\nexport function getMemoryToolDefinitions(): Array<ToolDefinition & { type: MemoryToolType }> {\n return [\n {\n name: \"memories_load\",\n type: \"load\",\n description: `Load project memories: returns all rules (always) + relevant history (by query or recent). Use [MEMORY_LOAD] in prompts for automatic loading.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description:\n \"Optional: search query to filter agent memories. If not provided, returns recent memories.\",\n },\n },\n required: [],\n },\n },\n {\n name: \"memories_load_extreme\",\n type: \"load_extreme\",\n description: `Load project memories with FULL ticket context. Returns all matching memories, and for each memory linked to a ticket, includes the complete ticket content (tasks, updates, decisions). Use when you need deep historical context about past work.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description:\n \"Optional: search query to filter agent memories. If not provided, returns recent memories.\",\n },\n },\n required: [],\n },\n },\n {\n name: \"memories_add\",\n type: \"add\",\n description: `Record a project memory. Optionally links to working ticket if exactly one exists. Use for key decisions, patterns discovered, or important context.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n content: {\n type: \"string\",\n description:\n \"Memory content to record. Be concise and focused on key decisions, patterns, or context.\",\n },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memories_list_all\",\n type: \"list_all\",\n description: `List ALL project memories (rules and agent history). Returns complete memory list with IDs for review/cleanup. Use for memory audits or before bulk operations.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n typeFilter: {\n type: \"string\",\n enum: [\"all\", \"user\", \"agent\"],\n description: \"Optional: Filter by memory type. 'user' = rules, 'agent' = history. Default: 'all'\",\n },\n },\n required: [],\n },\n },\n ];\n}\n\n/**\n * Get global prompt tool definitions (not project-scoped)\n */\nexport function getPromptToolDefinitions(): ToolDefinition[] {\n return [\n {\n name: \"prompts_run\",\n description: \"Execute a prompt by slug. Use prompts_list to list available prompts.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n slug: {\n type: \"string\",\n description: \"Prompt slug to execute (e.g., 'code-review', 'plan')\",\n },\n },\n required: [\"slug\"],\n },\n },\n {\n name: \"prompts_list\",\n description: \"List all available prompts\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n search: {\n type: \"string\",\n description: \"Optional search term to filter prompts by name or description (case-insensitive)\",\n },\n },\n },\n },\n {\n name: \"prompts_update\",\n description:\n \"Read or update a prompt, snippet, or template. Without content: returns resource with context. With content: saves new version.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n slug: {\n type: \"string\",\n description:\n \"Resource slug to read or update. Searches prompts first, then snippets, then templates. Supports fuzzy matching.\",\n },\n content: {\n type: \"string\",\n description: \"New resource content (omit for read-only mode)\",\n },\n },\n required: [\"slug\"],\n },\n },\n ];\n}\n\n/**\n * Get all tool names (for validation)\n */\nexport function getAllToolNames(projectSlug: string): string[] {\n const ticketNames = getTicketToolDefinitions(projectSlug).map((t) => t.name);\n const memoryNames = getMemoryToolDefinitions().map((t) => t.name);\n const promptNames = getPromptToolDefinitions().map((t) => t.name);\n return [...ticketNames, ...memoryNames, ...promptNames];\n}\n\n/**\n * Check if a tool name is a known tool (excludes per-prompt tools)\n */\nexport function isKnownTool(toolName: string, projectSlug: string): boolean {\n return getAllToolNames(projectSlug).includes(toolName);\n}\n","// ============================================================================\n// MCP Tool Argument Types\n// ============================================================================\n\n/**\n * Arguments for the tickets_work tool\n * Optional ticketSlug: if provided, work on specific ticket; otherwise get next from queue\n * Optional agent: filter queue to specific agent (implement-agent-routing)\n */\nexport interface WorkToolArgs {\n ticketSlug?: string;\n agent?: string; // Agent filtering (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_close tool\n * Required ticketSlug to identify which ticket to close\n * Optional metadata for two-phase close flow (when on_close hook is configured)\n */\nexport interface CloseToolArgs {\n ticketSlug: string;\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Arguments for the tickets_create tool\n * Required content where first line becomes the slug\n * Optional agent: assign to specific agent (implement-agent-routing)\n */\nexport interface CreateToolArgs {\n content: string;\n agent?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_search tool\n * Required query string (min 3 characters)\n * Optional agent: filter search results to specific agent (implement-agent-routing)\n */\nexport interface SearchToolArgs {\n query: string;\n agent?: string; // Agent filtering (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_get tool\n * Required ticketSlug to identify which ticket to retrieve\n */\nexport interface GetToolArgs {\n ticketSlug: string;\n}\n\n/**\n * Arguments for the tickets_list tool\n * Optional agent: filter to specific agent's tickets (implement-agent-routing)\n */\nexport interface ListToolArgs {\n agent?: string; // Agent filtering (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_update tool\n * Required ticketSlug and content to append\n * Optional agent: reassign ticket to agent (empty string = unassign) (implement-agent-routing)\n */\nexport interface UpdateToolArgs {\n ticketSlug: string;\n content: string;\n agent?: string; // Agent reassignment (implement-agent-routing) - empty string = unassign\n}\n\n/**\n * Arguments for the tickets_pause tool\n * Required ticketSlug and content (checkpoint progress)\n */\nexport interface PauseToolArgs {\n ticketSlug: string;\n content: string;\n}\n\n/**\n * Arguments for the tickets_plan tool\n * Optional ticketSlug: if provided, work on specific plan ticket; otherwise get next from plan queue\n * Optional agent: filter queue to specific agent (implement-agent-routing)\n */\nexport interface PlanToolArgs {\n ticketSlug?: string;\n agent?: string;\n}\n\n/**\n * Arguments for the prompts_run tool\n * Required slug to identify which prompt to execute\n */\nexport interface PromptsRunArgs {\n slug: string;\n}\n\n/**\n * Arguments for the prompts_list tool\n * Optional search term to filter prompts\n */\nexport interface PromptsListArgs {\n search?: string;\n}\n\n/**\n * Arguments for the prompts_update tool\n * Required slug, optional content for write mode\n */\nexport interface PromptsUpdateArgs {\n slug: string;\n content?: string;\n}\n\n/**\n * Arguments for the memories_load tool\n * Optional query for filtering agent memories\n */\nexport interface MemoriesLoadArgs {\n query?: string;\n}\n\n/**\n * Arguments for the memories_add tool\n * Required content for the memory entry\n */\nexport interface MemoriesAddArgs {\n content: string;\n}\n\n/**\n * Arguments for the memories_list_all tool\n * Optional typeFilter for filtering by memory type\n */\nexport interface MemoriesListAllArgs {\n typeFilter?: \"all\" | \"user\" | \"agent\";\n}\n\n// ============================================================================\n// Convex Response Types (for MCP mutations/queries)\n// ============================================================================\n\n/**\n * Response from workMcpTicket mutation\n */\nexport interface WorkTicketResult {\n slug: string;\n ticketNumber?: number;\n status: string;\n content: string;\n startedAt?: number;\n pausedAt?: number; // If set, ticket was previously paused - look for checkpoint content\n remainingTickets: number;\n wasOpened: boolean;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from planMcpTicket mutation\n * Status always remains \"plan\" - no transition to working\n */\nexport interface PlanTicketResult {\n slug: string;\n ticketNumber?: number;\n status: \"plan\";\n content: string;\n startedAt?: number;\n remainingPlanTickets: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Access denied response from ticket operations\n */\nexport interface AccessDeniedResult {\n error: string;\n accessDenied: true;\n}\n\n/**\n * Type guard to check if a result is an access denied response\n */\nexport function isAccessDenied(result: unknown): result is AccessDeniedResult {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'accessDenied' in result &&\n (result as AccessDeniedResult).accessDenied === true\n );\n}\n\n/**\n * Plan status blocked response - returned when tickets_work is called on a plan-status ticket\n */\nexport interface PlanStatusBlockedResult {\n error: string;\n planStatusBlocked: true;\n ticketSlug: string;\n}\n\n/**\n * Type guard to check if a result is a plan status blocked response\n */\nexport function isPlanStatusBlocked(result: unknown): result is PlanStatusBlockedResult {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'planStatusBlocked' in result &&\n (result as PlanStatusBlockedResult).planStatusBlocked === true\n );\n}\n\n/**\n * Response from createMcpTicket mutation\n */\nexport interface CreateTicketResult {\n slug: string;\n ticketNumber?: number;\n preview: string;\n position: number;\n totalPlan: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from closeMcpTicket mutation\n */\nexport interface CloseTicketResult {\n slug: string;\n status: string;\n closedAt: number;\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Response from updateMcpTicket mutation\n */\nexport interface UpdateTicketResult {\n slug: string;\n ticketNumber?: number;\n status: string;\n updatedAt: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from pauseMcpTicket mutation\n */\nexport interface PauseTicketResult {\n slug: string;\n ticketNumber?: number;\n status: \"open\";\n pausedAt: number;\n}\n\n/**\n * Response from getMcpTicket query\n */\nexport interface GetTicketResult {\n slug: string;\n ticketNumber?: number;\n content: string;\n status: string;\n createdAt: number;\n startedAt?: number;\n closedAt?: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Response from listMcpTickets query\n */\nexport interface ListTicketItem {\n position: number;\n slug: string;\n ticketNumber?: number;\n status: string;\n preview: string;\n createdAt: number;\n startedAt?: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from searchMcpTickets query\n */\nexport interface SearchTicketItem {\n slug: string;\n ticketNumber?: number;\n status: string;\n matchSnippet: string;\n createdAt: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Response from prompt metadata query\n */\nexport interface PromptMetadata {\n slug: string;\n description?: string;\n folderPath?: string; // Full path like \"coding/templates/planning\"\n slashCommand?: boolean; // Register as MCP slash command (/ppm:slug)\n}\n\n/**\n * Response from loadMemories query\n */\nexport interface LoadMemoriesResult {\n userMemories: Array<{\n content: string;\n createdAt: number;\n }>;\n agentMemories: Array<{\n content: string;\n ticketSlug?: string;\n ticketNumber?: number;\n createdAt: number;\n }>;\n}\n\n/**\n * Response from addMemory mutation\n */\nexport interface AddMemoryResult {\n success: boolean;\n memoryId: string;\n linkedTicket: {\n slug: string;\n number: number;\n } | null;\n /** True when memory was linked to a recently closed ticket (fallback) instead of a working ticket */\n linkedViaFallback: boolean;\n}\n\n/**\n * Response from listAllMemories query\n */\nexport interface ListAllMemoriesResult {\n memories: Array<{\n id: string;\n type: \"user\" | \"agent\";\n content: string;\n ticketSlug?: string;\n ticketNumber?: number;\n createdAt: number;\n }>;\n totalCount: number;\n}\n\n/**\n * Response from loadMemoriesExtreme query\n * Returns memories with full ticket content for linked tickets\n */\nexport interface LoadMemoriesExtremeResult {\n userMemories: Array<{\n content: string;\n createdAt: number;\n }>;\n agentMemories: Array<{\n content: string;\n ticketSlug?: string;\n ticketNumber?: number;\n createdAt: number;\n ticket?: {\n slug: string;\n ticketNumber: number;\n content: string;\n status: string;\n } | null;\n }>;\n}\n\n/**\n * Resource type returned by prompts_update tool\n */\nexport type ResourceType = \"prompt\" | \"snippet\" | \"template\";\n\n/**\n * Response from updateMcpPrompt mutation (read mode)\n */\nexport interface UpdatePromptReadResult {\n success: true;\n mode: \"read\";\n resourceType: ResourceType;\n matchType: \"exact\" | \"prefix\" | \"contains\";\n slug: string;\n description: string;\n content: string;\n version?: number; // Only for prompts\n context?: {\n variables: Array<{ slug: string; reference: string; type: string; description: string }>;\n snippets: Array<{ slug: string; reference: string; description: string }>;\n prompts: Array<{ slug: string; reference: string; description: string }>;\n };\n editingGuidance: string;\n hasAiTags?: boolean;\n aiTags?: string[];\n}\n\n/**\n * Response from updateMcpPrompt mutation (write mode)\n */\nexport interface UpdatePromptWriteResult {\n success: true;\n mode: \"write\";\n resourceType: ResourceType;\n slug: string;\n version?: number; // Only for prompts\n updatedAt?: string;\n message: string;\n}\n\n/**\n * Response from updateMcpPrompt mutation (error)\n */\nexport interface UpdatePromptErrorResult {\n success: false;\n error: string;\n suggestions?: string[];\n}\n\n/**\n * Union type for all updateMcpPrompt responses\n */\nexport type UpdatePromptResult =\n | UpdatePromptReadResult\n | UpdatePromptWriteResult\n | UpdatePromptErrorResult;\n\n/**\n * Account-scoped prompt match result types\n */\nexport type AccountScopedPromptResult =\n | { matchType: \"exact\" | \"prefix\" | \"contains\"; slug: string; description?: string; flattenedPrompt?: string }\n | { matchType: \"ambiguous\"; suggestions: string[] }\n | null;\n\n// ============================================================================\n// Argument Parsing Functions\n// ============================================================================\n\n/**\n * Parse and validate arguments for tickets_work tool\n */\nexport function parseWorkArgs(args: unknown): WorkToolArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n ticketSlug: typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent filtering (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_close tool\n * Returns null if required argument is missing\n */\nexport function parseCloseArgs(args: unknown): CloseToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n if (!ticketSlug) return null;\n\n // Parse optional metadata object\n let metadata: Record<string, string | number | boolean> | undefined;\n if (parsed?.metadata && typeof parsed.metadata === 'object' && !Array.isArray(parsed.metadata)) {\n metadata = {};\n for (const [key, value] of Object.entries(parsed.metadata as Record<string, unknown>)) {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n metadata[key] = value;\n }\n }\n // Only keep metadata if it has entries\n if (Object.keys(metadata).length === 0) {\n metadata = undefined;\n }\n }\n\n return { ticketSlug, metadata };\n}\n\n/**\n * Parse and validate arguments for tickets_create tool\n * Returns null if required argument is missing\n */\nexport function parseCreateArgs(args: unknown): CreateToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!content) return null;\n\n return {\n content,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent assignment (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_search tool\n * Returns null if required argument is missing or too short\n */\nexport function parseSearchArgs(args: unknown): SearchToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const query = typeof parsed?.query === 'string' ? parsed.query : undefined;\n if (!query || query.length < 3) return null;\n return {\n query,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent filtering (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_get tool\n * Returns null if required argument is missing\n */\nexport function parseGetArgs(args: unknown): GetToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n if (!ticketSlug) return null;\n return { ticketSlug };\n}\n\n/**\n * Parse arguments for tickets_list tool\n * Optional agent parameter for filtering\n */\nexport function parseListArgs(args: unknown): ListToolArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent filtering (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_update tool\n * Returns null if any required argument is missing\n */\nexport function parseUpdateArgs(args: unknown): UpdateToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!ticketSlug || !content) return null;\n return {\n ticketSlug,\n content,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent reassignment (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_pause tool\n * Returns null if any required argument is missing\n */\nexport function parsePauseArgs(args: unknown): PauseToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!ticketSlug || !content) return null;\n return { ticketSlug, content };\n}\n\n/**\n * Parse and validate arguments for tickets_plan tool\n */\nexport function parsePlanArgs(args: unknown): PlanToolArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n ticketSlug: typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined,\n };\n}\n\n/**\n * Parse and validate arguments for prompts_run tool\n * Returns null if required argument is missing\n */\nexport function parsePromptsRunArgs(args: unknown): PromptsRunArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const slug = typeof parsed?.slug === 'string' ? parsed.slug : undefined;\n if (!slug) return null;\n return { slug };\n}\n\n/**\n * Parse arguments for prompts_list tool\n */\nexport function parsePromptsListArgs(args: unknown): PromptsListArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n search: typeof parsed?.search === 'string' ? parsed.search : undefined,\n };\n}\n\n/**\n * Parse and validate arguments for prompts_update tool\n * Returns null if required slug is missing\n */\nexport function parsePromptsUpdateArgs(args: unknown): PromptsUpdateArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const slug = typeof parsed?.slug === 'string' ? parsed.slug : undefined;\n if (!slug) return null;\n return {\n slug,\n content: typeof parsed?.content === 'string' ? parsed.content : undefined,\n };\n}\n\n/**\n * Parse arguments for memories_load tool\n * Optional query parameter for filtering agent memories\n */\nexport function parseMemoriesLoadArgs(args: unknown): MemoriesLoadArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n query: typeof parsed?.query === 'string' ? parsed.query : undefined,\n };\n}\n\n/**\n * Parse and validate arguments for memories_add tool\n * Returns null if required content is missing\n */\nexport function parseMemoriesAddArgs(args: unknown): MemoriesAddArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!content) return null;\n return { content };\n}\n\n/**\n * Parse arguments for memories_list_all tool\n * Optional typeFilter parameter for filtering by memory type\n */\nexport function parseMemoriesListAllArgs(args: unknown): MemoriesListAllArgs {\n const parsed = args as Record<string, unknown> | undefined;\n const typeFilter = parsed?.typeFilter;\n return {\n typeFilter: (typeFilter === \"all\" || typeFilter === \"user\" || typeFilter === \"agent\")\n ? typeFilter\n : undefined,\n };\n}\n\n// ============================================================================\n// Legacy Types (kept for backwards compatibility)\n// ============================================================================\n\n/**\n * @deprecated Legacy type - prompts are now account-scoped (no projectSlug)\n * Kept for backwards compatibility during transition period.\n */\nexport interface McpPrompt {\n slug: string;\n name: string;\n description?: string;\n flattenedPrompt?: string;\n folderPath?: string; // Folder organization (used for ZIP downloads, not slash commands)\n projectSlug?: string; // @deprecated - prompts are now account-scoped\n projectName?: string; // @deprecated - prompts are now account-scoped\n}\n\n/**\n * @deprecated Legacy type - prompts are now account-scoped (no projectSlug)\n * Kept for backwards compatibility during transition period.\n */\nexport interface McpPromptMetadata {\n slug: string;\n description?: string;\n projectSlug?: string; // @deprecated - prompts are now account-scoped\n}\n\n// Note: McpCommandMetadata and McpCommandFull removed - commands resource eliminated\n\n/**\n * @deprecated Legacy type - prompts are now account-scoped (no projectSlug)\n * Kept for backwards compatibility during transition period.\n */\nexport interface McpPromptFull {\n slug: string;\n description?: string;\n flattenedPrompt?: string;\n projectSlug?: string; // @deprecated - prompts are now account-scoped\n}\n\n/**\n * @deprecated Legacy type - use account-scoped prompt queries instead\n * Kept for backwards compatibility during transition period.\n */\nexport type PromptMatchResult =\n | { matchType: \"exact\" | \"prefix\" | \"contains\"; slug: string; description?: string; flattenedPrompt?: string; projectSlug: string }\n | { matchType: \"ambiguous\"; suggestions: string[] }\n | null;\n\n/**\n * Configuration for the MCP server\n *\n * Authentication: Project Token (PPM_PROJECT_TOKEN)\n * Provides scoped access to a single project for both prompts and tickets.\n * The token's ownerId determines which prompts are accessible (account-scoped).\n *\n * Note: API Key auth (PPM_API_KEY) has been deprecated.\n * All authentication now uses project tokens.\n */\nexport interface ServerConfig {\n projectToken: string; // Required - scoped access to a single project\n isDev: boolean;\n convexUrl: string;\n}\n\n/**\n * Result of project token validation\n * Token is now stored directly on the projects table (single token per project)\n */\nexport interface ProjectTokenValidation {\n valid: boolean;\n projectId?: string;\n projectSlug?: string;\n ownerId?: string;\n error?: string;\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type { ServerConfig, PromptMetadata, AccountScopedPromptResult } from \"./types.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n * This allows us to use string function names while maintaining type safety\n * for the response types through explicit casting.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * Sanitizes a string for use in MCP tool names.\n * Ensures output matches MCP protocol pattern: ^[a-zA-Z0-9_-]{1,64}$\n *\n * @param str - Raw string to sanitize (project slug, folder path, or prompt slug)\n * @returns Sanitized string safe for MCP tool names\n */\nexport function sanitizeForMcp(str: string): string {\n return str\n .trim() // Remove leading/trailing whitespace first\n .toLowerCase() // Convert to lowercase for consistency\n .replace(/[^a-z0-9_-]/g, '-') // Replace ALL invalid chars (including spaces!) with hyphens\n .replace(/-+/g, '-') // Collapse multiple consecutive hyphens into one\n .replace(/^-+|-+$/g, '') // Remove leading and trailing hyphens\n .trim(); // Final trim to ensure no whitespace\n}\n\n// Note: The following legacy functions have been removed as prompts are now account-scoped:\n// - buildPromptName (was project:prompt format, now prompts are global)\n// - buildPromptNameFromMetadata (was project:prompt format)\n// - buildPromptSchema (used buildPromptName)\n// - buildPromptHandler (used project-scoped getMcpPrompts query)\n// - fetchAndExecutePrompt (used project-scoped getMcpPromptBySlug query)\n//\n// Use fetchAndExecuteAccountScopedPrompt instead for all prompt execution.\n\n/**\n * Custom error class for ambiguous prompt matches\n * Contains suggestions for the user to choose from\n */\nexport class AmbiguousPromptError extends Error {\n suggestions: string[];\n\n constructor(promptSlug: string, suggestions: string[]) {\n super(`Multiple prompts match \"${promptSlug}\". Please be more specific.`);\n this.name = \"AmbiguousPromptError\";\n this.suggestions = suggestions;\n }\n}\n\n/**\n * Fetch account-scoped prompt metadata using project token auth.\n *\n * @param client - Convex HTTP client\n * @param projectToken - Project token for authentication\n * @returns Account-scoped prompts for this project\n */\nexport async function fetchAccountScopedPromptMetadataByToken(\n client: ConvexHttpClient,\n projectToken: string\n): Promise<PromptMetadata[]> {\n try {\n // Cast to our typed client for string-based function references\n const typedClient = client as ConvexClientWithStringRefs;\n const metadata = await typedClient.query<PromptMetadata[]>(\n \"mcp_prompts:getAccountScopedPromptMetadataByToken\",\n { projectToken }\n );\n return metadata;\n } catch (error) {\n throw new Error(\n `Failed to fetch prompts via project token: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n}\n\n// Note: AccountScopedPromptResult type is imported from ./types.js\n\n/**\n * Fetch a single account-scoped prompt and execute it\n *\n * Account-scoped prompts are global (no project prefix required).\n * This is for prompts that don't have a projectId.\n *\n * Uses project token authentication: access via token's ownerId.\n *\n * Matching algorithm supports exact, prefix, and contains matching.\n */\nexport async function fetchAndExecuteAccountScopedPrompt(\n promptSlug: string,\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<{ messages: Array<{ role: string; content: { type: \"text\"; text: string } }> }> {\n // Cast to our typed client for string-based function references\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n // Project token auth - access via token's owner\n // NOTE: This is a mutation (not query) to enable analytics logging\n const result = await typedClient.mutation<AccountScopedPromptResult>(\n \"mcp_prompts:getAccountScopedPromptBySlugByToken\",\n {\n projectToken: config.projectToken,\n promptSlug,\n }\n );\n\n // Handle null - no matches found\n if (!result) {\n throw new Error(\n `Prompt \"${promptSlug}\" not found. Use system:prompts to list available prompts.`\n );\n }\n\n // Handle ambiguous matches - throw custom error with suggestions\n if (result.matchType === \"ambiguous\") {\n throw new AmbiguousPromptError(promptSlug, result.suggestions);\n }\n\n // Handle successful match (exact, prefix, or contains)\n if (!result.flattenedPrompt) {\n throw new Error(\n `Prompt \"${result.slug}\" has no flattened content. Please re-save the prompt to regenerate it.`\n );\n }\n\n // Log match type for debugging\n const matchNote = result.matchType === \"exact\"\n ? \"exact match\"\n : result.matchType === \"prefix\"\n ? `prefix match → ${result.slug}`\n : `contains match → ${result.slug}`;\n console.error(`[MCP] Fetched account-scoped prompt: ${promptSlug} (${matchNote})`);\n\n // Return raw flattened prompt (client will parse YAML front matter)\n return {\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\" as const,\n text: result.flattenedPrompt,\n },\n },\n ],\n };\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type {\n ServerConfig,\n UpdatePromptResult,\n PromptMetadata,\n} from \"../types.js\";\nimport {\n parsePromptsRunArgs,\n parsePromptsListArgs,\n parsePromptsUpdateArgs,\n} from \"../types.js\";\nimport { buildAuthArgs } from \"../auth/index.js\";\nimport {\n fetchAndExecuteAccountScopedPrompt,\n AmbiguousPromptError,\n} from \"../prompt-builder.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * MCP tool response format\n * Note: Index signature required for MCP SDK v1.20+ compatibility\n */\nexport interface McpToolResponse {\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n [x: string]: unknown;\n}\n\n/**\n * Handle prompts_run tool - execute a prompt by slug\n */\nexport async function handlePromptsRun(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<McpToolResponse> {\n const parsedArgs = parsePromptsRunArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing 'slug' parameter. Provide prompt slug (e.g., 'code-review', 'plan').\n\nUse \\`prompts_list\\` to list available prompts.`,\n },\n ],\n isError: true,\n };\n }\n\n const { slug: promptSlug } = parsedArgs;\n\n // Execute the prompt using account-scoped lookup\n try {\n const result = await fetchAndExecuteAccountScopedPrompt(\n promptSlug,\n config,\n convexClient\n );\n\n // Convert prompt result to tool result format\n const promptText = result.messages.map((msg) => msg.content.text).join(\"\\n\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: promptText,\n },\n ],\n };\n } catch (error) {\n // Handle ambiguous prompt matches with helpful suggestions\n if (error instanceof AmbiguousPromptError) {\n const suggestionsList = error.suggestions.map((s) => ` • ${s}`).join(\"\\n\");\n console.error(`[MCP] prompts_run ambiguous match:`, error.suggestions);\n return {\n content: [\n {\n type: \"text\",\n text: `Multiple prompts match \"${promptSlug}\". Please specify one of:\\n\\n${suggestionsList}\\n\\nExample: \\`prompts_run ${error.suggestions[0]}\\``,\n },\n ],\n isError: true,\n };\n }\n\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] prompts_run error:`, error);\n return {\n content: [\n {\n type: \"text\",\n text: `Error executing prompt \"${promptSlug}\": ${errorMessage}`,\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Handle prompts_list tool - list available prompts\n */\nexport async function handlePromptsList(\n args: unknown,\n _config: ServerConfig,\n _convexClient: ConvexHttpClient,\n accountScopedPrompts: PromptMetadata[]\n): Promise<McpToolResponse> {\n const { search: searchTerm } = parsePromptsListArgs(args);\n\n // Use account-scoped prompts (global, no project filter)\n let filteredPrompts = [...accountScopedPrompts];\n\n // Filter by search term if provided\n if (searchTerm) {\n const lowerSearch = searchTerm.toLowerCase();\n filteredPrompts = filteredPrompts.filter(\n (p) =>\n p.slug.toLowerCase().includes(lowerSearch) ||\n p.description?.toLowerCase().includes(lowerSearch)\n );\n }\n\n // Sort prompts by slug\n filteredPrompts.sort((a, b) => a.slug.localeCompare(b.slug));\n\n // Build user prompts list\n const userPromptList = filteredPrompts\n .map((p) => {\n const desc = p.description || \"No description\";\n return `• ${p.slug}\\n Description: ${desc}`;\n })\n .join(\"\\n\\n\");\n\n const summary = searchTerm\n ? `Found ${filteredPrompts.length} prompt(s) matching \"${searchTerm}\":`\n : `Available prompts (${filteredPrompts.length} total):`;\n\n return {\n content: [\n {\n type: \"text\",\n text: userPromptList\n ? `${summary}\\n\\n${userPromptList}`\n : `${summary}\\n\\nNo prompts found.`,\n },\n ],\n };\n}\n\n/**\n * Handle prompts_update tool - read or update a prompt/snippet/template\n */\nexport async function handlePromptsUpdate(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<McpToolResponse> {\n const parsedArgs = parsePromptsUpdateArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing 'slug' parameter. Provide prompt slug to read or update.\n\nUsage:\n- Read mode: prompts_update { slug: \"my-prompt\" }\n- Write mode: prompts_update { slug: \"my-prompt\", content: \"new content...\" }`,\n },\n ],\n isError: true,\n };\n }\n\n try {\n const typedClient = convexClient as ConvexClientWithStringRefs;\n const result = await typedClient.mutation<UpdatePromptResult>(\n \"mcp_prompts:updateMcpPrompt\",\n {\n ...buildAuthArgs(config),\n promptSlug: parsedArgs.slug,\n content: parsedArgs.content,\n }\n );\n\n if (!result.success) {\n // Handle error (not found, ambiguous)\n const errorResult = result as { success: false; error: string; suggestions?: string[] };\n if (errorResult.suggestions) {\n const suggestionsList = errorResult.suggestions.map((s) => ` • ${s}`).join(\"\\n\");\n return {\n content: [\n {\n type: \"text\",\n text: `${errorResult.error}\\n\\nDid you mean one of these?\\n${suggestionsList}`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: errorResult.error }],\n isError: true,\n };\n }\n\n // Handle read mode response\n if (result.mode === \"read\") {\n const readResult = result as {\n mode: \"read\";\n resourceType: \"prompt\" | \"snippet\" | \"template\";\n matchType: string;\n slug: string;\n description: string;\n content: string;\n version?: number;\n context?: object;\n editingGuidance: string;\n hasAiTags?: boolean;\n aiTags?: string[];\n };\n\n // Format the response with all context\n const matchNote =\n readResult.matchType !== \"exact\"\n ? `\\n_Note: Matched via ${readResult.matchType} match_`\n : \"\";\n\n // AI tag notice if tags detected\n const aiTagNotice = readResult.hasAiTags\n ? `\\n\\n## ⚡ AI Tags Detected\\nThis ${readResult.resourceType} contains AI tags that need processing: **${readResult.aiTags?.join(\", \")}**\\n\\nProcess these tags by reading the instructions in each tag, generating appropriate content, and saving the result with the content parameter.`\n : \"\";\n\n // Version info (only for prompts)\n const versionInfo = readResult.version !== undefined ? ` (v${readResult.version})` : \"\";\n\n // Resource type label (capitalize first letter)\n const resourceLabel =\n readResult.resourceType.charAt(0).toUpperCase() + readResult.resourceType.slice(1);\n\n // Context section (only for prompts)\n const contextSection = readResult.context\n ? `\\n\\n## Available Resources\\n\\`\\`\\`json\\n${JSON.stringify(readResult.context, null, 2)}\\n\\`\\`\\``\n : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `# ${resourceLabel}: ${readResult.slug}${versionInfo}${matchNote}${aiTagNotice}\n\n## Description\n${readResult.description || \"No description\"}\n\n## Content\n\\`\\`\\`\n${readResult.content}\n\\`\\`\\`${contextSection}\n\n${readResult.editingGuidance}\n\n---\n_To update this ${readResult.resourceType}, call prompts_update with content parameter._`,\n },\n ],\n };\n }\n\n // Handle write mode response\n if (result.mode === \"write\") {\n const writeResult = result as {\n mode: \"write\";\n resourceType: \"prompt\" | \"snippet\" | \"template\";\n slug: string;\n version?: number;\n updatedAt?: string;\n message: string;\n };\n\n // Resource type label (capitalize first letter)\n const resourceLabel =\n writeResult.resourceType.charAt(0).toUpperCase() + writeResult.resourceType.slice(1);\n\n // Version info (only for prompts)\n const versionInfo = writeResult.version !== undefined ? `\\nVersion: ${writeResult.version}` : \"\";\n\n // Updated timestamp\n const updatedInfo = writeResult.updatedAt ? `\\nUpdated: ${writeResult.updatedAt}` : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ ${writeResult.message}\n\n${resourceLabel}: ${writeResult.slug}${versionInfo}${updatedInfo}`,\n },\n ],\n };\n }\n\n // Shouldn't reach here, but handle gracefully\n return {\n content: [{ type: \"text\", text: \"Unknown response format\" }],\n isError: true,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] prompts_update error:`, error);\n return {\n content: [\n {\n type: \"text\",\n text: `Error updating prompt: ${errorMessage}`,\n },\n ],\n isError: true,\n };\n }\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type {\n ServerConfig,\n WorkTicketResult,\n AccessDeniedResult,\n PlanStatusBlockedResult,\n CreateTicketResult,\n CloseTicketResult,\n PauseTicketResult,\n UpdateTicketResult,\n GetTicketResult,\n ListTicketItem,\n SearchTicketItem,\n} from \"../types.js\";\nimport type { PlanTicketResult } from \"../types.js\";\nimport {\n parseWorkArgs,\n parsePlanArgs,\n parseCloseArgs,\n parsePauseArgs,\n parseCreateArgs,\n parseSearchArgs,\n parseGetArgs,\n parseListArgs,\n parseUpdateArgs,\n isAccessDenied,\n isPlanStatusBlocked,\n} from \"../types.js\";\nimport { buildAuthArgs, resolveAgent } from \"../auth/index.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * MCP tool response format\n * Note: Index signature required for MCP SDK v1.20+ compatibility\n */\nexport interface McpToolResponse {\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n [x: string]: unknown;\n}\n\n/**\n * Handle tickets_work tool - get next ticket or work on specific ticket\n */\nexport async function handleTicketsWork(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { ticketSlug, agent } = parseWorkArgs(args);\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<WorkTicketResult | AccessDeniedResult | PlanStatusBlockedResult | null>(\n \"mcp_tickets:workMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n agentId: resolvedAgent,\n }\n );\n\n if (!result) {\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n const message = ticketSlug\n ? `Ticket \"${ticketSlug}\" not found or not in open/working status in project \"${projectSlug}\"${agentContext}.`\n : `No open tickets${agentContext} in project \"${projectSlug}\".`;\n return {\n content: [{ type: \"text\", text: message }],\n };\n }\n\n if (isAccessDenied(result)) {\n return {\n content: [{ type: \"text\", text: `Access denied: ${result.error}` }],\n isError: true,\n };\n }\n\n if (isPlanStatusBlocked(result)) {\n return {\n content: [{ type: \"text\", text: result.error }],\n isError: true,\n };\n }\n\n const workResult = result as WorkTicketResult;\n const startedInfo = workResult.startedAt\n ? `\\nStarted: ${new Date(workResult.startedAt).toISOString()}`\n : \"\";\n\n const pausedNotice = workResult.pausedAt\n ? `\\n\\n**⚠️ PAUSED TICKET HANDOFF**: This ticket was paused on ${new Date(workResult.pausedAt).toISOString()}. A previous agent checkpointed their progress. Review the checkpoint content below (look for \"## Progress\", \"## Context\", \"## Remaining\", \"## Blockers\" sections) and resume where they left off.\\n`\n : \"\";\n\n const statusNote = workResult.wasOpened\n ? `_Ticket moved to working status. ${workResult.remainingTickets} ticket(s) remaining in queue._`\n : `_Resuming work on this ticket. ${workResult.remainingTickets} ticket(s) in queue._`;\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ticket: ${workResult.slug} [WORKING]${startedInfo}${pausedNotice}\n\n${workResult.content}\n\n---\n${statusNote}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_work error:`, error);\n return {\n content: [{ type: \"text\", text: `Error getting work: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_plan tool - get planning work without status change\n */\nexport async function handleTicketsPlan(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { ticketSlug, agent } = parsePlanArgs(args);\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<PlanTicketResult | null>(\n \"mcp_tickets:planMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n agentId: resolvedAgent,\n }\n );\n\n if (!result) {\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n const message = ticketSlug\n ? `Ticket \"${ticketSlug}\" not found or not in plan status in project \"${projectSlug}\"${agentContext}.`\n : `No plan tickets${agentContext} in project \"${projectSlug}\".`;\n return {\n content: [{ type: \"text\", text: message }],\n };\n }\n\n const startedInfo = result.startedAt\n ? `\\nStarted: ${new Date(result.startedAt).toISOString()}`\n : \"\";\n\n const planningBanner = `⚠️ PLANNING MODE REQUIRED\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nThis ticket is in PLAN status. You may ONLY:\n• Create/update plan files\n• Update this ticket with planning notes\n• Create sub-tickets for implementation\n\nDO NOT: Write code or make implementation changes.\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;\n\n const statusNote = `_Ticket remains in plan status. ${result.remainingPlanTickets} plan ticket(s) remaining in queue._`;\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ticket: ${result.slug} [PLAN]${startedInfo}\n\n${planningBanner}\n\n${result.content}\n\n---\n${statusNote}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_plan error:`, error);\n return {\n content: [{ type: \"text\", text: `Error getting plan work: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_create tool - create a new ticket\n */\nexport async function handleTicketsCreate(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseCreateArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the ticket content (first line becomes the slug).`,\n },\n ],\n isError: true,\n };\n }\n\n const { content, agent } = parsedArgs;\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<CreateTicketResult>(\n \"mcp_tickets:createMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n content,\n agentId: resolvedAgent,\n }\n );\n\n const agentInfo = result.agentId ? `\\nAssigned to: ${result.agentId}` : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Created ticket [${result.slug}] in plan queue for project \"${projectSlug}\".${agentInfo}\n\nPosition: #${result.position} of ${result.totalPlan} plan tickets\nPreview: ${result.preview}\n\n_Ticket created in plan queue. Use \\`tickets_work ${result.slug}\\` to move it to working status._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_create error:`, error);\n return {\n content: [{ type: \"text\", text: `Error creating ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_close tool - close a working ticket\n */\nexport async function handleTicketsClose(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseCloseArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Usage: Provide a ticket number (e.g., \"102\") or full slug (e.g., \"102-fix-auth\").`,\n },\n ],\n isError: true,\n };\n }\n\n const { ticketSlug, metadata } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<CloseTicketResult>(\n \"mcp_tickets:closeMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n metadata,\n }\n );\n\n let responseText = `✅ Ticket [${result.slug}] closed in project \"${projectSlug}\".\n\nClosed at: ${new Date(result.closedAt).toISOString()}`;\n\n if (result.metadata && Object.keys(result.metadata).length > 0) {\n responseText += `\\n\\n**Metadata saved:**`;\n for (const [key, value] of Object.entries(result.metadata)) {\n responseText += `\\n- ${key}: ${JSON.stringify(value)}`;\n }\n }\n\n responseText += `\\n\\n_Reminder: Ensure all embedded \\`[RUN_PROMPT ...]\\` directives were executed before closing._`;\n\n return {\n content: [{ type: \"text\", text: responseText }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_close error:`, error);\n return {\n content: [{ type: \"text\", text: `Error closing ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_pause tool - pause a working ticket and return to queue\n */\nexport async function handleTicketsPause(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parsePauseArgs(args);\n\n if (!parsedArgs) {\n const rawArgs = args as Record<string, unknown> | undefined;\n const hasTicketSlug = typeof rawArgs?.ticketSlug === \"string\" && rawArgs.ticketSlug;\n const hasContent = typeof rawArgs?.content === \"string\" && rawArgs.content;\n\n if (!hasTicketSlug) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n if (!hasContent) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Describe what's done, what remains, and any blockers.`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: `Error: Missing required parameters.` }],\n isError: true,\n };\n }\n\n const { ticketSlug, content } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<PauseTicketResult>(\n \"mcp_tickets:pauseMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n content,\n }\n );\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Ticket [${result.slug}] paused and returned to open queue in project \"${projectSlug}\".\n\nPaused at: ${new Date(result.pausedAt).toISOString()}\n\n_Ticket moved from working → open. Checkpoint content has been appended. Any agent can pick it up with \\`tickets_work\\`._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_pause error:`, error);\n return {\n content: [{ type: \"text\", text: `Error pausing ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_search tool - search tickets by content\n */\nexport async function handleTicketsSearch(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseSearchArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [{ type: \"text\", text: `Error: Search query must be at least 3 characters` }],\n isError: true,\n };\n }\n\n const { query, agent } = parsedArgs;\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<SearchTicketItem[]>(\"mcp_tickets:searchMcpTickets\", {\n ...buildAuthArgs(config),\n projectSlug,\n query,\n agentId: resolvedAgent,\n });\n\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n\n if (result.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No tickets found matching \"${query}\"${agentContext} in project \"${projectSlug}\".`,\n },\n ],\n };\n }\n\n const formattedList = result\n .map((t) => {\n const statusBadge =\n t.status === \"open\"\n ? \"🟢\"\n : t.status === \"working\"\n ? \"🟡\"\n : t.status === \"closed\"\n ? \"⚫\"\n : \"⚪\";\n const num = t.ticketNumber ? `#${t.ticketNumber}` : \"\";\n const agentBadge = t.agentId ? ` [${t.agentId}]` : \"\";\n const metadataHint =\n t.metadata && Object.keys(t.metadata).length > 0\n ? ` {${Object.keys(t.metadata).length} meta}`\n : \"\";\n return `${statusBadge} ${num} ${t.slug}${agentBadge}${metadataHint}\\n ${t.matchSnippet}`;\n })\n .join(\"\\n\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${result.length} ticket(s) matching \"${query}\"${agentContext}:\\n\\n${formattedList}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_search error:`, error);\n return {\n content: [{ type: \"text\", text: `Error searching tickets: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_get tool - get a specific ticket (read-only)\n */\nexport async function handleTicketsGet(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseGetArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n\n const { ticketSlug } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<GetTicketResult | AccessDeniedResult | null>(\n \"mcp_tickets:getMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n }\n );\n\n if (!result) {\n return {\n content: [\n {\n type: \"text\",\n text: `Ticket \"${ticketSlug}\" not found in project \"${projectSlug}\".`,\n },\n ],\n };\n }\n\n if (isAccessDenied(result)) {\n return {\n content: [{ type: \"text\", text: `Access denied: ${result.error}` }],\n isError: true,\n };\n }\n\n const getResult = result as GetTicketResult;\n\n const statusBadge = getResult.status.toUpperCase();\n const startedInfo = getResult.startedAt\n ? `\\nStarted: ${new Date(getResult.startedAt).toISOString()}`\n : \"\";\n const closedInfo = getResult.closedAt\n ? `\\nClosed: ${new Date(getResult.closedAt).toISOString()}`\n : \"\";\n\n let metadataInfo = \"\";\n if (getResult.metadata && Object.keys(getResult.metadata).length > 0) {\n metadataInfo = \"\\n\\n**Metadata:**\";\n for (const [key, value] of Object.entries(getResult.metadata)) {\n metadataInfo += `\\n- ${key}: ${JSON.stringify(value)}`;\n }\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ticket: ${getResult.slug} [${statusBadge}]${startedInfo}${closedInfo}\n\n${getResult.content}${metadataInfo}\n\n---\n_Read-only inspection. Use tickets_work to start working on this ticket._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_get error:`, error);\n return {\n content: [{ type: \"text\", text: `Error getting ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_list tool - list active tickets\n */\nexport async function handleTicketsList(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { agent } = parseListArgs(args);\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<ListTicketItem[]>(\"mcp_tickets:listMcpTickets\", {\n ...buildAuthArgs(config),\n projectSlug,\n agentId: resolvedAgent,\n });\n\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n\n if (result.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No active tickets${agentContext} in project \"${projectSlug}\". All tickets are closed.`,\n },\n ],\n };\n }\n\n const openTickets = result.filter((t) => t.status === \"open\");\n const workingTickets = result.filter((t) => t.status === \"working\");\n const planTickets = result.filter((t) => t.status === \"plan\");\n\n const formatTicketLine = (t: ListTicketItem) => {\n const num = t.ticketNumber ? `#${t.ticketNumber}` : \"\";\n const agentBadge = !resolvedAgent && t.agentId ? ` [${t.agentId}]` : \"\";\n return ` ${t.position}. ${num} ${t.slug}${agentBadge}\\n ${t.preview}`;\n };\n\n const sections: string[] = [];\n\n if (openTickets.length > 0) {\n sections.push(\n `**🟢 Open (${openTickets.length})**\\n${openTickets.map(formatTicketLine).join(\"\\n\")}`\n );\n }\n if (workingTickets.length > 0) {\n sections.push(\n `**🟡 Working (${workingTickets.length})**\\n${workingTickets.map(formatTicketLine).join(\"\\n\")}`\n );\n }\n if (planTickets.length > 0) {\n sections.push(\n `**⚪ Plan (${planTickets.length})**\\n${planTickets.map(formatTicketLine).join(\"\\n\")}`\n );\n }\n\n const headerSuffix = resolvedAgent ? ` (Agent: ${resolvedAgent})` : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Active Queue: ${projectSlug}${headerSuffix}\\n\\n${result.length} ticket(s) in queue\\n\\n${sections.join(\"\\n\\n\")}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_list error:`, error);\n return {\n content: [{ type: \"text\", text: `Error listing tickets: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_update tool - append content to a ticket\n */\nexport async function handleTicketsUpdate(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseUpdateArgs(args);\n\n if (!parsedArgs) {\n const rawArgs = args as Record<string, unknown> | undefined;\n const hasTicketSlug = typeof rawArgs?.ticketSlug === \"string\" && rawArgs.ticketSlug;\n const hasContent = typeof rawArgs?.content === \"string\" && rawArgs.content;\n\n if (!hasTicketSlug) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n if (!hasContent) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the update content to append to the ticket.`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: `Error: Missing required parameters.` }],\n isError: true,\n };\n }\n\n const { ticketSlug, content, agent } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<UpdateTicketResult>(\"mcp_tickets:updateMcpTicket\", {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n content,\n ...(agent !== undefined && { agentId: agent }),\n });\n\n const agentInfo = result.agentId\n ? `\\nAssigned to: ${result.agentId}`\n : agent === \"\"\n ? \"\\nAgent: Unassigned\"\n : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Ticket [${result.slug}] updated in project \"${projectSlug}\".${agentInfo}\nUpdated at: ${new Date(result.updatedAt).toISOString()}\n_Ticket content has been appended with your update._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_update error:`, error);\n return {\n content: [{ type: \"text\", text: `Error updating ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type {\n ServerConfig,\n LoadMemoriesResult,\n LoadMemoriesExtremeResult,\n AddMemoryResult,\n ListAllMemoriesResult,\n} from \"../types.js\";\nimport {\n parseMemoriesLoadArgs,\n parseMemoriesAddArgs,\n parseMemoriesListAllArgs,\n} from \"../types.js\";\nimport { buildAuthArgs } from \"../auth/index.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * MCP tool response format\n * Note: Index signature required for MCP SDK v1.20+ compatibility\n */\nexport interface McpToolResponse {\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n [x: string]: unknown;\n}\n\n/**\n * Handle memories_load tool - load project memories (rules + history)\n */\nexport async function handleMemoriesLoad(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { query } = parseMemoriesLoadArgs(args);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<LoadMemoriesResult>(\"mcp_memories:loadMemories\", {\n ...buildAuthArgs(config),\n projectSlug,\n query,\n });\n\n const sections: string[] = [];\n\n // Rules section (always show)\n if (result.userMemories.length > 0) {\n const rulesText = result.userMemories.map((m, i) => `${i + 1}. ${m.content}`).join(\"\\n\");\n sections.push(`## Rules (${result.userMemories.length})\\n${rulesText}`);\n } else {\n sections.push(`## Rules\\n_No rules defined. Create rules in the Memories page._`);\n }\n\n // History section\n if (result.agentMemories.length > 0) {\n const historyText = result.agentMemories\n .map((m) => {\n const ticketRef = m.ticketNumber ? `[#${m.ticketNumber}]` : \"\";\n const date = new Date(m.createdAt).toISOString().split(\"T\")[0];\n return `• ${ticketRef} ${m.content} _(${date})_`;\n })\n .join(\"\\n\");\n const searchNote = query ? ` matching \"${query}\"` : \" (recent)\";\n sections.push(`## History${searchNote} (${result.agentMemories.length})\\n${historyText}`);\n } else {\n const searchNote = query ? ` matching \"${query}\"` : \"\";\n sections.push(`## History${searchNote}\\n_No memories recorded yet._`);\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Project Memories: ${projectSlug}\\n\\n${sections.join(\"\\n\\n\")}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_load error:`, error);\n return {\n content: [{ type: \"text\", text: `Error loading memories: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle memories_load_extreme tool - load memories with full ticket content\n */\nexport async function handleMemoriesLoadExtreme(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { query } = parseMemoriesLoadArgs(args);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<LoadMemoriesExtremeResult>(\n \"mcp_memories:loadMemoriesExtreme\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n query,\n }\n );\n\n const lines: string[] = [];\n lines.push(`# Project Memories: ${projectSlug}\\n`);\n\n // Rules section\n lines.push(`## Rules (${result.userMemories.length})`);\n if (result.userMemories.length > 0) {\n result.userMemories.forEach((m, i) => {\n lines.push(`${i + 1}. ${m.content}`);\n });\n } else {\n lines.push(`_No rules defined. Create rules in the Memories page._`);\n }\n lines.push(\"\");\n\n // History section with full ticket content\n const historyHeader = query\n ? `## History matching \"${query}\" (${result.agentMemories.length})`\n : `## Recent History (${result.agentMemories.length})`;\n lines.push(historyHeader);\n lines.push(\"\");\n\n for (const memory of result.agentMemories) {\n lines.push(\"---\");\n lines.push(`**Memory:** ${memory.content}`);\n\n if (memory.ticket) {\n lines.push(`**Ticket:** #${memory.ticket.ticketNumber}-${memory.ticket.slug}`);\n }\n\n const date = new Date(memory.createdAt).toISOString().split(\"T\")[0];\n lines.push(`**Date:** ${date}`);\n lines.push(\"\");\n\n if (memory.ticket) {\n lines.push(\"<ticket-content>\");\n lines.push(memory.ticket.content);\n lines.push(\"</ticket-content>\");\n } else {\n lines.push(\"_(No linked ticket)_\");\n }\n lines.push(\"\");\n }\n\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_load_extreme error:`, error);\n return {\n content: [{ type: \"text\", text: `Error loading extreme memories: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle memories_add tool - add a new memory\n */\nexport async function handleMemoriesAdd(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseMemoriesAddArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the memory content to record.`,\n },\n ],\n isError: true,\n };\n }\n\n const { content } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<AddMemoryResult>(\"mcp_memories:addMemory\", {\n ...buildAuthArgs(config),\n projectSlug,\n content,\n });\n\n let responseText: string;\n if (result.linkedTicket) {\n const ticketRef = `#${result.linkedTicket.number}`;\n const fallbackNote = result.linkedViaFallback ? \" (recently closed)\" : \"\";\n responseText = `✅ Memory recorded for ticket [${ticketRef}]${fallbackNote} in project \"${projectSlug}\".\\n\\n_Memory will be available in future context via [MEMORY_LOAD]._`;\n } else {\n responseText = `✅ Memory recorded in project \"${projectSlug}\".\\n\\n_Memory created without ticket linkage (no working ticket or recent closed ticket)._\\n_Memory will be available in future context via [MEMORY_LOAD]._`;\n }\n\n return {\n content: [{ type: \"text\", text: responseText }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_add error:`, error);\n return {\n content: [{ type: \"text\", text: `Error adding memory: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle memories_list_all tool - list all memories for review/cleanup\n */\nexport async function handleMemoriesListAll(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseMemoriesListAllArgs(args);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<ListAllMemoriesResult>(\"mcp_memories:listAllMemories\", {\n ...buildAuthArgs(config),\n projectSlug,\n typeFilter: parsedArgs.typeFilter,\n });\n\n const formatDate = (ts: number) => new Date(ts).toISOString().split(\"T\")[0];\n\n const userMemories = result.memories.filter((m) => m.type === \"user\");\n const agentMemories = result.memories.filter((m) => m.type === \"agent\");\n\n let output = `# Project Memories (${result.totalCount} total)\\n\\n`;\n\n if (userMemories.length > 0) {\n output += `## Rules (${userMemories.length})\\n`;\n userMemories.forEach((m, i) => {\n output += `${i + 1}. [${m.id}] ${m.content}\\n`;\n });\n output += \"\\n\";\n }\n\n if (agentMemories.length > 0) {\n output += `## Agent History (${agentMemories.length})\\n`;\n agentMemories.forEach((m) => {\n const ticketRef = m.ticketNumber ? ` [#${m.ticketNumber}]` : \"\";\n output += `• [${m.id}]${ticketRef} ${m.content.substring(0, 100)}${m.content.length > 100 ? \"...\" : \"\"} _(${formatDate(m.createdAt)})_\\n`;\n });\n }\n\n return {\n content: [{ type: \"text\", text: output }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_list_all error:`, error);\n return {\n content: [{ type: \"text\", text: `Error listing memories: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/convex-client.ts","../src/server.ts","../src/auth/agent-resolver.ts","../src/auth/token-validator.ts","../src/tools/registry.ts","../src/types.ts","../src/prompt-builder.ts","../src/handlers/prompts.ts","../src/handlers/tickets.ts","../src/handlers/memories.ts"],"sourcesContent":["import minimist from \"minimist\";\nimport { createConvexClient } from \"./convex-client.js\";\nimport { startServer } from \"./server.js\";\nimport type { ServerConfig } from \"./types.js\";\n\n/**\n * Main entry point for the MCP server\n */\nasync function main() {\n try {\n // Parse CLI arguments\n const argv = minimist(process.argv.slice(2));\n const isDev = argv.dev === true;\n\n // Check for project token authentication\n const projectToken = process.env.PPM_PROJECT_TOKEN;\n\n if (!projectToken) {\n console.error(\n \"[MCP] ERROR: Missing authentication. Set PPM_PROJECT_TOKEN environment variable.\"\n );\n console.error(\n \"[MCP] Example:\"\n );\n console.error(\"[MCP] export PPM_PROJECT_TOKEN=wst_... # Get from project settings\");\n process.exit(1);\n }\n\n console.error(\"[MCP] Auth mode: Project Token\");\n\n // Create Convex client\n const convexClient = createConvexClient(isDev);\n const convexUrl = isDev\n ? \"https://hallowed-shrimp-344.convex.cloud\"\n : \"https://trustworthy-squirrel-735.convex.cloud\";\n\n // Build server config\n const config: ServerConfig = {\n projectToken,\n isDev,\n convexUrl,\n };\n\n // Start server - this will keep the process alive via stdio transport\n await startServer(config, convexClient);\n\n // This line should never be reached if the promise in startServer never resolves\n console.error(\"[MCP] WARNING: startServer promise resolved unexpectedly!\");\n } catch (error) {\n console.error(\n \"[MCP] FATAL ERROR:\",\n error instanceof Error ? error.message : \"Unknown error\"\n );\n if (error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n}\n\n// Handle graceful shutdown\nprocess.on(\"SIGINT\", () => {\n console.error(\"[MCP] Received SIGINT, shutting down gracefully...\");\n process.exit(0);\n});\n\nprocess.on(\"SIGTERM\", () => {\n console.error(\"[MCP] Received SIGTERM, shutting down gracefully...\");\n process.exit(0);\n});\n\nmain();\n","import { ConvexHttpClient } from \"convex/browser\";\n\nconst PROD_URL = \"https://trustworthy-squirrel-735.convex.cloud\";\nconst DEV_URL = \"https://hallowed-shrimp-344.convex.cloud\";\n\n/**\n * Create a Convex HTTP client for the appropriate deployment\n */\nexport function createConvexClient(isDev: boolean): ConvexHttpClient {\n const url = isDev ? DEV_URL : PROD_URL;\n return new ConvexHttpClient(url);\n}\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ConvexHttpClient } from \"convex/browser\";\nimport type { ServerConfig } from \"./types.js\";\n\n// Auth module\nimport { validateProjectToken } from \"./auth/index.js\";\n\n// Tools module\nimport {\n getTicketToolDefinitions,\n getMemoryToolDefinitions,\n getPromptToolDefinitions,\n} from \"./tools/index.js\";\n\n// Handlers module\nimport {\n handlePromptsRun,\n handlePromptsList,\n handlePromptsUpdate,\n handleTicketsWork,\n handleTicketsPlan,\n handleTicketsCreate,\n handleTicketsClose,\n handleTicketsPause,\n handleTicketsSearch,\n handleTicketsGet,\n handleTicketsList,\n handleTicketsUpdate,\n handleTicketsReplace,\n handleMemoriesLoad,\n handleMemoriesLoadExtreme,\n handleMemoriesAdd,\n handleMemoriesListAll,\n} from \"./handlers/index.js\";\n\n// Prompt builder for per-prompt tools and slash commands\nimport {\n fetchAndExecuteAccountScopedPrompt,\n fetchAccountScopedPromptMetadataByToken,\n} from \"./prompt-builder.js\";\n\n/**\n * Initialize and start the MCP server\n */\nexport async function startServer(\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<void> {\n // Validate project token authentication\n console.error(\"[MCP] Validating project token...\");\n const validation = await validateProjectToken(convexClient, config.projectToken);\n if (!validation.valid) {\n throw new Error(`Invalid project token: ${validation.error}`);\n }\n const projectSlug = validation.projectSlug!;\n console.error(`[MCP] Project token validated for project \"${projectSlug}\"`);\n\n // Fetch account-scoped prompts (global MCP tools)\n console.error(\"[MCP] Fetching prompt metadata...\");\n const accountScopedPrompts = await fetchAccountScopedPromptMetadataByToken(\n convexClient,\n config.projectToken\n );\n console.error(`[MCP] Project token mode: loaded ${accountScopedPrompts.length} prompts`);\n\n // Filter prompts with slashCommand: true for slash command registration\n const slashCommandPrompts = accountScopedPrompts.filter((p) => p.slashCommand === true);\n console.error(`[MCP] ${slashCommandPrompts.length} prompts registered as slash commands`);\n\n if (accountScopedPrompts.length === 0) {\n console.error(\n \"[MCP] WARNING: No prompts found. Create prompts in the 'prompts' section to expose them via MCP.\"\n );\n }\n\n // Get tool definitions from registry\n const ticketTools = getTicketToolDefinitions(projectSlug);\n const memoryTools = getMemoryToolDefinitions();\n const promptTools = getPromptToolDefinitions();\n\n console.error(`[MCP] Registering ${ticketTools.length} ticket tools...`);\n console.error(`[MCP] Registering ${memoryTools.length} memory tools...`);\n console.error(`[MCP] Registering ${promptTools.length} global prompt tools...`);\n\n // Build dynamic per-prompt tools\n const dynamicPromptTools = accountScopedPrompts.map((prompt) => {\n const folderPrefix = prompt.folderPath ? `[${prompt.folderPath}] ` : \"\";\n const baseDescription = prompt.description || `Execute the \"${prompt.slug}\" prompt`;\n return {\n name: prompt.slug,\n description: folderPrefix + baseDescription,\n promptSlug: prompt.slug,\n };\n });\n\n console.error(`[MCP] Registering ${dynamicPromptTools.length} per-prompt tools (global)...`);\n\n // Check for duplicate prompt names\n const promptNames = new Set<string>();\n const duplicates: string[] = [];\n accountScopedPrompts.forEach((p) => {\n if (promptNames.has(p.slug)) {\n duplicates.push(p.slug);\n }\n promptNames.add(p.slug);\n });\n\n if (duplicates.length > 0) {\n console.error(\n `[MCP] WARNING: Duplicate prompt slugs detected: ${duplicates.join(\", \")}. Only the first occurrence will be registered.`\n );\n }\n\n // Create MCP server\n const server = new Server(\n { name: \"ppm-mcp-server\", version: \"3.1.0\" },\n { capabilities: { prompts: {}, tools: {} } }\n );\n\n // ============================================================================\n // LIST PROMPTS HANDLER\n // ============================================================================\n server.setRequestHandler(ListPromptsRequestSchema, async () => {\n return {\n prompts: [\n // Global prompt tools (prompts_run, prompts_list, prompts_update)\n ...promptTools.map((t) => ({ name: t.name, description: t.description })),\n // Ticket tools\n ...ticketTools.map((t) => ({ name: t.name, description: t.description })),\n // Memory tools\n ...memoryTools.map((t) => ({ name: t.name, description: t.description })),\n // User prompts with slashCommand: true\n ...slashCommandPrompts.map((p) => ({\n name: p.slug,\n description: p.description || `Execute the \"${p.slug}\" prompt`,\n })),\n ],\n };\n });\n\n // ============================================================================\n // GET PROMPT HANDLER (slash command content)\n // ============================================================================\n server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const promptName = request.params.name;\n\n // Handle tickets_work with optional argument (e.g., \"tickets_work 102\")\n const ticketWorkMatch = promptName.match(/^tickets_work\\s+(.+)$/);\n if (ticketWorkMatch) {\n const ticketArg = ticketWorkMatch[1].trim();\n return {\n description: `Work on ticket \"${ticketArg}\" from \"${projectSlug}\"`,\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Get work on ticket \"${ticketArg}\" from the \"${projectSlug}\" project.\\n\\nCall the \\`tickets_work\\` tool with ticketSlug: \"${ticketArg}\".\\n\\nThis will open the ticket if it's in the open queue, or resume it if already working.`,\n },\n },\n ],\n };\n }\n\n // Handle tickets_plan with optional argument (e.g., \"tickets_plan 102\")\n const ticketPlanMatch = promptName.match(/^tickets_plan\\s+(.+)$/);\n if (ticketPlanMatch) {\n const ticketArg = ticketPlanMatch[1].trim();\n return {\n description: `Plan ticket \"${ticketArg}\" from \"${projectSlug}\"`,\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Get planning work on ticket \"${ticketArg}\" from the \"${projectSlug}\" project.\\n\\nCall the \\`tickets_plan\\` tool with ticketSlug: \"${ticketArg}\".\\n\\nThis ticket is in PLAN status. You may ONLY:\\n• Create/update plan files\\n• Update this ticket with planning notes\\n• Create sub-tickets for implementation\\n\\nDO NOT: Write code or make implementation changes.`,\n },\n },\n ],\n };\n }\n\n // Handle ticket tools\n const ticketTool = ticketTools.find((t) => t.name === promptName);\n if (ticketTool) {\n return buildTicketPromptResponse(ticketTool.type, ticketTool.name, projectSlug);\n }\n\n // Handle prompts_list\n if (promptName === \"prompts_list\") {\n return {\n description: \"List all available prompts\",\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `List all available prompts.\\n\\nCall the \\`prompts_list\\` tool with optional \\`search\\` parameter to filter results.`,\n },\n },\n ],\n };\n }\n\n // Handle prompts_run with optional argument\n const runPromptMatch = promptName.match(/^prompts_run\\s+(.+)$/);\n if (promptName === \"prompts_run\" || runPromptMatch) {\n if (runPromptMatch) {\n const promptSlug = runPromptMatch[1].trim();\n return {\n description: `Execute prompt \"${promptSlug}\"`,\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Execute the \"${promptSlug}\" prompt.\\n\\nCall the \\`prompts_run\\` tool with slug: \"${promptSlug}\".`,\n },\n },\n ],\n };\n }\n return {\n description: \"Execute a prompt by slug\",\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `Execute a prompt by slug.\\n\\n## Usage\\nCall the \\`prompts_run\\` tool with the prompt slug.\\n\\n## Available Prompts\\nUse \\`prompts_list\\` to list all available prompts.\\n\\n## Example\\n/ppm:prompts_run code-review\\n\\nThis will execute the \"code-review\" prompt.`,\n },\n },\n ],\n };\n }\n\n // Handle user slash command prompts\n const userSlashCommand = slashCommandPrompts.find((p) => p.slug === promptName);\n if (userSlashCommand) {\n try {\n const result = await fetchAndExecuteAccountScopedPrompt(\n userSlashCommand.slug,\n config,\n convexClient\n );\n return {\n description: userSlashCommand.description || `Execute \"${userSlashCommand.slug}\"`,\n messages: result.messages.map((msg) => ({\n role: msg.role as \"user\",\n content: { type: \"text\" as const, text: msg.content.text },\n })),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n throw new Error(`Error executing slash command \"${promptName}\": ${errorMessage}`);\n }\n }\n\n // Unknown prompt\n throw new Error(`Unknown prompt: ${promptName}. Use prompts_run to execute prompts.`);\n });\n\n // ============================================================================\n // LIST TOOLS HANDLER\n // ============================================================================\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n // Ticket tools\n ...ticketTools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n // Prompt tools (global)\n ...promptTools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n // Memory tools\n ...memoryTools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n // Per-prompt tools\n ...dynamicPromptTools.map((pt) => ({\n name: pt.name,\n description: pt.description,\n inputSchema: { type: \"object\" as const, properties: {}, required: [] },\n })),\n ],\n };\n });\n\n // ============================================================================\n // CALL TOOL HANDLER - Main dispatcher\n // ============================================================================\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const toolName = request.params.name;\n const args = request.params.arguments;\n\n // --- Global Prompt Tools ---\n if (toolName === \"prompts_run\") {\n return handlePromptsRun(args, config, convexClient);\n }\n if (toolName === \"prompts_list\") {\n return handlePromptsList(args, config, convexClient, accountScopedPrompts);\n }\n if (toolName === \"prompts_update\") {\n return handlePromptsUpdate(args, config, convexClient);\n }\n\n // --- Ticket Tools ---\n if (toolName === \"tickets_work\") {\n return handleTicketsWork(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_plan\") {\n return handleTicketsPlan(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_create\") {\n return handleTicketsCreate(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_close\") {\n return handleTicketsClose(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_pause\") {\n return handleTicketsPause(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_search\") {\n return handleTicketsSearch(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_get\") {\n return handleTicketsGet(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_list\") {\n return handleTicketsList(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_update\") {\n return handleTicketsUpdate(args, config, convexClient, projectSlug);\n }\n if (toolName === \"tickets_replace\") {\n return handleTicketsReplace(args, config, convexClient, projectSlug);\n }\n\n // --- Memory Tools ---\n if (toolName === \"memories_load\") {\n return handleMemoriesLoad(args, config, convexClient, projectSlug);\n }\n if (toolName === \"memories_load_extreme\") {\n return handleMemoriesLoadExtreme(args, config, convexClient, projectSlug);\n }\n if (toolName === \"memories_add\") {\n return handleMemoriesAdd(args, config, convexClient, projectSlug);\n }\n if (toolName === \"memories_list_all\") {\n return handleMemoriesListAll(args, config, convexClient, projectSlug);\n }\n\n // --- Per-Prompt Tools (dynamic) ---\n const promptTool = dynamicPromptTools.find((pt) => pt.name === toolName);\n if (promptTool) {\n try {\n const result = await fetchAndExecuteAccountScopedPrompt(\n promptTool.promptSlug,\n config,\n convexClient\n );\n const promptText = result.messages.map((msg) => msg.content.text).join(\"\\n\\n\");\n return { content: [{ type: \"text\", text: promptText }] };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] ${toolName} error:`, error);\n return {\n content: [{ type: \"text\", text: `Error executing prompt: ${errorMessage}` }],\n isError: true,\n };\n }\n }\n\n // --- Unknown Tool ---\n return {\n content: [\n {\n type: \"text\",\n text: `Unknown tool: ${toolName}. Use prompts_run to execute prompts by name, or check available tools.`,\n },\n ],\n isError: true,\n };\n });\n\n // ============================================================================\n // START SERVER\n // ============================================================================\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error(\"[MCP] Server started successfully\");\n console.error(`[MCP] Deployment: ${config.isDev ? \"DEVELOPMENT\" : \"PRODUCTION\"}`);\n console.error(`[MCP] Convex URL: ${config.convexUrl}`);\n console.error(`[MCP] Data mode: REAL-TIME (fetches fresh data on each invocation)`);\n\n const allPromptNames = [...Array.from(promptNames)].sort();\n console.error(`[MCP] Prompts available: ${allPromptNames.join(\", \")}`);\n console.error(`[MCP] - Total prompts: ${promptNames.size}`);\n\n // Keep the event loop alive with a heartbeat\n setInterval(() => {\n // Heartbeat every 60 seconds to keep process alive\n }, 60000);\n\n // Return a promise that never resolves to keep the server running\n return new Promise<void>(() => {\n // The transport handles stdin/stdout communication\n });\n}\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Build prompt response for ticket tools (used by GetPromptRequestSchema)\n */\nfunction buildTicketPromptResponse(\n type: string,\n toolName: string,\n projectSlug: string\n): { description: string; messages: Array<{ role: \"user\"; content: { type: \"text\"; text: string } }> } {\n let promptContent: string;\n let description: string;\n\n if (type === \"work\") {\n description = `Get work from the \"${projectSlug}\" project`;\n promptContent = `Get work from the \"${projectSlug}\" project.\\n\\nCall the \\`tickets_work\\` tool to get the next ticket from the open queue.\\n\\nYou can also specify a ticket: /ppm:tickets_work <number-or-slug>\\n\\nThis unified command handles both opening new tickets and resuming in-progress work.`;\n } else if (type === \"plan\") {\n description = `Get planning work from the \"${projectSlug}\" project`;\n promptContent = `Get planning work from the \"${projectSlug}\" project.\n\nCall the \\`tickets_plan\\` tool to get the next ticket from the plan queue.\n\nYou can also specify a ticket: /ppm:tickets_plan <number-or-slug>\n\nThis unified command handles both opening new plan tickets and resuming in-progress planning work.\n\n**IMPORTANT**: This ticket is in PLAN status. You may ONLY:\n• Create/update plan files\n• Update this ticket with planning notes\n• Create sub-tickets for implementation\n\nDO NOT: Write code or make implementation changes.`;\n } else if (type === \"create\") {\n description = `Create a new ticket in \"${projectSlug}\"`;\n promptContent = `Create a new ticket in the \"${projectSlug}\" project queue.\n\n## How This Works\nThe user provides **instructions** (not raw content). You interpret those instructions to generate the ticket.\n\n## Instructions\n1. **Read the user's request** - they may reference a file, ask you to summarize a session, or describe what they want\n2. **Process the input** - read files, extract relevant sections, summarize as needed\n3. **Generate ticket content** with a clear, descriptive title as the first line\n4. **Call the tool** with the generated content\n\n## Content Format\n\\`\\`\\`\n[Clear descriptive title - this becomes the slug]\n\n[Body content - tasks, description, context, etc.]\n\\`\\`\\`\n\n## Examples\n- \"create a ticket from /path/to/plan.md\" → Read file, use as ticket content\n- \"summarize our brainstorm into a ticket\" → Extract key points from conversation\n- \"create a ticket for the auth bug we discussed\" → Generate from session context\n- \"just the tasks from this file\" → Extract only task items\n\nCall the \\`${toolName}\\` tool with the final generated content.`;\n } else if (type === \"close\") {\n description = `Close a working ticket in \"${projectSlug}\"`;\n promptContent = `Close a working ticket in the \"${projectSlug}\" project.\\n\\nCall the \\`${toolName}\\` tool with the ticket number or slug.`;\n } else {\n // Fallback for other types\n description = `Use the ${toolName} tool`;\n promptContent = `Use the \\`${toolName}\\` tool.`;\n }\n\n return {\n description,\n messages: [\n {\n role: \"user\" as const,\n content: { type: \"text\" as const, text: promptContent },\n },\n ],\n };\n}\n","import type { ServerConfig } from \"../types.js\";\n\n/**\n * Build authentication arguments for Convex mutations/queries.\n * All auth is now via project token.\n */\nexport function buildAuthArgs(config: ServerConfig): { projectToken: string } {\n return { projectToken: config.projectToken };\n}\n\n/**\n * Resolve agent for ticket operations (implement-agent-routing)\n * Priority: explicit param > PPM_AGENT_NAME env var > undefined (owner mode)\n *\n * @param paramAgent - Agent slug passed as tool parameter\n * @returns Resolved agent slug or undefined for owner mode\n */\nexport function resolveAgent(paramAgent?: string): string | undefined {\n // Explicit parameter takes priority\n if (paramAgent) return paramAgent;\n\n // Fall back to environment variable\n const envAgent = process.env.PPM_AGENT_NAME;\n if (envAgent) return envAgent;\n\n // Owner mode - no filtering\n return undefined;\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type { ProjectTokenValidation } from \"../types.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n * This allows us to use string function names while maintaining type safety\n * for the response types through explicit casting.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * Response type from validateProjectToken query\n */\ninterface ValidateProjectTokenResponse {\n valid: boolean;\n projectId?: string;\n projectSlug?: string;\n ownerId?: string;\n}\n\n/**\n * Validate project token with Convex\n *\n * Project tokens are now stored directly on the projects table.\n * Returns project details if valid, null if invalid.\n */\nexport async function validateProjectToken(\n client: ConvexHttpClient,\n token: string\n): Promise<ProjectTokenValidation> {\n try {\n // Cast to our typed client for string-based function references\n const typedClient = client as ConvexClientWithStringRefs;\n const result = await typedClient.query<ValidateProjectTokenResponse | null>(\n \"projects:validateProjectToken\",\n { token }\n );\n\n if (result && result.valid) {\n return {\n valid: true,\n projectId: result.projectId,\n projectSlug: result.projectSlug,\n ownerId: result.ownerId,\n };\n }\n return { valid: false, error: \"Invalid project token\" };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n","/**\n * Unified Tool Registry - Single source of truth for all MCP tools\n *\n * Each tool is defined once with: name, description, inputSchema\n * Handler mapping happens at runtime in server.ts since handlers need\n * dynamic context (projectSlug, accountScopedPrompts)\n *\n * This ensures ListTools and CallTool are always in sync.\n */\n\n/**\n * Tool definition entry (without handler - handlers are mapped at runtime)\n */\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/**\n * Ticket tool types for type-safe tool identification\n */\nexport type TicketToolType =\n | \"work\"\n | \"plan\"\n | \"close\"\n | \"pause\"\n | \"create\"\n | \"search\"\n | \"get\"\n | \"list\"\n | \"update\"\n | \"replace\";\n\n/**\n * Memory tool types for type-safe tool identification\n */\nexport type MemoryToolType = \"load\" | \"load_extreme\" | \"add\" | \"list_all\";\n\n/**\n * Get ticket tool definitions with project-specific descriptions\n */\nexport function getTicketToolDefinitions(projectSlug: string): Array<ToolDefinition & { type: TicketToolType }> {\n return [\n {\n name: \"tickets_work\",\n type: \"work\",\n description: `Get work from the \"${projectSlug}\" project. With no args: gets next ticket from open queue. With ticket slug/number: opens or resumes that specific ticket.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description:\n \"Optional: Ticket number (e.g., '102') or full slug. If not provided, gets next ticket from open queue.\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter queue. Overrides PPM_AGENT_NAME env var. Omit for owner mode (no filtering).\",\n },\n },\n required: [],\n },\n },\n {\n name: \"tickets_plan\",\n type: \"plan\",\n description: `Get planning work from the \"${projectSlug}\" project. With no args: gets next ticket from plan queue. With ticket slug/number: opens that specific plan ticket. Status stays as 'plan' - no code changes allowed, only planning files and ticket updates.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description:\n \"Optional: Ticket number (e.g., '102') or full slug. If not provided, gets next ticket from plan queue.\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter queue. Overrides PPM_AGENT_NAME env var. Omit for owner mode (no filtering).\",\n },\n },\n required: [],\n },\n },\n {\n name: \"tickets_close\",\n type: \"close\",\n description: `Mark a working ticket as completed in the \"${projectSlug}\" project. If a hook is configured, first call returns instructions - then call again with metadata.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n metadata: {\n type: \"object\",\n description:\n \"Optional: Key-value metadata to store with the closed ticket (e.g., evaluation scores, completion notes).\",\n additionalProperties: {\n oneOf: [{ type: \"string\" }, { type: \"number\" }, { type: \"boolean\" }],\n },\n },\n },\n required: [\"ticketSlug\"],\n },\n },\n {\n name: \"tickets_pause\",\n type: \"pause\",\n description: `Pause a working ticket and return to queue. Before calling, review the full session context and generate comprehensive checkpoint content that enables seamless handoff to another agent. Include: completed tasks with specifics, key decisions and rationale, sticking points and resolutions, user preferences discovered, remaining work with file:line references, and open questions.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n content: {\n type: \"string\",\n description:\n 'Comprehensive checkpoint for handoff. Review the session and include: ## Progress (completed tasks with specifics, decisions made and why) ## Context (user preferences, edge cases discovered, key feedback received) ## Remaining (specific next steps, file:line references if applicable) ## Blockers (unresolved issues, open questions). This enables the next agent to continue seamlessly.',\n },\n },\n required: [\"ticketSlug\", \"content\"],\n },\n },\n {\n name: \"tickets_create\",\n type: \"create\",\n description: `Create a new ticket in the \"${projectSlug}\" project queue`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n content: {\n type: \"string\",\n description:\n \"The generated ticket content. First line should be a clear descriptive title (becomes the slug). Body contains tasks, description, context as needed.\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to assign ticket to. Overrides PPM_AGENT_NAME env var. Omit for unassigned.\",\n },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"tickets_search\",\n type: \"search\",\n description: `Search for tickets by content in the \"${projectSlug}\" project`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description: \"Search query (min 3 characters)\",\n },\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter results. Overrides PPM_AGENT_NAME env var. Omit for all tickets.\",\n },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"tickets_get\",\n type: \"get\",\n description: `Get a specific ticket by number or slug from \"${projectSlug}\" (read-only)`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug\",\n },\n },\n required: [\"ticketSlug\"],\n },\n },\n {\n name: \"tickets_list\",\n type: \"list\",\n description: `List active tickets in the \"${projectSlug}\" project (plan + open + working)`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n agent: {\n type: \"string\",\n description:\n \"Optional: Agent slug to filter tickets. Overrides PPM_AGENT_NAME env var. Omit for all tickets.\",\n },\n },\n required: [],\n },\n },\n {\n name: \"tickets_update\",\n type: \"update\",\n description: `Update a ticket in the \"${projectSlug}\" project by appending content with timestamp`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n content: {\n type: \"string\",\n description: \"Update content to append to the ticket (markdown supported)\",\n },\n agent: {\n type: \"string\",\n description: \"Optional: Reassign ticket to this agent. Use empty string '' to unassign.\",\n },\n },\n required: [\"ticketSlug\", \"content\"],\n },\n },\n {\n name: \"tickets_replace\",\n type: \"replace\",\n description: `Replace ticket content in the \"${projectSlug}\" project. Archives old content. Only works on 'plan' status tickets.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n ticketSlug: {\n type: \"string\",\n description: \"Ticket number (e.g., '102') or full slug (e.g., '102-fix-auth')\",\n },\n content: {\n type: \"string\",\n description: \"New content to replace with (old content is archived in HTML comment)\",\n },\n },\n required: [\"ticketSlug\", \"content\"],\n },\n },\n ];\n}\n\n/**\n * Get memory tool definitions with project-specific context\n */\nexport function getMemoryToolDefinitions(): Array<ToolDefinition & { type: MemoryToolType }> {\n return [\n {\n name: \"memories_load\",\n type: \"load\",\n description: `Load project memories: returns all rules (always) + relevant history (by query or recent). Use [MEMORY_LOAD] in prompts for automatic loading.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description:\n \"Optional: search query to filter agent memories. If not provided, returns recent memories.\",\n },\n },\n required: [],\n },\n },\n {\n name: \"memories_load_extreme\",\n type: \"load_extreme\",\n description: `Load project memories with FULL ticket context. Returns all matching memories, and for each memory linked to a ticket, includes the complete ticket content (tasks, updates, decisions). Use when you need deep historical context about past work.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description:\n \"Optional: search query to filter agent memories. If not provided, returns recent memories.\",\n },\n },\n required: [],\n },\n },\n {\n name: \"memories_add\",\n type: \"add\",\n description: `Record a project memory. Optionally links to working ticket if exactly one exists. Use for key decisions, patterns discovered, or important context.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n content: {\n type: \"string\",\n description:\n \"Memory content to record. Be concise and focused on key decisions, patterns, or context.\",\n },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memories_list_all\",\n type: \"list_all\",\n description: `List ALL project memories (rules and agent history). Returns complete memory list with IDs for review/cleanup. Use for memory audits or before bulk operations.`,\n inputSchema: {\n type: \"object\" as const,\n properties: {\n typeFilter: {\n type: \"string\",\n enum: [\"all\", \"user\", \"agent\"],\n description: \"Optional: Filter by memory type. 'user' = rules, 'agent' = history. Default: 'all'\",\n },\n },\n required: [],\n },\n },\n ];\n}\n\n/**\n * Get global prompt tool definitions (not project-scoped)\n */\nexport function getPromptToolDefinitions(): ToolDefinition[] {\n return [\n {\n name: \"prompts_run\",\n description: \"Execute a prompt by slug. Use prompts_list to list available prompts.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n slug: {\n type: \"string\",\n description: \"Prompt slug to execute (e.g., 'code-review', 'plan')\",\n },\n },\n required: [\"slug\"],\n },\n },\n {\n name: \"prompts_list\",\n description: \"List all available prompts\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n search: {\n type: \"string\",\n description: \"Optional search term to filter prompts by name or description (case-insensitive)\",\n },\n },\n },\n },\n {\n name: \"prompts_update\",\n description:\n \"Read or update a prompt. Without content: returns resource with context. With content: saves new version.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n slug: {\n type: \"string\",\n description:\n \"Prompt slug to read or update. Supports fuzzy matching.\",\n },\n content: {\n type: \"string\",\n description: \"New prompt content (omit for read-only mode)\",\n },\n },\n required: [\"slug\"],\n },\n },\n ];\n}\n\n/**\n * Get all tool names (for validation)\n */\nexport function getAllToolNames(projectSlug: string): string[] {\n const ticketNames = getTicketToolDefinitions(projectSlug).map((t) => t.name);\n const memoryNames = getMemoryToolDefinitions().map((t) => t.name);\n const promptNames = getPromptToolDefinitions().map((t) => t.name);\n return [...ticketNames, ...memoryNames, ...promptNames];\n}\n\n/**\n * Check if a tool name is a known tool (excludes per-prompt tools)\n */\nexport function isKnownTool(toolName: string, projectSlug: string): boolean {\n return getAllToolNames(projectSlug).includes(toolName);\n}\n","// ============================================================================\n// MCP Tool Argument Types\n// ============================================================================\n\n/**\n * Arguments for the tickets_work tool\n * Optional ticketSlug: if provided, work on specific ticket; otherwise get next from queue\n * Optional agent: filter queue to specific agent (implement-agent-routing)\n */\nexport interface WorkToolArgs {\n ticketSlug?: string;\n agent?: string; // Agent filtering (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_close tool\n * Required ticketSlug to identify which ticket to close\n * Optional metadata for two-phase close flow (when on_close hook is configured)\n */\nexport interface CloseToolArgs {\n ticketSlug: string;\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Arguments for the tickets_create tool\n * Required content where first line becomes the slug\n * Optional agent: assign to specific agent (implement-agent-routing)\n */\nexport interface CreateToolArgs {\n content: string;\n agent?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_search tool\n * Required query string (min 3 characters)\n * Optional agent: filter search results to specific agent (implement-agent-routing)\n */\nexport interface SearchToolArgs {\n query: string;\n agent?: string; // Agent filtering (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_get tool\n * Required ticketSlug to identify which ticket to retrieve\n */\nexport interface GetToolArgs {\n ticketSlug: string;\n}\n\n/**\n * Arguments for the tickets_list tool\n * Optional agent: filter to specific agent's tickets (implement-agent-routing)\n */\nexport interface ListToolArgs {\n agent?: string; // Agent filtering (implement-agent-routing)\n}\n\n/**\n * Arguments for the tickets_update tool\n * Required ticketSlug and content to append\n * Optional agent: reassign ticket to agent (empty string = unassign) (implement-agent-routing)\n */\nexport interface UpdateToolArgs {\n ticketSlug: string;\n content: string;\n agent?: string; // Agent reassignment (implement-agent-routing) - empty string = unassign\n}\n\n/**\n * Arguments for the tickets_pause tool\n * Required ticketSlug and content (checkpoint progress)\n */\nexport interface PauseToolArgs {\n ticketSlug: string;\n content: string;\n}\n\n/**\n * Arguments for the tickets_plan tool\n * Optional ticketSlug: if provided, work on specific plan ticket; otherwise get next from plan queue\n * Optional agent: filter queue to specific agent (implement-agent-routing)\n */\nexport interface PlanToolArgs {\n ticketSlug?: string;\n agent?: string;\n}\n\n/**\n * Arguments for the tickets_replace tool\n * Required ticketSlug to identify which ticket to replace\n * Required content (new content to replace with)\n */\nexport interface ReplaceToolArgs {\n ticketSlug: string;\n content: string;\n}\n\n/**\n * Arguments for the prompts_run tool\n * Required slug to identify which prompt to execute\n */\nexport interface PromptsRunArgs {\n slug: string;\n}\n\n/**\n * Arguments for the prompts_list tool\n * Optional search term to filter prompts\n */\nexport interface PromptsListArgs {\n search?: string;\n}\n\n/**\n * Arguments for the prompts_update tool\n * Required slug, optional content for write mode\n */\nexport interface PromptsUpdateArgs {\n slug: string;\n content?: string;\n}\n\n/**\n * Arguments for the memories_load tool\n * Optional query for filtering agent memories\n */\nexport interface MemoriesLoadArgs {\n query?: string;\n}\n\n/**\n * Arguments for the memories_add tool\n * Required content for the memory entry\n */\nexport interface MemoriesAddArgs {\n content: string;\n}\n\n/**\n * Arguments for the memories_list_all tool\n * Optional typeFilter for filtering by memory type\n */\nexport interface MemoriesListAllArgs {\n typeFilter?: \"all\" | \"user\" | \"agent\";\n}\n\n// ============================================================================\n// Convex Response Types (for MCP mutations/queries)\n// ============================================================================\n\n/**\n * Response from workMcpTicket mutation\n */\nexport interface WorkTicketResult {\n slug: string;\n ticketNumber?: number;\n status: string;\n content: string;\n startedAt?: number;\n pausedAt?: number; // If set, ticket was previously paused - look for checkpoint content\n remainingTickets: number;\n wasOpened: boolean;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from planMcpTicket mutation\n * Status always remains \"plan\" - no transition to working\n */\nexport interface PlanTicketResult {\n slug: string;\n ticketNumber?: number;\n status: \"plan\";\n content: string;\n startedAt?: number;\n remainingPlanTickets: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Access denied response from ticket operations\n */\nexport interface AccessDeniedResult {\n error: string;\n accessDenied: true;\n}\n\n/**\n * Type guard to check if a result is an access denied response\n */\nexport function isAccessDenied(result: unknown): result is AccessDeniedResult {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'accessDenied' in result &&\n (result as AccessDeniedResult).accessDenied === true\n );\n}\n\n/**\n * Plan status blocked response - returned when tickets_work is called on a plan-status ticket\n */\nexport interface PlanStatusBlockedResult {\n error: string;\n planStatusBlocked: true;\n ticketSlug: string;\n}\n\n/**\n * Type guard to check if a result is a plan status blocked response\n */\nexport function isPlanStatusBlocked(result: unknown): result is PlanStatusBlockedResult {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'planStatusBlocked' in result &&\n (result as PlanStatusBlockedResult).planStatusBlocked === true\n );\n}\n\n/**\n * Response from createMcpTicket mutation\n */\nexport interface CreateTicketResult {\n slug: string;\n ticketNumber?: number;\n preview: string;\n position: number;\n totalPlan: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from closeMcpTicket mutation\n */\nexport interface CloseTicketResult {\n slug: string;\n status: string;\n closedAt: number;\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Response from updateMcpTicket mutation\n */\nexport interface UpdateTicketResult {\n slug: string;\n ticketNumber?: number;\n status: string;\n updatedAt: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from pauseMcpTicket mutation\n */\nexport interface PauseTicketResult {\n slug: string;\n ticketNumber?: number;\n status: \"open\";\n pausedAt: number;\n}\n\n/**\n * Response from replaceMcpTicket mutation\n */\nexport interface ReplaceTicketResult {\n slug: string;\n ticketNumber?: number;\n status: \"plan\";\n replacedAt: number;\n archivedContentLength: number;\n newContentLength: number;\n}\n\n/**\n * Response from getMcpTicket query\n */\nexport interface GetTicketResult {\n slug: string;\n ticketNumber?: number;\n content: string;\n status: string;\n createdAt: number;\n startedAt?: number;\n closedAt?: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Response from listMcpTickets query\n */\nexport interface ListTicketItem {\n position: number;\n slug: string;\n ticketNumber?: number;\n status: string;\n preview: string;\n createdAt: number;\n startedAt?: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n}\n\n/**\n * Response from searchMcpTickets query\n */\nexport interface SearchTicketItem {\n slug: string;\n ticketNumber?: number;\n status: string;\n matchSnippet: string;\n createdAt: number;\n agentId?: string; // Agent assignment (implement-agent-routing)\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Response from prompt metadata query\n */\nexport interface PromptMetadata {\n slug: string;\n description?: string;\n folderPath?: string; // Full path like \"coding/templates/planning\"\n slashCommand?: boolean; // Register as MCP slash command (/ppm:slug)\n}\n\n/**\n * Response from loadMemories query\n */\nexport interface LoadMemoriesResult {\n userMemories: Array<{\n content: string;\n createdAt: number;\n }>;\n agentMemories: Array<{\n content: string;\n ticketSlug?: string;\n ticketNumber?: number;\n createdAt: number;\n }>;\n}\n\n/**\n * Response from addMemory mutation\n */\nexport interface AddMemoryResult {\n success: boolean;\n memoryId: string;\n linkedTicket: {\n slug: string;\n number: number;\n } | null;\n /** True when memory was linked to a recently closed ticket (fallback) instead of a working ticket */\n linkedViaFallback: boolean;\n}\n\n/**\n * Response from listAllMemories query\n */\nexport interface ListAllMemoriesResult {\n memories: Array<{\n id: string;\n type: \"user\" | \"agent\";\n content: string;\n ticketSlug?: string;\n ticketNumber?: number;\n createdAt: number;\n }>;\n totalCount: number;\n}\n\n/**\n * Response from loadMemoriesExtreme query\n * Returns memories with full ticket content for linked tickets\n */\nexport interface LoadMemoriesExtremeResult {\n userMemories: Array<{\n content: string;\n createdAt: number;\n }>;\n agentMemories: Array<{\n content: string;\n ticketSlug?: string;\n ticketNumber?: number;\n createdAt: number;\n ticket?: {\n slug: string;\n ticketNumber: number;\n content: string;\n status: string;\n } | null;\n }>;\n}\n\n/**\n * Resource type returned by prompts_update tool\n */\nexport type ResourceType = \"prompt\";\n\n/**\n * Response from updateMcpPrompt mutation (read mode)\n */\nexport interface UpdatePromptReadResult {\n success: true;\n mode: \"read\";\n resourceType: ResourceType;\n matchType: \"exact\" | \"prefix\" | \"contains\";\n slug: string;\n description: string;\n content: string;\n version?: number; // Only for prompts\n context?: {\n variables: Array<{ slug: string; reference: string; type: string; description: string }>;\n prompts: Array<{ slug: string; reference: string; description: string }>;\n };\n editingGuidance: string;\n hasAiTags?: boolean;\n aiTags?: string[];\n}\n\n/**\n * Response from updateMcpPrompt mutation (write mode)\n */\nexport interface UpdatePromptWriteResult {\n success: true;\n mode: \"write\";\n resourceType: ResourceType;\n slug: string;\n version?: number; // Only for prompts\n updatedAt?: string;\n message: string;\n}\n\n/**\n * Response from updateMcpPrompt mutation (error)\n */\nexport interface UpdatePromptErrorResult {\n success: false;\n error: string;\n suggestions?: string[];\n}\n\n/**\n * Union type for all updateMcpPrompt responses\n */\nexport type UpdatePromptResult =\n | UpdatePromptReadResult\n | UpdatePromptWriteResult\n | UpdatePromptErrorResult;\n\n/**\n * Account-scoped prompt match result types\n */\nexport type AccountScopedPromptResult =\n | { matchType: \"exact\" | \"prefix\" | \"contains\"; slug: string; description?: string; flattenedPrompt?: string }\n | { matchType: \"ambiguous\"; suggestions: string[] }\n | null;\n\n// ============================================================================\n// Argument Parsing Functions\n// ============================================================================\n\n/**\n * Parse and validate arguments for tickets_work tool\n */\nexport function parseWorkArgs(args: unknown): WorkToolArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n ticketSlug: typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent filtering (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_close tool\n * Returns null if required argument is missing\n */\nexport function parseCloseArgs(args: unknown): CloseToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n if (!ticketSlug) return null;\n\n // Parse optional metadata object\n let metadata: Record<string, string | number | boolean> | undefined;\n if (parsed?.metadata && typeof parsed.metadata === 'object' && !Array.isArray(parsed.metadata)) {\n metadata = {};\n for (const [key, value] of Object.entries(parsed.metadata as Record<string, unknown>)) {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n metadata[key] = value;\n }\n }\n // Only keep metadata if it has entries\n if (Object.keys(metadata).length === 0) {\n metadata = undefined;\n }\n }\n\n return { ticketSlug, metadata };\n}\n\n/**\n * Parse and validate arguments for tickets_create tool\n * Returns null if required argument is missing\n */\nexport function parseCreateArgs(args: unknown): CreateToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!content) return null;\n\n return {\n content,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent assignment (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_search tool\n * Returns null if required argument is missing or too short\n */\nexport function parseSearchArgs(args: unknown): SearchToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const query = typeof parsed?.query === 'string' ? parsed.query : undefined;\n if (!query || query.length < 3) return null;\n return {\n query,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent filtering (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_get tool\n * Returns null if required argument is missing\n */\nexport function parseGetArgs(args: unknown): GetToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n if (!ticketSlug) return null;\n return { ticketSlug };\n}\n\n/**\n * Parse arguments for tickets_list tool\n * Optional agent parameter for filtering\n */\nexport function parseListArgs(args: unknown): ListToolArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent filtering (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_update tool\n * Returns null if any required argument is missing\n */\nexport function parseUpdateArgs(args: unknown): UpdateToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!ticketSlug || !content) return null;\n return {\n ticketSlug,\n content,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined, // Agent reassignment (implement-agent-routing)\n };\n}\n\n/**\n * Parse and validate arguments for tickets_pause tool\n * Returns null if any required argument is missing\n */\nexport function parsePauseArgs(args: unknown): PauseToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!ticketSlug || !content) return null;\n return { ticketSlug, content };\n}\n\n/**\n * Parse and validate arguments for tickets_plan tool\n */\nexport function parsePlanArgs(args: unknown): PlanToolArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n ticketSlug: typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined,\n agent: typeof parsed?.agent === 'string' ? parsed.agent : undefined,\n };\n}\n\n/**\n * Parse and validate arguments for tickets_replace tool\n * Returns null if any required argument is missing\n */\nexport function parseReplaceArgs(args: unknown): ReplaceToolArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const ticketSlug = typeof parsed?.ticketSlug === 'string' ? parsed.ticketSlug : undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!ticketSlug || !content) return null;\n return { ticketSlug, content };\n}\n\n/**\n * Parse and validate arguments for prompts_run tool\n * Returns null if required argument is missing\n */\nexport function parsePromptsRunArgs(args: unknown): PromptsRunArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const slug = typeof parsed?.slug === 'string' ? parsed.slug : undefined;\n if (!slug) return null;\n return { slug };\n}\n\n/**\n * Parse arguments for prompts_list tool\n */\nexport function parsePromptsListArgs(args: unknown): PromptsListArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n search: typeof parsed?.search === 'string' ? parsed.search : undefined,\n };\n}\n\n/**\n * Parse and validate arguments for prompts_update tool\n * Returns null if required slug is missing\n */\nexport function parsePromptsUpdateArgs(args: unknown): PromptsUpdateArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const slug = typeof parsed?.slug === 'string' ? parsed.slug : undefined;\n if (!slug) return null;\n return {\n slug,\n content: typeof parsed?.content === 'string' ? parsed.content : undefined,\n };\n}\n\n/**\n * Parse arguments for memories_load tool\n * Optional query parameter for filtering agent memories\n */\nexport function parseMemoriesLoadArgs(args: unknown): MemoriesLoadArgs {\n const parsed = args as Record<string, unknown> | undefined;\n return {\n query: typeof parsed?.query === 'string' ? parsed.query : undefined,\n };\n}\n\n/**\n * Parse and validate arguments for memories_add tool\n * Returns null if required content is missing\n */\nexport function parseMemoriesAddArgs(args: unknown): MemoriesAddArgs | null {\n const parsed = args as Record<string, unknown> | undefined;\n const content = typeof parsed?.content === 'string' ? parsed.content : undefined;\n if (!content) return null;\n return { content };\n}\n\n/**\n * Parse arguments for memories_list_all tool\n * Optional typeFilter parameter for filtering by memory type\n */\nexport function parseMemoriesListAllArgs(args: unknown): MemoriesListAllArgs {\n const parsed = args as Record<string, unknown> | undefined;\n const typeFilter = parsed?.typeFilter;\n return {\n typeFilter: (typeFilter === \"all\" || typeFilter === \"user\" || typeFilter === \"agent\")\n ? typeFilter\n : undefined,\n };\n}\n\n// ============================================================================\n// Legacy Types (kept for backwards compatibility)\n// ============================================================================\n\n/**\n * @deprecated Legacy type - prompts are now account-scoped (no projectSlug)\n * Kept for backwards compatibility during transition period.\n */\nexport interface McpPrompt {\n slug: string;\n name: string;\n description?: string;\n flattenedPrompt?: string;\n folderPath?: string; // Folder organization (used for ZIP downloads, not slash commands)\n projectSlug?: string; // @deprecated - prompts are now account-scoped\n projectName?: string; // @deprecated - prompts are now account-scoped\n}\n\n/**\n * @deprecated Legacy type - prompts are now account-scoped (no projectSlug)\n * Kept for backwards compatibility during transition period.\n */\nexport interface McpPromptMetadata {\n slug: string;\n description?: string;\n projectSlug?: string; // @deprecated - prompts are now account-scoped\n}\n\n// Note: McpCommandMetadata and McpCommandFull removed - commands resource eliminated\n\n/**\n * @deprecated Legacy type - prompts are now account-scoped (no projectSlug)\n * Kept for backwards compatibility during transition period.\n */\nexport interface McpPromptFull {\n slug: string;\n description?: string;\n flattenedPrompt?: string;\n projectSlug?: string; // @deprecated - prompts are now account-scoped\n}\n\n/**\n * @deprecated Legacy type - use account-scoped prompt queries instead\n * Kept for backwards compatibility during transition period.\n */\nexport type PromptMatchResult =\n | { matchType: \"exact\" | \"prefix\" | \"contains\"; slug: string; description?: string; flattenedPrompt?: string; projectSlug: string }\n | { matchType: \"ambiguous\"; suggestions: string[] }\n | null;\n\n/**\n * Configuration for the MCP server\n *\n * Authentication: Project Token (PPM_PROJECT_TOKEN)\n * Provides scoped access to a single project for both prompts and tickets.\n * The token's ownerId determines which prompts are accessible (account-scoped).\n *\n * Note: API Key auth (PPM_API_KEY) has been deprecated.\n * All authentication now uses project tokens.\n */\nexport interface ServerConfig {\n projectToken: string; // Required - scoped access to a single project\n isDev: boolean;\n convexUrl: string;\n}\n\n/**\n * Result of project token validation\n * Token is now stored directly on the projects table (single token per project)\n */\nexport interface ProjectTokenValidation {\n valid: boolean;\n projectId?: string;\n projectSlug?: string;\n ownerId?: string;\n error?: string;\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type { ServerConfig, PromptMetadata, AccountScopedPromptResult } from \"./types.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n * This allows us to use string function names while maintaining type safety\n * for the response types through explicit casting.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * Sanitizes a string for use in MCP tool names.\n * Ensures output matches MCP protocol pattern: ^[a-zA-Z0-9_-]{1,64}$\n *\n * @param str - Raw string to sanitize (project slug, folder path, or prompt slug)\n * @returns Sanitized string safe for MCP tool names\n */\nexport function sanitizeForMcp(str: string): string {\n return str\n .trim() // Remove leading/trailing whitespace first\n .toLowerCase() // Convert to lowercase for consistency\n .replace(/[^a-z0-9_-]/g, '-') // Replace ALL invalid chars (including spaces!) with hyphens\n .replace(/-+/g, '-') // Collapse multiple consecutive hyphens into one\n .replace(/^-+|-+$/g, '') // Remove leading and trailing hyphens\n .trim(); // Final trim to ensure no whitespace\n}\n\n// Note: The following legacy functions have been removed as prompts are now account-scoped:\n// - buildPromptName (was project:prompt format, now prompts are global)\n// - buildPromptNameFromMetadata (was project:prompt format)\n// - buildPromptSchema (used buildPromptName)\n// - buildPromptHandler (used project-scoped getMcpPrompts query)\n// - fetchAndExecutePrompt (used project-scoped getMcpPromptBySlug query)\n//\n// Use fetchAndExecuteAccountScopedPrompt instead for all prompt execution.\n\n/**\n * Custom error class for ambiguous prompt matches\n * Contains suggestions for the user to choose from\n */\nexport class AmbiguousPromptError extends Error {\n suggestions: string[];\n\n constructor(promptSlug: string, suggestions: string[]) {\n super(`Multiple prompts match \"${promptSlug}\". Please be more specific.`);\n this.name = \"AmbiguousPromptError\";\n this.suggestions = suggestions;\n }\n}\n\n/**\n * Fetch account-scoped prompt metadata using project token auth.\n *\n * @param client - Convex HTTP client\n * @param projectToken - Project token for authentication\n * @returns Account-scoped prompts for this project\n */\nexport async function fetchAccountScopedPromptMetadataByToken(\n client: ConvexHttpClient,\n projectToken: string\n): Promise<PromptMetadata[]> {\n try {\n // Cast to our typed client for string-based function references\n const typedClient = client as ConvexClientWithStringRefs;\n const metadata = await typedClient.query<PromptMetadata[]>(\n \"mcp_prompts:getAccountScopedPromptMetadataByToken\",\n { projectToken }\n );\n return metadata;\n } catch (error) {\n throw new Error(\n `Failed to fetch prompts via project token: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n}\n\n// Note: AccountScopedPromptResult type is imported from ./types.js\n\n/**\n * Fetch a single account-scoped prompt and execute it\n *\n * Account-scoped prompts are global (no project prefix required).\n * This is for prompts that don't have a projectId.\n *\n * Uses project token authentication: access via token's ownerId.\n *\n * Matching algorithm supports exact, prefix, and contains matching.\n */\nexport async function fetchAndExecuteAccountScopedPrompt(\n promptSlug: string,\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<{ messages: Array<{ role: string; content: { type: \"text\"; text: string } }> }> {\n // Cast to our typed client for string-based function references\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n // Project token auth - access via token's owner\n // NOTE: This is a mutation (not query) to enable analytics logging\n const result = await typedClient.mutation<AccountScopedPromptResult>(\n \"mcp_prompts:getAccountScopedPromptBySlugByToken\",\n {\n projectToken: config.projectToken,\n promptSlug,\n }\n );\n\n // Handle null - no matches found\n if (!result) {\n throw new Error(\n `Prompt \"${promptSlug}\" not found. Use system:prompts to list available prompts.`\n );\n }\n\n // Handle ambiguous matches - throw custom error with suggestions\n if (result.matchType === \"ambiguous\") {\n throw new AmbiguousPromptError(promptSlug, result.suggestions);\n }\n\n // Handle successful match (exact, prefix, or contains)\n if (!result.flattenedPrompt) {\n throw new Error(\n `Prompt \"${result.slug}\" has no flattened content. Please re-save the prompt to regenerate it.`\n );\n }\n\n // Log match type for debugging\n const matchNote = result.matchType === \"exact\"\n ? \"exact match\"\n : result.matchType === \"prefix\"\n ? `prefix match → ${result.slug}`\n : `contains match → ${result.slug}`;\n console.error(`[MCP] Fetched account-scoped prompt: ${promptSlug} (${matchNote})`);\n\n // Return raw flattened prompt (client will parse YAML front matter)\n return {\n messages: [\n {\n role: \"user\",\n content: {\n type: \"text\" as const,\n text: result.flattenedPrompt,\n },\n },\n ],\n };\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type {\n ServerConfig,\n UpdatePromptResult,\n PromptMetadata,\n} from \"../types.js\";\nimport {\n parsePromptsRunArgs,\n parsePromptsListArgs,\n parsePromptsUpdateArgs,\n} from \"../types.js\";\nimport { buildAuthArgs } from \"../auth/index.js\";\nimport {\n fetchAndExecuteAccountScopedPrompt,\n AmbiguousPromptError,\n} from \"../prompt-builder.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * MCP tool response format\n * Note: Index signature required for MCP SDK v1.20+ compatibility\n */\nexport interface McpToolResponse {\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n [x: string]: unknown;\n}\n\n/**\n * Handle prompts_run tool - execute a prompt by slug\n */\nexport async function handlePromptsRun(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<McpToolResponse> {\n const parsedArgs = parsePromptsRunArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing 'slug' parameter. Provide prompt slug (e.g., 'code-review', 'plan').\n\nUse \\`prompts_list\\` to list available prompts.`,\n },\n ],\n isError: true,\n };\n }\n\n const { slug: promptSlug } = parsedArgs;\n\n // Execute the prompt using account-scoped lookup\n try {\n const result = await fetchAndExecuteAccountScopedPrompt(\n promptSlug,\n config,\n convexClient\n );\n\n // Convert prompt result to tool result format\n const promptText = result.messages.map((msg) => msg.content.text).join(\"\\n\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: promptText,\n },\n ],\n };\n } catch (error) {\n // Handle ambiguous prompt matches with helpful suggestions\n if (error instanceof AmbiguousPromptError) {\n const suggestionsList = error.suggestions.map((s) => ` • ${s}`).join(\"\\n\");\n console.error(`[MCP] prompts_run ambiguous match:`, error.suggestions);\n return {\n content: [\n {\n type: \"text\",\n text: `Multiple prompts match \"${promptSlug}\". Please specify one of:\\n\\n${suggestionsList}\\n\\nExample: \\`prompts_run ${error.suggestions[0]}\\``,\n },\n ],\n isError: true,\n };\n }\n\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] prompts_run error:`, error);\n return {\n content: [\n {\n type: \"text\",\n text: `Error executing prompt \"${promptSlug}\": ${errorMessage}`,\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Handle prompts_list tool - list available prompts\n */\nexport async function handlePromptsList(\n args: unknown,\n _config: ServerConfig,\n _convexClient: ConvexHttpClient,\n accountScopedPrompts: PromptMetadata[]\n): Promise<McpToolResponse> {\n const { search: searchTerm } = parsePromptsListArgs(args);\n\n // Use account-scoped prompts (global, no project filter)\n let filteredPrompts = [...accountScopedPrompts];\n\n // Filter by search term if provided\n if (searchTerm) {\n const lowerSearch = searchTerm.toLowerCase();\n filteredPrompts = filteredPrompts.filter(\n (p) =>\n p.slug.toLowerCase().includes(lowerSearch) ||\n p.description?.toLowerCase().includes(lowerSearch)\n );\n }\n\n // Sort prompts by slug\n filteredPrompts.sort((a, b) => a.slug.localeCompare(b.slug));\n\n // Build user prompts list\n const userPromptList = filteredPrompts\n .map((p) => {\n const desc = p.description || \"No description\";\n return `• ${p.slug}\\n Description: ${desc}`;\n })\n .join(\"\\n\\n\");\n\n const summary = searchTerm\n ? `Found ${filteredPrompts.length} prompt(s) matching \"${searchTerm}\":`\n : `Available prompts (${filteredPrompts.length} total):`;\n\n return {\n content: [\n {\n type: \"text\",\n text: userPromptList\n ? `${summary}\\n\\n${userPromptList}`\n : `${summary}\\n\\nNo prompts found.`,\n },\n ],\n };\n}\n\n/**\n * Handle prompts_update tool - read or update a prompt\n */\nexport async function handlePromptsUpdate(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient\n): Promise<McpToolResponse> {\n const parsedArgs = parsePromptsUpdateArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing 'slug' parameter. Provide prompt slug to read or update.\n\nUsage:\n- Read mode: prompts_update { slug: \"my-prompt\" }\n- Write mode: prompts_update { slug: \"my-prompt\", content: \"new content...\" }`,\n },\n ],\n isError: true,\n };\n }\n\n try {\n const typedClient = convexClient as ConvexClientWithStringRefs;\n const result = await typedClient.mutation<UpdatePromptResult>(\n \"mcp_prompts:updateMcpPrompt\",\n {\n ...buildAuthArgs(config),\n promptSlug: parsedArgs.slug,\n content: parsedArgs.content,\n }\n );\n\n if (!result.success) {\n // Handle error (not found, ambiguous)\n const errorResult = result as { success: false; error: string; suggestions?: string[] };\n if (errorResult.suggestions) {\n const suggestionsList = errorResult.suggestions.map((s) => ` • ${s}`).join(\"\\n\");\n return {\n content: [\n {\n type: \"text\",\n text: `${errorResult.error}\\n\\nDid you mean one of these?\\n${suggestionsList}`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: errorResult.error }],\n isError: true,\n };\n }\n\n // Handle read mode response\n if (result.mode === \"read\") {\n const readResult = result as {\n mode: \"read\";\n matchType: string;\n slug: string;\n description: string;\n content: string;\n version?: number;\n context?: object;\n editingGuidance: string;\n hasAiTags?: boolean;\n aiTags?: string[];\n };\n\n // Format the response with all context\n const matchNote =\n readResult.matchType !== \"exact\"\n ? `\\n_Note: Matched via ${readResult.matchType} match_`\n : \"\";\n\n // AI tag notice if tags detected\n const aiTagNotice = readResult.hasAiTags\n ? `\\n\\n## ⚡ AI Tags Detected\\nThis prompt contains AI tags that need processing: **${readResult.aiTags?.join(\", \")}**\\n\\nProcess these tags by reading the instructions in each tag, generating appropriate content, and saving the result with the content parameter.`\n : \"\";\n\n // Version info\n const versionInfo = readResult.version !== undefined ? ` (v${readResult.version})` : \"\";\n\n // Context section\n const contextSection = readResult.context\n ? `\\n\\n## Available Resources\\n\\`\\`\\`json\\n${JSON.stringify(readResult.context, null, 2)}\\n\\`\\`\\``\n : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Prompt: ${readResult.slug}${versionInfo}${matchNote}${aiTagNotice}\n\n## Description\n${readResult.description || \"No description\"}\n\n## Content\n\\`\\`\\`\n${readResult.content}\n\\`\\`\\`${contextSection}\n\n${readResult.editingGuidance}\n\n---\n_To update this prompt, call prompts_update with content parameter._`,\n },\n ],\n };\n }\n\n // Handle write mode response\n if (result.mode === \"write\") {\n const writeResult = result as {\n mode: \"write\";\n slug: string;\n version?: number;\n updatedAt?: string;\n message: string;\n };\n\n // Version info\n const versionInfo = writeResult.version !== undefined ? `\\nVersion: ${writeResult.version}` : \"\";\n\n // Updated timestamp\n const updatedInfo = writeResult.updatedAt ? `\\nUpdated: ${writeResult.updatedAt}` : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ ${writeResult.message}\n\nPrompt: ${writeResult.slug}${versionInfo}${updatedInfo}`,\n },\n ],\n };\n }\n\n // Shouldn't reach here, but handle gracefully\n return {\n content: [{ type: \"text\", text: \"Unknown response format\" }],\n isError: true,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] prompts_update error:`, error);\n return {\n content: [\n {\n type: \"text\",\n text: `Error updating prompt: ${errorMessage}`,\n },\n ],\n isError: true,\n };\n }\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type {\n ServerConfig,\n WorkTicketResult,\n AccessDeniedResult,\n PlanStatusBlockedResult,\n CreateTicketResult,\n CloseTicketResult,\n PauseTicketResult,\n UpdateTicketResult,\n ReplaceTicketResult,\n GetTicketResult,\n ListTicketItem,\n SearchTicketItem,\n} from \"../types.js\";\nimport type { PlanTicketResult } from \"../types.js\";\nimport {\n parseWorkArgs,\n parsePlanArgs,\n parseCloseArgs,\n parsePauseArgs,\n parseCreateArgs,\n parseSearchArgs,\n parseGetArgs,\n parseListArgs,\n parseUpdateArgs,\n parseReplaceArgs,\n isAccessDenied,\n isPlanStatusBlocked,\n} from \"../types.js\";\nimport { buildAuthArgs, resolveAgent } from \"../auth/index.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * MCP tool response format\n * Note: Index signature required for MCP SDK v1.20+ compatibility\n */\nexport interface McpToolResponse {\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n [x: string]: unknown;\n}\n\n/**\n * Handle tickets_work tool - get next ticket or work on specific ticket\n */\nexport async function handleTicketsWork(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { ticketSlug, agent } = parseWorkArgs(args);\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<WorkTicketResult | AccessDeniedResult | PlanStatusBlockedResult | null>(\n \"mcp_tickets:workMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n agentId: resolvedAgent,\n }\n );\n\n if (!result) {\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n const message = ticketSlug\n ? `Ticket \"${ticketSlug}\" not found or not in open/working status in project \"${projectSlug}\"${agentContext}.`\n : `No open tickets${agentContext} in project \"${projectSlug}\".`;\n return {\n content: [{ type: \"text\", text: message }],\n };\n }\n\n if (isAccessDenied(result)) {\n return {\n content: [{ type: \"text\", text: `Access denied: ${result.error}` }],\n isError: true,\n };\n }\n\n if (isPlanStatusBlocked(result)) {\n return {\n content: [{ type: \"text\", text: result.error }],\n isError: true,\n };\n }\n\n const workResult = result as WorkTicketResult;\n const startedInfo = workResult.startedAt\n ? `\\nStarted: ${new Date(workResult.startedAt).toISOString()}`\n : \"\";\n\n const pausedNotice = workResult.pausedAt\n ? `\\n\\n**⚠️ PAUSED TICKET HANDOFF**: This ticket was paused on ${new Date(workResult.pausedAt).toISOString()}. A previous agent checkpointed their progress. Review the checkpoint content below (look for \"## Progress\", \"## Context\", \"## Remaining\", \"## Blockers\" sections) and resume where they left off.\\n`\n : \"\";\n\n const statusNote = workResult.wasOpened\n ? `_Ticket moved to working status. ${workResult.remainingTickets} ticket(s) remaining in queue._`\n : `_Resuming work on this ticket. ${workResult.remainingTickets} ticket(s) in queue._`;\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ticket: ${workResult.slug} [WORKING]${startedInfo}${pausedNotice}\n\n${workResult.content}\n\n---\n${statusNote}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_work error:`, error);\n return {\n content: [{ type: \"text\", text: `Error getting work: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_plan tool - get planning work without status change\n */\nexport async function handleTicketsPlan(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { ticketSlug, agent } = parsePlanArgs(args);\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<PlanTicketResult | null>(\n \"mcp_tickets:planMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n agentId: resolvedAgent,\n }\n );\n\n if (!result) {\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n const message = ticketSlug\n ? `Ticket \"${ticketSlug}\" not found or not in plan status in project \"${projectSlug}\"${agentContext}.`\n : `No plan tickets${agentContext} in project \"${projectSlug}\".`;\n return {\n content: [{ type: \"text\", text: message }],\n };\n }\n\n const startedInfo = result.startedAt\n ? `\\nStarted: ${new Date(result.startedAt).toISOString()}`\n : \"\";\n\n const planningBanner = `⚠️ PLANNING MODE REQUIRED\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nThis ticket is in PLAN status. You may ONLY:\n• Create/update plan files\n• Update this ticket with planning notes\n• Create sub-tickets for implementation\n\nDO NOT: Write code or make implementation changes.\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;\n\n const statusNote = `_Ticket remains in plan status. ${result.remainingPlanTickets} plan ticket(s) remaining in queue._`;\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ticket: ${result.slug} [PLAN]${startedInfo}\n\n${planningBanner}\n\n${result.content}\n\n---\n${statusNote}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_plan error:`, error);\n return {\n content: [{ type: \"text\", text: `Error getting plan work: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_create tool - create a new ticket\n */\nexport async function handleTicketsCreate(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseCreateArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the ticket content (first line becomes the slug).`,\n },\n ],\n isError: true,\n };\n }\n\n const { content, agent } = parsedArgs;\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<CreateTicketResult>(\n \"mcp_tickets:createMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n content,\n agentId: resolvedAgent,\n }\n );\n\n const agentInfo = result.agentId ? `\\nAssigned to: ${result.agentId}` : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Created ticket [${result.slug}] in plan queue for project \"${projectSlug}\".${agentInfo}\n\nPosition: #${result.position} of ${result.totalPlan} plan tickets\nPreview: ${result.preview}\n\n_Ticket created in plan queue. Use \\`tickets_work ${result.slug}\\` to move it to working status._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_create error:`, error);\n return {\n content: [{ type: \"text\", text: `Error creating ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_close tool - close a working ticket\n */\nexport async function handleTicketsClose(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseCloseArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Usage: Provide a ticket number (e.g., \"102\") or full slug (e.g., \"102-fix-auth\").`,\n },\n ],\n isError: true,\n };\n }\n\n const { ticketSlug, metadata } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<CloseTicketResult>(\n \"mcp_tickets:closeMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n metadata,\n }\n );\n\n let responseText = `✅ Ticket [${result.slug}] closed in project \"${projectSlug}\".\n\nClosed at: ${new Date(result.closedAt).toISOString()}`;\n\n if (result.metadata && Object.keys(result.metadata).length > 0) {\n responseText += `\\n\\n**Metadata saved:**`;\n for (const [key, value] of Object.entries(result.metadata)) {\n responseText += `\\n- ${key}: ${JSON.stringify(value)}`;\n }\n }\n\n responseText += `\\n\\n_Reminder: Ensure all embedded \\`[RUN_PROMPT ...]\\` directives were executed before closing._`;\n\n return {\n content: [{ type: \"text\", text: responseText }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_close error:`, error);\n return {\n content: [{ type: \"text\", text: `Error closing ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_pause tool - pause a working ticket and return to queue\n */\nexport async function handleTicketsPause(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parsePauseArgs(args);\n\n if (!parsedArgs) {\n const rawArgs = args as Record<string, unknown> | undefined;\n const hasTicketSlug = typeof rawArgs?.ticketSlug === \"string\" && rawArgs.ticketSlug;\n const hasContent = typeof rawArgs?.content === \"string\" && rawArgs.content;\n\n if (!hasTicketSlug) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n if (!hasContent) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Describe what's done, what remains, and any blockers.`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: `Error: Missing required parameters.` }],\n isError: true,\n };\n }\n\n const { ticketSlug, content } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<PauseTicketResult>(\n \"mcp_tickets:pauseMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n content,\n }\n );\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Ticket [${result.slug}] paused and returned to open queue in project \"${projectSlug}\".\n\nPaused at: ${new Date(result.pausedAt).toISOString()}\n\n_Ticket moved from working → open. Checkpoint content has been appended. Any agent can pick it up with \\`tickets_work\\`._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_pause error:`, error);\n return {\n content: [{ type: \"text\", text: `Error pausing ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_search tool - search tickets by content\n */\nexport async function handleTicketsSearch(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseSearchArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [{ type: \"text\", text: `Error: Search query must be at least 3 characters` }],\n isError: true,\n };\n }\n\n const { query, agent } = parsedArgs;\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<SearchTicketItem[]>(\"mcp_tickets:searchMcpTickets\", {\n ...buildAuthArgs(config),\n projectSlug,\n query,\n agentId: resolvedAgent,\n });\n\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n\n if (result.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No tickets found matching \"${query}\"${agentContext} in project \"${projectSlug}\".`,\n },\n ],\n };\n }\n\n const formattedList = result\n .map((t) => {\n const statusBadge =\n t.status === \"open\"\n ? \"🟢\"\n : t.status === \"working\"\n ? \"🟡\"\n : t.status === \"closed\"\n ? \"⚫\"\n : \"⚪\";\n const num = t.ticketNumber ? `#${t.ticketNumber}` : \"\";\n const agentBadge = t.agentId ? ` [${t.agentId}]` : \"\";\n const metadataHint =\n t.metadata && Object.keys(t.metadata).length > 0\n ? ` {${Object.keys(t.metadata).length} meta}`\n : \"\";\n return `${statusBadge} ${num} ${t.slug}${agentBadge}${metadataHint}\\n ${t.matchSnippet}`;\n })\n .join(\"\\n\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${result.length} ticket(s) matching \"${query}\"${agentContext}:\\n\\n${formattedList}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_search error:`, error);\n return {\n content: [{ type: \"text\", text: `Error searching tickets: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_get tool - get a specific ticket (read-only)\n */\nexport async function handleTicketsGet(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseGetArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n\n const { ticketSlug } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<GetTicketResult | AccessDeniedResult | null>(\n \"mcp_tickets:getMcpTicket\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n }\n );\n\n if (!result) {\n return {\n content: [\n {\n type: \"text\",\n text: `Ticket \"${ticketSlug}\" not found in project \"${projectSlug}\".`,\n },\n ],\n };\n }\n\n if (isAccessDenied(result)) {\n return {\n content: [{ type: \"text\", text: `Access denied: ${result.error}` }],\n isError: true,\n };\n }\n\n const getResult = result as GetTicketResult;\n\n const statusBadge = getResult.status.toUpperCase();\n const startedInfo = getResult.startedAt\n ? `\\nStarted: ${new Date(getResult.startedAt).toISOString()}`\n : \"\";\n const closedInfo = getResult.closedAt\n ? `\\nClosed: ${new Date(getResult.closedAt).toISOString()}`\n : \"\";\n\n let metadataInfo = \"\";\n if (getResult.metadata && Object.keys(getResult.metadata).length > 0) {\n metadataInfo = \"\\n\\n**Metadata:**\";\n for (const [key, value] of Object.entries(getResult.metadata)) {\n metadataInfo += `\\n- ${key}: ${JSON.stringify(value)}`;\n }\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ticket: ${getResult.slug} [${statusBadge}]${startedInfo}${closedInfo}\n\n${getResult.content}${metadataInfo}\n\n---\n_Read-only inspection. Use tickets_work to start working on this ticket._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_get error:`, error);\n return {\n content: [{ type: \"text\", text: `Error getting ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_list tool - list active tickets\n */\nexport async function handleTicketsList(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { agent } = parseListArgs(args);\n const resolvedAgent = resolveAgent(agent);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<ListTicketItem[]>(\"mcp_tickets:listMcpTickets\", {\n ...buildAuthArgs(config),\n projectSlug,\n agentId: resolvedAgent,\n });\n\n const agentContext = resolvedAgent ? ` for agent \"${resolvedAgent}\"` : \"\";\n\n if (result.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No active tickets${agentContext} in project \"${projectSlug}\". All tickets are closed.`,\n },\n ],\n };\n }\n\n const openTickets = result.filter((t) => t.status === \"open\");\n const workingTickets = result.filter((t) => t.status === \"working\");\n const planTickets = result.filter((t) => t.status === \"plan\");\n\n const formatTicketLine = (t: ListTicketItem) => {\n const num = t.ticketNumber ? `#${t.ticketNumber}` : \"\";\n const agentBadge = !resolvedAgent && t.agentId ? ` [${t.agentId}]` : \"\";\n return ` ${t.position}. ${num} ${t.slug}${agentBadge}\\n ${t.preview}`;\n };\n\n const sections: string[] = [];\n\n if (openTickets.length > 0) {\n sections.push(\n `**🟢 Open (${openTickets.length})**\\n${openTickets.map(formatTicketLine).join(\"\\n\")}`\n );\n }\n if (workingTickets.length > 0) {\n sections.push(\n `**🟡 Working (${workingTickets.length})**\\n${workingTickets.map(formatTicketLine).join(\"\\n\")}`\n );\n }\n if (planTickets.length > 0) {\n sections.push(\n `**⚪ Plan (${planTickets.length})**\\n${planTickets.map(formatTicketLine).join(\"\\n\")}`\n );\n }\n\n const headerSuffix = resolvedAgent ? ` (Agent: ${resolvedAgent})` : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Active Queue: ${projectSlug}${headerSuffix}\\n\\n${result.length} ticket(s) in queue\\n\\n${sections.join(\"\\n\\n\")}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_list error:`, error);\n return {\n content: [{ type: \"text\", text: `Error listing tickets: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_update tool - append content to a ticket\n */\nexport async function handleTicketsUpdate(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseUpdateArgs(args);\n\n if (!parsedArgs) {\n const rawArgs = args as Record<string, unknown> | undefined;\n const hasTicketSlug = typeof rawArgs?.ticketSlug === \"string\" && rawArgs.ticketSlug;\n const hasContent = typeof rawArgs?.content === \"string\" && rawArgs.content;\n\n if (!hasTicketSlug) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n if (!hasContent) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the update content to append to the ticket.`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: `Error: Missing required parameters.` }],\n isError: true,\n };\n }\n\n const { ticketSlug, content, agent } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<UpdateTicketResult>(\"mcp_tickets:updateMcpTicket\", {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n content,\n ...(agent !== undefined && { agentId: agent }),\n });\n\n const agentInfo = result.agentId\n ? `\\nAssigned to: ${result.agentId}`\n : agent === \"\"\n ? \"\\nAgent: Unassigned\"\n : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Ticket [${result.slug}] updated in project \"${projectSlug}\".${agentInfo}\nUpdated at: ${new Date(result.updatedAt).toISOString()}\n_Ticket content has been appended with your update._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_update error:`, error);\n return {\n content: [{ type: \"text\", text: `Error updating ticket: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle tickets_replace tool - replace ticket content (destructive operation)\n * Only works on plan status tickets. Archives old content in HTML comment.\n */\nexport async function handleTicketsReplace(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseReplaceArgs(args);\n\n if (!parsedArgs) {\n const rawArgs = args as Record<string, unknown> | undefined;\n const hasTicketSlug = typeof rawArgs?.ticketSlug === \"string\" && rawArgs.ticketSlug;\n const hasContent = typeof rawArgs?.content === \"string\" && rawArgs.content;\n\n if (!hasTicketSlug) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing ticketSlug parameter. Provide a ticket number (e.g., \"102\") or full slug.`,\n },\n ],\n isError: true,\n };\n }\n if (!hasContent) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the new content to replace the ticket with.`,\n },\n ],\n isError: true,\n };\n }\n return {\n content: [{ type: \"text\", text: `Error: Missing required parameters.` }],\n isError: true,\n };\n }\n\n const { ticketSlug, content } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<ReplaceTicketResult>(\"mcp_tickets:replaceMcpTicket\", {\n ...buildAuthArgs(config),\n projectSlug,\n ticketSlug,\n content,\n });\n\n return {\n content: [\n {\n type: \"text\",\n text: `✅ Ticket [${result.slug}] content replaced in project \"${projectSlug}\".\n\nReplaced at: ${new Date(result.replacedAt).toISOString()}\nArchived: ${result.archivedContentLength} characters\nNew content: ${result.newContentLength} characters\n\n_Old content has been archived in an HTML comment block. Ticket remains in plan status._`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] tickets_replace error:`, error);\n return {\n content: [{ type: \"text\", text: `Error replacing ticket content: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n","import type { ConvexHttpClient } from \"convex/browser\";\nimport type {\n ServerConfig,\n LoadMemoriesResult,\n LoadMemoriesExtremeResult,\n AddMemoryResult,\n ListAllMemoriesResult,\n} from \"../types.js\";\nimport {\n parseMemoriesLoadArgs,\n parseMemoriesAddArgs,\n parseMemoriesListAllArgs,\n} from \"../types.js\";\nimport { buildAuthArgs } from \"../auth/index.js\";\n\n/**\n * Helper type for Convex HTTP client with string-based function references.\n */\ntype ConvexClientWithStringRefs = ConvexHttpClient & {\n mutation: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n query: <T>(name: string, args: Record<string, unknown>) => Promise<T>;\n};\n\n/**\n * MCP tool response format\n * Note: Index signature required for MCP SDK v1.20+ compatibility\n */\nexport interface McpToolResponse {\n content: Array<{ type: \"text\"; text: string }>;\n isError?: boolean;\n [x: string]: unknown;\n}\n\n/**\n * Handle memories_load tool - load project memories (rules + history)\n */\nexport async function handleMemoriesLoad(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { query } = parseMemoriesLoadArgs(args);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<LoadMemoriesResult>(\"mcp_memories:loadMemories\", {\n ...buildAuthArgs(config),\n projectSlug,\n query,\n });\n\n const sections: string[] = [];\n\n // Rules section (always show)\n if (result.userMemories.length > 0) {\n const rulesText = result.userMemories.map((m, i) => `${i + 1}. ${m.content}`).join(\"\\n\");\n sections.push(`## Rules (${result.userMemories.length})\\n${rulesText}`);\n } else {\n sections.push(`## Rules\\n_No rules defined. Create rules in the Memories page._`);\n }\n\n // History section\n if (result.agentMemories.length > 0) {\n const historyText = result.agentMemories\n .map((m) => {\n const ticketRef = m.ticketNumber ? `[#${m.ticketNumber}]` : \"\";\n const date = new Date(m.createdAt).toISOString().split(\"T\")[0];\n return `• ${ticketRef} ${m.content} _(${date})_`;\n })\n .join(\"\\n\");\n const searchNote = query ? ` matching \"${query}\"` : \" (recent)\";\n sections.push(`## History${searchNote} (${result.agentMemories.length})\\n${historyText}`);\n } else {\n const searchNote = query ? ` matching \"${query}\"` : \"\";\n sections.push(`## History${searchNote}\\n_No memories recorded yet._`);\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Project Memories: ${projectSlug}\\n\\n${sections.join(\"\\n\\n\")}`,\n },\n ],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_load error:`, error);\n return {\n content: [{ type: \"text\", text: `Error loading memories: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle memories_load_extreme tool - load memories with full ticket content\n */\nexport async function handleMemoriesLoadExtreme(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const { query } = parseMemoriesLoadArgs(args);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<LoadMemoriesExtremeResult>(\n \"mcp_memories:loadMemoriesExtreme\",\n {\n ...buildAuthArgs(config),\n projectSlug,\n query,\n }\n );\n\n const lines: string[] = [];\n lines.push(`# Project Memories: ${projectSlug}\\n`);\n\n // Rules section\n lines.push(`## Rules (${result.userMemories.length})`);\n if (result.userMemories.length > 0) {\n result.userMemories.forEach((m, i) => {\n lines.push(`${i + 1}. ${m.content}`);\n });\n } else {\n lines.push(`_No rules defined. Create rules in the Memories page._`);\n }\n lines.push(\"\");\n\n // History section with full ticket content\n const historyHeader = query\n ? `## History matching \"${query}\" (${result.agentMemories.length})`\n : `## Recent History (${result.agentMemories.length})`;\n lines.push(historyHeader);\n lines.push(\"\");\n\n for (const memory of result.agentMemories) {\n lines.push(\"---\");\n lines.push(`**Memory:** ${memory.content}`);\n\n if (memory.ticket) {\n lines.push(`**Ticket:** #${memory.ticket.ticketNumber}-${memory.ticket.slug}`);\n }\n\n const date = new Date(memory.createdAt).toISOString().split(\"T\")[0];\n lines.push(`**Date:** ${date}`);\n lines.push(\"\");\n\n if (memory.ticket) {\n lines.push(\"<ticket-content>\");\n lines.push(memory.ticket.content);\n lines.push(\"</ticket-content>\");\n } else {\n lines.push(\"_(No linked ticket)_\");\n }\n lines.push(\"\");\n }\n\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_load_extreme error:`, error);\n return {\n content: [{ type: \"text\", text: `Error loading extreme memories: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle memories_add tool - add a new memory\n */\nexport async function handleMemoriesAdd(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseMemoriesAddArgs(args);\n\n if (!parsedArgs) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: Missing content parameter. Provide the memory content to record.`,\n },\n ],\n isError: true,\n };\n }\n\n const { content } = parsedArgs;\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.mutation<AddMemoryResult>(\"mcp_memories:addMemory\", {\n ...buildAuthArgs(config),\n projectSlug,\n content,\n });\n\n let responseText: string;\n if (result.linkedTicket) {\n const ticketRef = `#${result.linkedTicket.number}`;\n const fallbackNote = result.linkedViaFallback ? \" (recently closed)\" : \"\";\n responseText = `✅ Memory recorded for ticket [${ticketRef}]${fallbackNote} in project \"${projectSlug}\".\\n\\n_Memory will be available in future context via [MEMORY_LOAD]._`;\n } else {\n responseText = `✅ Memory recorded in project \"${projectSlug}\".\\n\\n_Memory created without ticket linkage (no working ticket or recent closed ticket)._\\n_Memory will be available in future context via [MEMORY_LOAD]._`;\n }\n\n return {\n content: [{ type: \"text\", text: responseText }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_add error:`, error);\n return {\n content: [{ type: \"text\", text: `Error adding memory: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n\n/**\n * Handle memories_list_all tool - list all memories for review/cleanup\n */\nexport async function handleMemoriesListAll(\n args: unknown,\n config: ServerConfig,\n convexClient: ConvexHttpClient,\n projectSlug: string\n): Promise<McpToolResponse> {\n const parsedArgs = parseMemoriesListAllArgs(args);\n const typedClient = convexClient as ConvexClientWithStringRefs;\n\n try {\n const result = await typedClient.query<ListAllMemoriesResult>(\"mcp_memories:listAllMemories\", {\n ...buildAuthArgs(config),\n projectSlug,\n typeFilter: parsedArgs.typeFilter,\n });\n\n const formatDate = (ts: number) => new Date(ts).toISOString().split(\"T\")[0];\n\n const userMemories = result.memories.filter((m) => m.type === \"user\");\n const agentMemories = result.memories.filter((m) => m.type === \"agent\");\n\n let output = `# Project Memories (${result.totalCount} total)\\n\\n`;\n\n if (userMemories.length > 0) {\n output += `## Rules (${userMemories.length})\\n`;\n userMemories.forEach((m, i) => {\n output += `${i + 1}. [${m.id}] ${m.content}\\n`;\n });\n output += \"\\n\";\n }\n\n if (agentMemories.length > 0) {\n output += `## Agent History (${agentMemories.length})\\n`;\n agentMemories.forEach((m) => {\n const ticketRef = m.ticketNumber ? ` [#${m.ticketNumber}]` : \"\";\n output += `• [${m.id}]${ticketRef} ${m.content.substring(0, 100)}${m.content.length > 100 ? \"...\" : \"\"} _(${formatDate(m.createdAt)})_\\n`;\n });\n }\n\n return {\n content: [{ type: \"text\", text: output }],\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`[MCP] memories_list_all error:`, error);\n return {\n content: [{ type: \"text\", text: `Error listing memories: ${errorMessage}` }],\n isError: true,\n };\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED