secondbrainos-mcp-server 1.4.3 → 1.4.5
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/build/index.js +57 -49
- 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;
|
|
@@ -164,7 +165,8 @@ class SecondBrainOSServer {
|
|
|
164
165
|
// Better error handling with HttpLlm
|
|
165
166
|
if (axios.isAxiosError(error)) {
|
|
166
167
|
const status = error.response?.status;
|
|
167
|
-
const
|
|
168
|
+
const rawError = error.response?.data?.error || error.response?.data?.message || error.message;
|
|
169
|
+
const errorMessage = typeof rawError === 'object' ? JSON.stringify(rawError) : rawError;
|
|
168
170
|
let mcpError;
|
|
169
171
|
switch (status) {
|
|
170
172
|
case 401:
|
|
@@ -205,24 +207,17 @@ class SecondBrainOSServer {
|
|
|
205
207
|
// List available prompts (user's workflows + agents)
|
|
206
208
|
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
207
209
|
const prompts = [];
|
|
208
|
-
// Fetch workflows as prompts
|
|
210
|
+
// Fetch workflows as prompts (uses cached enriched data)
|
|
209
211
|
if (this.runPromptChainPath) {
|
|
210
212
|
try {
|
|
211
|
-
const
|
|
212
|
-
const workflows = data.workflows || [];
|
|
213
|
+
const workflows = await this.fetchAndEnrichWorkflows();
|
|
213
214
|
this.workflowNameToId.clear();
|
|
214
215
|
for (const wf of workflows) {
|
|
215
|
-
|
|
216
|
-
|
|
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)}`;
|
|
216
|
+
const snakeName = `skill_${toSnakeCase(wf.name)}`;
|
|
217
|
+
this.workflowNameToId.set(snakeName, wf.workflow_id);
|
|
223
218
|
prompts.push({
|
|
224
219
|
name: snakeName,
|
|
225
|
-
title: `[Skill] ${
|
|
220
|
+
title: `[Skill] ${wf.name}`,
|
|
226
221
|
description: wf.description || wf.name,
|
|
227
222
|
arguments: [
|
|
228
223
|
{
|
|
@@ -570,6 +565,42 @@ class SecondBrainOSServer {
|
|
|
570
565
|
this.cachedAgents = agents;
|
|
571
566
|
return agents;
|
|
572
567
|
}
|
|
568
|
+
async fetchAndEnrichWorkflows() {
|
|
569
|
+
if (this.cachedWorkflows)
|
|
570
|
+
return this.cachedWorkflows;
|
|
571
|
+
const data = await this.callRunPromptChain('', '');
|
|
572
|
+
const workflows = (data.workflows || []).filter((wf) => wf.name && wf.workflow_id);
|
|
573
|
+
const enriched = await Promise.all(workflows.map(async (wf) => {
|
|
574
|
+
try {
|
|
575
|
+
const workflowDetail = await this.callRunPromptChain('workflow', wf.workflow_id);
|
|
576
|
+
const promptIds = workflowDetail.prompt_id || [];
|
|
577
|
+
const promptResults = await Promise.all(promptIds.map(async (promptId) => {
|
|
578
|
+
try {
|
|
579
|
+
const promptData = await this.callRunPromptChain('prompt', promptId);
|
|
580
|
+
return {
|
|
581
|
+
id: promptId,
|
|
582
|
+
name: promptData.name,
|
|
583
|
+
order: promptData.order,
|
|
584
|
+
description: promptData.description || ''
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
catch {
|
|
588
|
+
return { id: promptId, name: '', order: 0, description: '' };
|
|
589
|
+
}
|
|
590
|
+
}));
|
|
591
|
+
return {
|
|
592
|
+
...wf,
|
|
593
|
+
prompts: promptResults.sort((a, b) => (a.order || 0) - (b.order || 0))
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
catch (error) {
|
|
597
|
+
console.error(`Failed to enrich workflow "${wf.name}":`, error);
|
|
598
|
+
return { ...wf, prompts: [] };
|
|
599
|
+
}
|
|
600
|
+
}));
|
|
601
|
+
this.cachedWorkflows = enriched;
|
|
602
|
+
return enriched;
|
|
603
|
+
}
|
|
573
604
|
/**
|
|
574
605
|
* Write Claude Code skill files to ~/.claude/skills/secondbrainos/
|
|
575
606
|
* Called on every server startup so skills stay in sync with SBOS.
|
|
@@ -616,46 +647,23 @@ class SecondBrainOSServer {
|
|
|
616
647
|
console.error('Failed to write agent skill files:', error);
|
|
617
648
|
}
|
|
618
649
|
}
|
|
619
|
-
// 3. workflows (
|
|
650
|
+
// 3. workflows (uses cached enriched data)
|
|
620
651
|
if (this.runPromptChainPath) {
|
|
621
652
|
try {
|
|
622
|
-
const
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
id: promptId,
|
|
634
|
-
name: promptData.name,
|
|
635
|
-
order: promptData.order,
|
|
636
|
-
description: promptData.description || ''
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
catch {
|
|
640
|
-
return { id: promptId, name: '', order: 0, description: '' };
|
|
641
|
-
}
|
|
642
|
-
}));
|
|
643
|
-
const sortedPrompts = promptResults.sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
644
|
-
const workflowDocument = {
|
|
645
|
-
skill_id: wf.workflow_id,
|
|
646
|
-
name: wf.name,
|
|
647
|
-
description: wf.description || '',
|
|
648
|
-
prompts: sortedPrompts
|
|
649
|
-
};
|
|
650
|
-
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`);
|
|
651
|
-
}
|
|
652
|
-
catch (error) {
|
|
653
|
-
console.error(`Failed to write skill file for workflow "${wf.name}":`, error);
|
|
654
|
-
}
|
|
655
|
-
}));
|
|
653
|
+
const workflows = await this.fetchAndEnrichWorkflows();
|
|
654
|
+
for (const wf of workflows) {
|
|
655
|
+
const folderName = toSnakeCase(wf.name);
|
|
656
|
+
const workflowDocument = {
|
|
657
|
+
skill_id: wf.workflow_id,
|
|
658
|
+
name: wf.name,
|
|
659
|
+
description: wf.description || '',
|
|
660
|
+
prompts: wf.prompts
|
|
661
|
+
};
|
|
662
|
+
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`);
|
|
663
|
+
}
|
|
656
664
|
}
|
|
657
665
|
catch (error) {
|
|
658
|
-
console.error('Failed to
|
|
666
|
+
console.error('Failed to write workflow skill files:', error);
|
|
659
667
|
}
|
|
660
668
|
}
|
|
661
669
|
// 4. knowledgebases
|