secondbrainos-mcp-server 1.5.2 → 1.5.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.
package/bin/cli.js CHANGED
@@ -362,6 +362,42 @@ async function main() {
362
362
  const cliPath = path.join(packageRoot, 'bin', 'cli.js');
363
363
  const claudeCodeConfigured = await configureClaudeCode(cliPath, nodePath);
364
364
 
365
+ // Add SessionStart hook to global Claude Code settings
366
+ if (claudeCodeConfigured) {
367
+ try {
368
+ const claudeSettingsPath = path.join(homedir(), '.claude', 'settings.json');
369
+ let settings = {};
370
+ try {
371
+ settings = JSON.parse(await fs.readFile(claudeSettingsPath, 'utf8'));
372
+ } catch { /* file may not exist yet */ }
373
+
374
+ if (!settings.hooks) settings.hooks = {};
375
+ if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
376
+
377
+ // Check if our hook already exists
378
+ const skillFilePath = path.join(homedir(), '.claude', 'skills', 'secondbrainos', 'server-use', 'SKILL.md');
379
+ const hookCommand = `cat "${skillFilePath}" 2>/dev/null || true`;
380
+ const hasHook = settings.hooks.SessionStart.some(
381
+ entry => entry.hooks && entry.hooks.some(h => h.command && h.command.includes('secondbrainos/server-use/SKILL.md'))
382
+ );
383
+
384
+ if (!hasHook) {
385
+ settings.hooks.SessionStart.push({
386
+ hooks: [
387
+ {
388
+ type: "command",
389
+ command: hookCommand
390
+ }
391
+ ]
392
+ });
393
+ await fs.writeFile(claudeSettingsPath, JSON.stringify(settings, null, 2));
394
+ console.log('SessionStart hook configured for SBOS context loading.');
395
+ }
396
+ } catch (error) {
397
+ console.log(`Note: Could not configure SessionStart hook: ${error.message}`);
398
+ }
399
+ }
400
+
365
401
  console.log('\nInstallation successful!');
366
402
  console.log('\nClaude Desktop:');
367
403
  console.log('1. Completely quit Claude Desktop if it is running');
package/build/index.js CHANGED
@@ -15,6 +15,12 @@ function toSnakeCase(str) {
15
15
  .replace(/[^a-z0-9]+/g, '_')
16
16
  .replace(/^_+|_+$/g, '');
17
17
  }
18
+ function toKebabCase(str) {
19
+ return str
20
+ .toLowerCase()
21
+ .replace(/[^a-z0-9]+/g, '-')
22
+ .replace(/^-+|-+$/g, '');
23
+ }
18
24
  class SecondBrainOSServer {
19
25
  constructor(initialSchema) {
20
26
  this.originalSpec = initialSchema;
@@ -584,8 +590,62 @@ class SecondBrainOSServer {
584
590
  fs.mkdirSync(dir, { recursive: true });
585
591
  fs.writeFileSync(path.join(dir, 'SKILL.md'), content, 'utf-8');
586
592
  };
587
- // 1. server-use — placeholder
588
- writeSkill(path.join(skillsBase, 'server-use'), `---\nname: secondbrainos_server_use\ndescription: Second Brain OS server context\nuser-invocable: false\n---\n\nHello world.\n`);
593
+ // 1. server-use — context document for Claude Code sessions
594
+ // Gather agent and workflow names for the index
595
+ let agentIndex = '';
596
+ let skillIndex = '';
597
+ try {
598
+ const agents = await this.fetchAndEnrichAgents();
599
+ agentIndex = agents
600
+ .filter((a) => a.name && a.id)
601
+ .map((a) => `- ${a.name} → \`/secondbrainos:agent_${toSnakeCase(a.name)}\``)
602
+ .join('\n');
603
+ }
604
+ catch { /* skip if unavailable */ }
605
+ try {
606
+ const workflows = await this.fetchAndEnrichWorkflows();
607
+ skillIndex = workflows
608
+ .filter((wf) => wf.name)
609
+ .map((wf) => `- ${wf.name} → \`/secondbrainos:skill_${toSnakeCase(wf.name)}\``)
610
+ .join('\n');
611
+ }
612
+ catch { /* skip if unavailable */ }
613
+ const serverUseContent = `---
614
+ name: server-use
615
+ description: Second Brain OS server context — terminology, architecture, and available agents/skills index
616
+ user-invocable: false
617
+ ---
618
+
619
+ # Second Brain OS — Server Context
620
+
621
+ ## Terminology
622
+ These terms are synonyms and used interchangeably in SBOS:
623
+ - **Tabs / Agents** — AI agents with behaviour, knowledge, tools, and skills
624
+ - **Services / Tools** — always MCP tools
625
+ - **Workflows / Skills** — a skill is a structured set of prompts, enabling optimised context per step so the agent can progress through a skill without overload
626
+
627
+ ## Agent Architecture
628
+ An agent definition combines:
629
+ 1. **Knowledge** — an obfuscated vector store collection ID for \`searchMyKnowledge\`
630
+ 2. **Services (Tools)** — the MCP tools the agent can use
631
+ 3. **Workflows (Skills)** — the prompt chains the agent follows
632
+
633
+ This means you can spin up sub-agents from an agent's skill definitions (see \`~/.claude/skills/secondbrainos/tabs/\`).
634
+
635
+ ## Accessing Agents & Skills
636
+ - Skill files live at \`~/.claude/skills/secondbrainos/\` (tabs/, workflows/, knowledge-bases/)
637
+ - All skill files are set to \`user-invocable: false\` to avoid duplicating slash commands already available via MCP prompts
638
+ - **Users** invoke agents or skills via slash commands (e.g. \`/secondbrainos:agent_...\` or \`/secondbrainos:skill_...\`)
639
+ - **Users** cannot invoke MCP tools directly via slash commands — they must ask you to load and call the relevant tool
640
+ - When using an agent with sub-agents, load the necessary skills at the start of the conversation by reading the agent's skill files
641
+
642
+ ## Available Agents
643
+ ${agentIndex || '_None configured_'}
644
+
645
+ ## Available Skills
646
+ ${skillIndex || '_None configured_'}
647
+ `;
648
+ writeSkill(path.join(skillsBase, 'server-use'), serverUseContent);
589
649
  // 2. tabs (agents)
590
650
  if (this.getAIAgentsSchemaPath) {
591
651
  try {
@@ -593,7 +653,7 @@ class SecondBrainOSServer {
593
653
  for (const agent of agents) {
594
654
  if (!agent.name || !agent.id)
595
655
  continue;
596
- const folderName = toSnakeCase(agent.name);
656
+ const folderName = toKebabCase(agent.name);
597
657
  const agentDocument = {
598
658
  agent_id: agent.id,
599
659
  name: agent.name,
@@ -612,7 +672,7 @@ class SecondBrainOSServer {
612
672
  }))
613
673
  }))
614
674
  };
615
- writeSkill(path.join(skillsBase, 'tabs', folderName), `---\nname: secondbrainos_agent_${folderName}\ndescription: "${agent.description || agent.name}"\nuser-invocable: false\n---\n\n${JSON.stringify(agentDocument, null, 2)}\n`);
675
+ writeSkill(path.join(skillsBase, 'tabs', folderName), `---\nname: ${folderName}\ndescription: "${agent.description || agent.name}"\nuser-invocable: false\n---\n\n${JSON.stringify(agentDocument, null, 2)}\n`);
616
676
  }
617
677
  }
