secondbrainos-mcp-server 1.4.8 → 1.5.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/build/index.js +40 -48
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -521,31 +521,37 @@ class SecondBrainOSServer {
521
521
  async fetchAndEnrichAgents() {
522
522
  if (this.cachedAgents)
523
523
  return this.cachedAgents;
524
- const data = await this.callGetAIAgentsSchema();
525
- const agents = data.agents || [];
526
- // Enrich each agent's workflows with full prompt details
524
+ // Fetch agents and all workflows in parallel
525
+ const [agentData, workflows] = await Promise.all([
526
+ this.callGetAIAgentsSchema(),
527
+ this.fetchAndEnrichWorkflows()
528
+ ]);
529
+ const agents = agentData.agents || [];
530
+ // Build a prompt lookup from the already-fetched workflows
531
+ const promptLookup = new Map();
532
+ for (const wf of workflows) {
533
+ for (const p of wf.prompts || []) {
534
+ promptLookup.set(p.id, p);
535
+ }
536
+ }
537
+ // Enrich agent workflows using the lookup — no extra API calls
527
538
  for (const agent of agents) {
528
539
  if (!agent.workflows)
529
540
  continue;
530
541
  for (const workflow of agent.workflows) {
531
542
  if (!workflow.prompts || workflow.prompts.length === 0)
532
543
  continue;
533
- // Fetch prompt metadata (name, order, description) — no instructions
534
- const enrichedPrompts = await Promise.all(workflow.prompts.map(async (prompt) => {
535
- try {
536
- const promptData = await this.callRunPromptChain('prompt', prompt.id);
537
- return {
538
- id: prompt.id,
539
- name: promptData.name || prompt.name,
540
- order: promptData.order,
541
- description: promptData.description || ''
542
- };
543
- }
544
- catch {
545
- return { id: prompt.id, name: prompt.name, order: 0, description: '' };
546
- }
547
- }));
548
- workflow.prompts = enrichedPrompts.sort((a, b) => (a.order || 0) - (b.order || 0));
544
+ workflow.prompts = workflow.prompts
545
+ .map((prompt) => {
546
+ const enriched = promptLookup.get(prompt.id);
547
+ return {
548
+ id: prompt.id,
549
+ name: enriched?.name || prompt.name,
550
+ order: enriched?.order || 0,
551
+ description: enriched?.description || ''
552
+ };
553
+ })
554
+ .sort((a, b) => (a.order || 0) - (b.order || 0));
549
555
  }
550
556
  }
551
557
  this.cachedAgents = agents;
@@ -554,35 +560,19 @@ class SecondBrainOSServer {
554
560
  async fetchAndEnrichWorkflows() {
555
561
  if (this.cachedWorkflows)
556
562
  return this.cachedWorkflows;
563
+ // Single API call — now returns all workflows with prompt metadata
557
564
  const data = await this.callRunPromptChain('', '');
558
565
  const workflows = (data.workflows || []).filter((wf) => wf.name && wf.workflow_id);
559
- const enriched = await Promise.all(workflows.map(async (wf) => {
560
- try {
561
- const workflowDetail = await this.callRunPromptChain('workflow', wf.workflow_id);
562
- const promptIds = workflowDetail.prompt_id || [];
563
- const promptResults = await Promise.all(promptIds.map(async (promptId) => {
564
- try {
565
- const promptData = await this.callRunPromptChain('prompt', promptId);
566
- return {
567
- id: promptId,
568
- name: promptData.name,
569
- order: promptData.order,
570
- description: promptData.description || ''
571
- };
572
- }
573
- catch {
574
- return { id: promptId, name: '', order: 0, description: '' };
575
- }
576
- }));
577
- return {
578
- ...wf,
579
- prompts: promptResults.sort((a, b) => (a.order || 0) - (b.order || 0))
580
- };
581
- }
582
- catch (error) {
583
- console.error(`Failed to enrich workflow "${wf.name}":`, error);
584
- return { ...wf, prompts: [] };
585
- }
566
+ const enriched = workflows.map((wf) => ({
567
+ ...wf,
568
+ prompts: (wf.prompts || [])
569
+ .map((p) => ({
570
+ id: p.prompt_id,
571
+ name: p.name || '',
572
+ order: p.order || 0,
573
+ description: p.description || ''
574
+ }))
575
+ .sort((a, b) => (a.order || 0) - (b.order || 0))
586
576
  }));
587
577
  this.cachedWorkflows = enriched;
588
578
  return enriched;
@@ -675,11 +665,13 @@ class SecondBrainOSServer {
675
665
  // This method is kept for future error handling implementations
676
666
  }
677
667
  async run() {
678
- // Write skill files before connecting so Claude Code sees them at session start
679
- await this.writeSkillFiles().catch(err => console.error('Failed to write skill files:', err));
680
668
  const transport = new StdioServerTransport();
681
669
  await this.server.connect(transport);
682
670
  console.error("Second Brain OS MCP server running on stdio");
671
+ // Write skill files AFTER connecting so the MCP handshake completes
672
+ // within Claude Code's 30s timeout. Skill files are written in the
673
+ // background — they'll be available for subsequent conversations.
674
+ this.writeSkillFiles().catch(err => console.error('Failed to write skill files:', err));
683
675
  }
684
676
  }
685
677
  SecondBrainOSServer.ALLOWED_EXTENSIONS = ['.txt', '.md'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secondbrainos-mcp-server",
3
- "version": "1.4.8",
3
+ "version": "1.5.0",
4
4
  "description": "Second Brain OS MCP Server for Claude Desktop",
5
5
  "type": "module",
6
6
  "main": "build/index.js",