feat: load global user-level skills and MCP servers#295
feat: load global user-level skills and MCP servers#295execsumo wants to merge 4 commits intoYishenTu:mainfrom
Conversation
Replace browser-based SDK transports (SSEClientTransport, StreamableHTTPClientTransport) with a custom NodeHttpTransport that uses Node.js native http/https modules. This bypasses CORS restrictions in Obsidian's Electron renderer, which sends Origin: app://obsidian.md with every request — an origin that MCP servers never whitelist. This affects all HTTP and SSE servers (local and remote), not just local ones. Stdio servers are unaffected. The 10-second timeout, custom header passthrough, and error handling behavior are all preserved.
- SkillStorage: load skills from ~/.claude/skills/ alongside vault skills (.claude/skills/). Vault skills take precedence on name collision. Global skills get id prefix 'skill-global-'. - McpStorage: load MCP servers from ~/.claude/settings.json alongside vault .claude/mcp.json. Vault servers take precedence on name collision. Restructured load() to isolate vault try/catch from global merge. - AgentManager already loads global agents from ~/.claude/agents - no changes needed. - Added unit tests for both global loading paths (5 new SkillStorage tests, 6 new McpStorage tests) with fs mocks.
i do think we already support global skill discovery. |
to be more precise, Claude Agent SDK is handling the skill discovery. we only parse what's inside vault/skills into the setting page. the consideration behind this design is that global skills usually contains coding-related skills, which is not suitable for obsidian operation. if you ask claudian, "list all your skills", you will see local as well as global skills are dicoverable. |
@YishenTu That's true for Agents and Plugins, but I think Skills and MCP were only loading from the directory for the Obsidian Vault ".claude", but not the global user directory "~/.claude". I verified this on two machines, a Windows PC and a Macbook Pro, and neither loaded the user-level Skills and MCPs. Maybe that was typo / vibe code slip and you wanted it to reference user-level configurations in ~/.claude for Skills, MCPs, Agents, and Plugins? I think having only user-level tools would work too if you want to keep the code simpler, but only having vault/project-level tools means users have to copy the tools between vaults if they want to use the same tools. |
ah ok, that makes sense. I'll go back to earlier version and try "list all your skills". Thanks Yishen. Love the tool, BTW. |
|
SDK is handling skill discoverability, and it follows Claude Code's pattern, loading from ~/.claude/skills/ and project/.claude/skills/ , it cant be turned off or modified. what we did is that in setting page, we list commands/skills in project/vault level, which is much more related to obsidian operation, to allow user to be able to modify them directly in the UI. for global skills (~/.claude/skills), just ask Claudian, "list all your skills" or "use this skills to do foo" , it can load them automatically without any settings. |
|
gotcha - maybe we can add a option in the settings to show or hide global tools 🤔 |
i do want to isolate vault and user skills/commands/agents to be seen and modified within Claudian, since vault operation is very different from coding/other tasks, however, you can use them without any changes, this is mostly SDK's behaviour. MCP on the other hand, since i dont use them very much, i have no tendency towards them. but the general principle is the same, user should be able to use it, but not touch it. |
SkillStorage: load skills from ~/.claude/skills/ alongside vault skills (.claude/skills/). Vault skills take precedence on name collision. Global skills get id prefix 'skill-global-'. Isolated vault-loading errors so global skills load even if the vault directory doesn't exist yet.
McpStorage: load MCP servers from ~/.claude/settings.json alongside vault .claude/mcp.json. Vault servers take precedence on name collision. Restructured load() to isolate vault try/catch from global merge.
AgentManager already loads global agents from ~/.claude/agents - no changes needed.
Added unit tests for both global loading paths (5 new SkillStorage tests, 6 new McpStorage tests) with fs mocks.