618
678
  catch (error) {
@@ -624,14 +684,14 @@ class SecondBrainOSServer {
624
684
  try {
625
685
  const workflows = await this.fetchAndEnrichWorkflows();
626
686
  for (const wf of workflows) {
627
- const folderName = toSnakeCase(wf.name);
687
+ const folderName = toKebabCase(wf.name);
628
688
  const workflowDocument = {
629
689
  skill_id: wf.workflow_id,
630
690
  name: wf.name,
631
691
  description: wf.description || '',
632
692
  prompts: wf.prompts
633
693
  };
634
- 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`);
694
+ writeSkill(path.join(skillsBase, 'workflows', folderName), `---\nname: ${folderName}\ndescription: "${wf.description || wf.name}"\nuser-invocable: false\n---\n\n${JSON.stringify(workflowDocument, null, 2)}\n`);
635
695
  }
636
696
  }
637
697
  catch (error) {
@@ -647,7 +707,7 @@ class SecondBrainOSServer {
647
707
  .filter((id) => id && id.length > 0);
648
708
  if (collectionIds.length > 0) {
649
709
  const kbDocument = { searchMyKnowledge_collection_ids: collectionIds };
650
- writeSkill(path.join(skillsBase, 'knowledgebases'), `---\nname: secondbrainos_knowledge_bases\ndescription: Knowledge base collection IDs available to agents\nuser-invocable: false\n---\n\n${JSON.stringify(kbDocument, null, 2)}\n`);
710
+ writeSkill(path.join(skillsBase, 'knowledge-bases'), `---\nname: knowledge-bases\ndescription: Knowledge base collection IDs available to agents\nuser-invocable: false\n---\n\n${JSON.stringify(kbDocument, null, 2)}\n`);
651
711
  }
652
712
  }
653
713
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secondbrainos-mcp-server",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "Second Brain OS MCP Server for Claude Desktop",
5
5
  "type": "module",
6
6
  "main": "build/index.js",