secondbrainos-mcp-server 1.4.2 → 1.4.4

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/build/index.js +45 -35
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -43,6 +43,7 @@ class SecondBrainOSServer {
43
43
  this.workflowNameToId = new Map();
44
44
  this.agentNameToId = new Map();
45
45
  this.cachedAgents = null;
46
+ this.cachedWorkflows = null;
46
47
  // Discover service paths from the OpenAPI schema
47
48
  this.runPromptChainPath = null;
48
49
  this.getAIAgentsSchemaPath = null;
@@ -205,24 +206,17 @@ class SecondBrainOSServer {
205
206
  // List available prompts (user's workflows + agents)
206
207
  this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
207
208
  const prompts = [];
208
- // Fetch workflows as prompts
209
+ // Fetch workflows as prompts (uses cached enriched data)
209
210
  if (this.runPromptChainPath) {
210
211
  try {
211
- const data = await this.callRunPromptChain('', '');
212
- const workflows = data.workflows || [];
212
+ const workflows = await this.fetchAndEnrichWorkflows();
213
213
  this.workflowNameToId.clear();
214
214
  for (const wf of workflows) {
215
- if (wf.name && wf.workflow_id) {
216
- const snakeName = `skill_${toSnakeCase(wf.name)}`;
217
- this.workflowNameToId.set(snakeName, wf.workflow_id);
218
- }
219
- }
220
- for (const wf of workflows) {
221
- const skillName = wf.name || wf.workflow_id;
222
- const snakeName = `skill_${toSnakeCase(skillName)}`;
215
+ const snakeName = `skill_${toSnakeCase(wf.name)}`;
216
+ this.workflowNameToId.set(snakeName, wf.workflow_id);
223
217
  prompts.push({
224
218
  name: snakeName,
225
- title: `[Skill] ${skillName}`,
219
+ title: `[Skill] ${wf.name}`,
226
220
  description: wf.description || wf.name,
227
221
  arguments: [
228
222
  {
@@ -570,6 +564,42 @@ class SecondBrainOSServer {
570
564
  this.cachedAgents = agents;
571
565
  return agents;
572
566
  }
567
+ async fetchAndEnrichWorkflows() {
568
+ if (this.cachedWorkflows)
569
+ return this.cachedWorkflows;
570
+ const data = await this.callRunPromptChain('', '');
571
+ const workflows = (data.workflows || []).filter((wf) => wf.name && wf.workflow_id);
572
+ const enriched = await Promise.all(workflows.map(async (wf) => {
573
+ try {
574
+ const workflowDetail = await this.callRunPromptChain('workflow', wf.workflow_id);
575
+ const promptIds = workflowDetail.prompt_id || [];
576
+ const promptResults = await Promise.all(promptIds.map(async (promptId) => {
577
+ try {
578
+ const promptData = await this.callRunPromptChain('prompt', promptId);
579
+ return {
580
+ id: promptId,
581
+ name: promptData.name,
582
+ order: promptData.order,
583
+ description: promptData.description || ''
584
+ };
585
+ }
586
+ catch {
587
+ return { id: promptId, name: '', order: 0, description: '' };
588
+ }
589
+ }));
590
+ return {
591
+ ...wf,
592
+ prompts: promptResults.sort((a, b) => (a.order || 0) - (b.order || 0))
593
+ };
594
+ }
595
+ catch (error) {
596
+ console.error(`Failed to enrich workflow "${wf.name}":`, error);
597
+ return { ...wf, prompts: [] };
598
+ }
599
+ }));
600
+ this.cachedWorkflows = enriched;
601
+ return enriched;
602
+ }
573
603
  /**
574
604
  * Write Claude Code skill files to ~/.claude/skills/secondbrainos/
575
605
  * Called on every server startup so skills stay in sync with SBOS.
@@ -616,37 +646,17 @@ class SecondBrainOSServer {
616
646
  console.error('Failed to write agent skill files:', error);
617
647
  }
618
648
  }
619
- // 3. workflows
649
+ // 3. workflows (uses cached enriched data)
620
650
  if (this.runPromptChainPath) {
621
651
  try {
622
- const data = await this.callRunPromptChain('', '');
623
- const workflows = data.workflows || [];
652
+ const workflows = await this.fetchAndEnrichWorkflows();
624
653
  for (const wf of workflows) {
625
- if (!wf.name || !wf.workflow_id)
626
- continue;
627
654
  const folderName = toSnakeCase(wf.name);
628
- const workflowDetail = await this.callRunPromptChain('workflow', wf.workflow_id);
629
- const promptIds = workflowDetail.prompt_id || [];
630
- const promptResults = await Promise.all(promptIds.map(async (promptId) => {
631
- try {
632
- const promptData = await this.callRunPromptChain('prompt', promptId);
633
- return {
634
- id: promptId,
635
- name: promptData.name,
636
- order: promptData.order,
637
- description: promptData.description || ''
638
- };
639
- }
640
- catch {
641
- return { id: promptId, name: '', order: 0, description: '' };
642
- }
643
- }));
644
- const sortedPrompts = promptResults.sort((a, b) => (a.order || 0) - (b.order || 0));
645
655
  const workflowDocument = {
646
656
  skill_id: wf.workflow_id,
647
657
  name: wf.name,
648
658
  description: wf.description || '',
649
- prompts: sortedPrompts
659
+ prompts: wf.prompts
650
660
  };
651
661
  writeSkill(path.join(skillsBase, 'workflows', folderName), `---\nname: secondbrainos_skill_${folderName}\ndescription: "${wf.description || wf.name}"\nuser-invocable: false\n---\n\n${JSON.stringify(workflowDocument, null, 2)}\n`);
652
662
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secondbrainos-mcp-server",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "Second Brain OS MCP Server for Claude Desktop",
5
5
  "type": "module",
6
6
  "main": "build/index.js",