purmemo-mcp 13.2.0 → 13.3.0

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.js +56 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "purmemo-mcp",
3
- "version": "13.2.0",
3
+ "version": "13.3.0",
4
4
  "mcpName": "io.github.purmemo-ai/purmemo",
5
5
  "description": "MCP server for pūrmemo - AI conversation memory that works everywhere. Save and recall conversations across Claude Desktop, Cursor, and other MCP-compatible platforms. Intelligent context extraction, smart titles, living documents.",
6
6
  "main": "src/server.js",
package/src/server.js CHANGED
@@ -1094,8 +1094,7 @@ If no specific workflow is named, the system auto-routes based on the user's int
1094
1094
  properties: {
1095
1095
  workflow: {
1096
1096
  type: 'string',
1097
- enum: Object.keys(WORKFLOW_TEMPLATES),
1098
- description: 'Workflow name (e.g., "prd", "debug", "sprint"). Optional — if omitted, auto-routes from input.'
1097
+ description: 'Workflow name (e.g., "prd", "debug", "sprint"). Use list_workflows to see all available options including custom workflows. Optional — if omitted, auto-routes from input.'
1099
1098
  },
1100
1099
  input: {
1101
1100
  type: 'string',
@@ -1310,7 +1309,7 @@ Returns the full catalog of workflows organized by category with descriptions.`,
1310
1309
  ];
1311
1310
 
1312
1311
  const server = new Server(
1313
- { name: 'purmemo-mcp', version: '13.2.0' },
1312
+ { name: 'purmemo-mcp', version: '13.3.0' },
1314
1313
  {
1315
1314
  capabilities: { tools: {}, resources: {}, prompts: {} },
1316
1315
  instructions: `Purmemo is a cross-platform AI conversation memory system. Use these tools to save, search, and discover conversations across ChatGPT, Claude, Gemini, and other platforms.
@@ -2606,8 +2605,11 @@ async function handleRunWorkflow(args) {
2606
2605
  });
2607
2606
  }
2608
2607
 
2609
- if (!workflowName || !WORKFLOW_TEMPLATES[workflowName]) {
2610
- // Could not route return the catalog with a suggestion
2608
+ // Resolve template: check hardcoded first, then database for user-created workflows
2609
+ let template = workflowName ? WORKFLOW_TEMPLATES[workflowName] : null;
2610
+
2611
+ if (!workflowName) {
2612
+ // Could not route — return the catalog
2611
2613
  const catalogLines = Object.values(WORKFLOW_TEMPLATES)
2612
2614
  .map(wf => ` ${wf.name.padEnd(12)} — ${wf.description}`)
2613
2615
  .join('\n');
@@ -2623,11 +2625,56 @@ async function handleRunWorkflow(args) {
2623
2625
  };
2624
2626
  }
2625
2627
 
2626
- const template = WORKFLOW_TEMPLATES[workflowName];
2628
+ // If workflow not in hardcoded templates, it might be a user-created workflow
2629
+ // Check the database for it
2630
+ if (!template) {
2631
+ try {
2632
+ const userConfig = await makeApiCall(`/api/v1/workflow-dashboard/${workflowName}/user-config`);
2633
+ if (userConfig?.has_custom && userConfig?.prompt) {
2634
+ template = {
2635
+ name: workflowName,
2636
+ display_name: workflowName,
2637
+ description: '',
2638
+ memory_queries: ['[INPUT]'],
2639
+ route_chain: [],
2640
+ prompt: userConfig.prompt
2641
+ };
2642
+ structuredLog.info(`${toolName}: using user-created workflow`, {
2643
+ request_id: requestId,
2644
+ workflow: workflowName
2645
+ });
2646
+ }
2647
+ } catch {
2648
+ // Database unavailable — workflow not found
2649
+ }
2650
+ }
2651
+
2652
+ if (!template) {
2653
+ return {
2654
+ content: [{
2655
+ type: 'text',
2656
+ text: `Unknown workflow: "${workflowName}". Use list_workflows to see available options.`
2657
+ }]
2658
+ };
2659
+ }
2660
+
2661
+ // Check if the user has a custom prompt for this workflow (edits from dashboard)
2662
+ // User's custom prompt always wins over hardcoded default
2663
+ let workflowPrompt = template.prompt;
2664
+ try {
2665
+ const userConfig = await makeApiCall(`/api/v1/workflow-dashboard/${workflowName}/user-config`);
2666
+ if (userConfig?.has_custom && userConfig?.prompt) {
2667
+ workflowPrompt = userConfig.prompt;
2668
+ structuredLog.info(`${toolName}: using user's custom prompt`, {
2669
+ request_id: requestId,
2670
+ workflow: workflowName
2671
+ });
2672
+ }
2673
+ } catch {
2674
+ // Database unavailable — use hardcoded default
2675
+ }
2627
2676
 
2628
2677
  // Pre-load memories and identity in parallel
2629
- // Uses buildMemoryQueries to extract keywords from long input
2630
- // Short input (≤6 words) passes through directly; long input gets keyword extraction
2631
2678
  const memoryQueries = buildMemoryQueries(template, input);
2632
2679
 
2633
2680
  const [identityResult, ...memoryResults] = await Promise.allSettled([
@@ -2721,7 +2768,7 @@ async function handleRunWorkflow(args) {
2721
2768
  const assembled = [
2722
2769
  transparencyBlock,
2723
2770
  '',
2724
- template.prompt,
2771
+ workflowPrompt,
2725
2772
  '',
2726
2773
  identityBlock,
2727
2774
  `## User Input\n${input}`,