@softspark/ai-toolkit 4.27.0 → 4.28.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.
- package/CHANGELOG.md +59 -0
- package/README.md +16 -19
- package/app/.claude-plugin/plugin.json +1 -1
- package/benchmarks/ecosystem-doctor-snapshot.json +11 -10
- package/kb/reference/global-install-model.md +5 -2
- package/kb/reference/mcp-editor-compatibility.md +27 -3
- package/kb/reference/mcp-templates.md +5 -3
- package/kb/reference/supported-tools-registry.md +4 -3
- package/llms-full.txt +41 -11
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/ecosystem_tools.json +9 -4
- package/scripts/mcp_editors.py +112 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,65 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v4.28.0 — MCP servers reach Chat and Cowork (2026-08-21)
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`claude-app` MCP adapter.** `ai-toolkit mcp install --editor claude-app
|
|
15
|
+
--scope global <template>` writes `claude_desktop_config.json` — macOS
|
|
16
|
+
`~/Library/Application Support/Claude/`, Windows `%APPDATA%/Claude/`, Linux
|
|
17
|
+
`~/.config/Claude/`, with `CLAUDE_USER_DATA_DIR` overriding the root the same
|
|
18
|
+
way the app itself honors it. Until now the Claude app was reachable only
|
|
19
|
+
through an uploaded plugin ZIP, so a user with seven MCP servers configured for
|
|
20
|
+
Claude Code still had an empty `mcpServers` block in Chat and Cowork. The app
|
|
21
|
+
parses this file on startup and reports invalid entries in its own warning
|
|
22
|
+
dialog, so it was always a supported surface — ai-toolkit just never wrote to
|
|
23
|
+
it. Note that `--editor claude` targets Claude Code (`.mcp.json`,
|
|
24
|
+
`~/.claude.json`); the two are different runtimes and different files.
|
|
25
|
+
- **HTTP and SSE templates are bridged through `mcp-remote`.** The app validates
|
|
26
|
+
each entry as `{command, args, env}`; remote endpoints live in a separate
|
|
27
|
+
`remoteMcpServers` surface managed from its Connectors UI and are not
|
|
28
|
+
file-configurable. Writing a portable `{"type":"http","url":…}` entry verbatim
|
|
29
|
+
would produce a config the app silently skips, so the adapter wraps remote
|
|
30
|
+
servers as `npx -y mcp-remote <url>`, forwarding `headers` as `--header`
|
|
31
|
+
arguments. `mcp-remote` negotiates the transport itself, so one bridge shape
|
|
32
|
+
covers both the `http` and `sse` spellings. This also applies to
|
|
33
|
+
`ai-toolkit inject-mcp`, which propagates to every editor exposing a global
|
|
34
|
+
path and therefore now reaches the Claude app too.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- `_resolve_global_config_root` gained a `_validate_configured_config_root`
|
|
39
|
+
helper, shared with the new adapter. `COPILOT_HOME` and `CODEX_HOME` keep
|
|
40
|
+
their existing semantics; the Claude app root is validated only when set
|
|
41
|
+
explicitly, because its platform default need not exist yet.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **Two docs described the `claude` adapter's config path wrongly.**
|
|
46
|
+
`kb/reference/mcp-editor-compatibility.md` and `kb/reference/mcp-templates.md`
|
|
47
|
+
both claimed it writes `.claude/settings.local.json` and
|
|
48
|
+
`~/.claude/settings.json`. It writes `.mcp.json` and `~/.claude.json`, and has
|
|
49
|
+
for as long as the adapter has existed. Both scopes were wrong in both files.
|
|
50
|
+
|
|
51
|
+
### Ecosystem
|
|
52
|
+
|
|
53
|
+
- `claude-app` gains three `config_paths`, the `scripts/mcp_editors.py`
|
|
54
|
+
generator, and an `MCP` capability marker. Re-baseline with
|
|
55
|
+
`python3 scripts/ecosystem_doctor.py --update --tool claude-app`.
|
|
56
|
+
|
|
57
|
+
### Tests
|
|
58
|
+
|
|
59
|
+
- 1645 → 1659. Thirteen cover the adapter (path resolution, parent-tree
|
|
60
|
+
creation, preservation of `preferences`/`coworkUserFilesPath`/user-owned
|
|
61
|
+
servers, byte-identical re-install, the bridge shape, rejection of entries
|
|
62
|
+
with neither or both transports, four `CLAUDE_USER_DATA_DIR` validation cases,
|
|
63
|
+
removal, and transactional rollback). One covers `inject-mcp` propagation,
|
|
64
|
+
where per-editor failures are downgraded to warnings and a regression would
|
|
65
|
+
otherwise be silent.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
10
69
|
## v4.27.0 — Doctor sees the Claude app plugin (2026-08-21)
|
|
11
70
|
|
|
12
71
|
### Added
|
package/README.md
CHANGED
|
@@ -6,25 +6,22 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](app/skills/)
|
|
8
8
|
[](app/agents/)
|
|
9
|
-
[](tests/)
|
|
10
10
|
|
|
11
|
-
## What's New in v4.
|
|
11
|
+
## What's New in v4.28.0
|
|
12
12
|
|
|
13
|
-
**v4.
|
|
13
|
+
**v4.28.0** gives Claude Chat and Cowork their MCP servers:
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
and the verification steps.
|
|
26
|
-
|
|
27
|
-
See [CHANGELOG.md](CHANGELOG.md) for full history.
|
|
15
|
+
- The Claude app parses `claude_desktop_config.json` on startup and reports bad
|
|
16
|
+
entries in its own warning dialog, but ai-toolkit never wrote to it. A user
|
|
17
|
+
with seven servers configured for Claude Code still had an empty `mcpServers`
|
|
18
|
+
block in Cowork.
|
|
19
|
+
- `ai-toolkit mcp install --editor claude-app --scope global <template>` now
|
|
20
|
+
writes it, on macOS, Windows, and Linux, honoring `CLAUDE_USER_DATA_DIR` the
|
|
21
|
+
way the app does. `--editor claude` remains Claude Code -- different runtime,
|
|
22
|
+
different file.
|
|
23
|
+
- The app accepts stdio entries only, so HTTP/SSE templates are bridged as
|
|
24
|
+
`npx -y mcp-remote <url>` rather than written verbatim and silently skipped.
|
|
28
25
|
|
|
29
26
|
## Table of Contents
|
|
30
27
|
|
|
@@ -143,7 +140,7 @@ See [CLI Reference](kb/reference/cli-reference.md) for all commands and options.
|
|
|
143
140
|
| Platform | Config Files | Hooks | Scope |
|
|
144
141
|
|----------|-------------|:-----:|-------|
|
|
145
142
|
| Claude Code | `~/.claude/agents`, `~/.claude/skills`, `~/.claude/rules/*.md`, `~/.claude/settings.json` | ✅ | global |
|
|
146
|
-
| Claude Chat / Cowork | uploaded plugin ZIP + UI global/folder instructions | Cowork only | account/app |
|
|
143
|
+
| Claude Chat / Cowork | uploaded plugin ZIP + UI global/folder instructions + `claude_desktop_config.json` (MCP) | Cowork only | account/app |
|
|
147
144
|
| Cursor | `.cursor/rules/*.mdc` + `.cursor/mcp.json` + `.cursor/skills/*` | ✅ | project (`~/.cursor/mcp.json` for MCP only) |
|
|
148
145
|
| Windsurf (Devin Desktop) | `~/.config/devin/AGENTS.md` + `.devin/rules/*.md` + `.devin/hooks.v1.json` + `.windsurf/skills/*` | ✅ | global + project |
|
|
149
146
|
| Gemini CLI | `~/.gemini/GEMINI.md` + `.gemini/settings.json` + `.gemini/{commands,skills,agents}/` | ✅ | project + user |
|
|
@@ -156,7 +153,7 @@ See [CLI Reference](kb/reference/cli-reference.md) for all commands and options.
|
|
|
156
153
|
| Codex CLI | Project: `AGENTS.md` + `.agents/skills/*` + `.codex/{agents,hooks}/` + `.codex/{hooks.json,config.toml}`; user: `$CODEX_HOME/{AGENTS.md,agents,hooks.json,config.toml}` + `$HOME/.agents/skills/*` | ✅ | project + user |
|
|
157
154
|
| opencode | `AGENTS.md` + `.opencode/{agents,commands,plugins,skills}/*` + `opencode.{json,jsonc}` | ✅ | project + global (`~/.config/opencode/`) |
|
|
158
155
|
|
|
159
|
-
> Claude Code is always installed (primary platform). Other editors are selected with `--editors`; the Claude app uses the separate `claude-app export` flow because its customization store is UI/plugin-managed. The **Hooks** column marks platforms with lifecycle enforcement. Platforms marked — receive guidance without blocking hooks.
|
|
156
|
+
> Claude Code is always installed (primary platform). Other editors are selected with `--editors`; the Claude app uses the separate `claude-app export` flow because its customization store is UI/plugin-managed, except for MCP servers, which `ai-toolkit mcp install --editor claude-app --scope global` writes straight to `claude_desktop_config.json`. The **Hooks** column marks platforms with lifecycle enforcement. Platforms marked — receive guidance without blocking hooks.
|
|
160
157
|
|
|
161
158
|
---
|
|
162
159
|
|
|
@@ -192,7 +189,7 @@ ai-toolkit/
|
|
|
192
189
|
│ └── ARCHITECTURE.md # Full system design
|
|
193
190
|
├── kb/ # Reference docs, procedures, plans
|
|
194
191
|
├── scripts/ # Validation, install, evaluation scripts
|
|
195
|
-
├── tests/ # Bats and Python test suite (
|
|
192
|
+
├── tests/ # Bats and Python test suite (1659 tests)
|
|
196
193
|
└── CHANGELOG.md
|
|
197
194
|
```
|
|
198
195
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "ai-toolkit",
|
|
4
4
|
"displayName": "AI Toolkit",
|
|
5
5
|
"description": "Professional-grade engineering skills, agents, rules, and lifecycle guardrails for Claude Code, Claude Chat, and Cowork.",
|
|
6
|
-
"version": "4.
|
|
6
|
+
"version": "4.28.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "SoftSpark",
|
|
9
9
|
"url": "https://github.com/softspark"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"last_run": "2026-08-
|
|
2
|
+
"last_run": "2026-08-21T18:54:11Z",
|
|
3
3
|
"schema_version": 1,
|
|
4
4
|
"tools": {
|
|
5
5
|
"aider": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"augment": {
|
|
27
|
-
"docs_hash": "
|
|
27
|
+
"docs_hash": "fda8f5ca2c114b30",
|
|
28
28
|
"headings": [
|
|
29
29
|
"Admin",
|
|
30
30
|
"Auggie CLI",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"claude-app": {
|
|
69
|
-
"docs_hash": "
|
|
69
|
+
"docs_hash": "73b44d89c7b771d9",
|
|
70
70
|
"headings": [
|
|
71
71
|
"Add global and folder instructions",
|
|
72
72
|
"Availability",
|
|
@@ -101,13 +101,14 @@
|
|
|
101
101
|
"markers": {
|
|
102
102
|
"Folder instructions": true,
|
|
103
103
|
"Global instructions": true,
|
|
104
|
+
"MCP": true,
|
|
104
105
|
"plugins": true,
|
|
105
106
|
"skills": true,
|
|
106
107
|
"sub-agents": true
|
|
107
108
|
}
|
|
108
109
|
},
|
|
109
110
|
"claude-code": {
|
|
110
|
-
"docs_hash": "
|
|
111
|
+
"docs_hash": "1666675fbb24aaad",
|
|
111
112
|
"headings": [
|
|
112
113
|
"Core concepts",
|
|
113
114
|
"Documentation Index",
|
|
@@ -176,7 +177,7 @@
|
|
|
176
177
|
"version": "2.1.238 (Claude Code)"
|
|
177
178
|
},
|
|
178
179
|
"cline": {
|
|
179
|
-
"docs_hash": "
|
|
180
|
+
"docs_hash": "a0753bb220f610ba",
|
|
180
181
|
"headings": [
|
|
181
182
|
"API Reference",
|
|
182
183
|
"Best Practices",
|
|
@@ -223,7 +224,7 @@
|
|
|
223
224
|
}
|
|
224
225
|
},
|
|
225
226
|
"codex-cli": {
|
|
226
|
-
"docs_hash": "
|
|
227
|
+
"docs_hash": "61d85bae5c0cf885",
|
|
227
228
|
"headings": [
|
|
228
229
|
"API",
|
|
229
230
|
"API Reference",
|
|
@@ -365,7 +366,7 @@
|
|
|
365
366
|
"version": "codex-cli 0.148.0"
|
|
366
367
|
},
|
|
367
368
|
"cursor": {
|
|
368
|
-
"docs_hash": "
|
|
369
|
+
"docs_hash": "189e666436c73107",
|
|
369
370
|
"headings": [
|
|
370
371
|
"Agent",
|
|
371
372
|
"CLI",
|
|
@@ -397,7 +398,7 @@
|
|
|
397
398
|
}
|
|
398
399
|
},
|
|
399
400
|
"gemini-cli": {
|
|
400
|
-
"docs_hash": "
|
|
401
|
+
"docs_hash": "547969f433375d0c",
|
|
401
402
|
"headings": [
|
|
402
403
|
"Breadcrumbs",
|
|
403
404
|
"Directory actions",
|
|
@@ -438,7 +439,7 @@
|
|
|
438
439
|
"version": "0.55.1"
|
|
439
440
|
},
|
|
440
441
|
"github-copilot": {
|
|
441
|
-
"docs_hash": "
|
|
442
|
+
"docs_hash": "a313606be316fada",
|
|
442
443
|
"headings": [
|
|
443
444
|
"About Copilot auto model selection",
|
|
444
445
|
"About Copilot automations",
|
|
@@ -564,7 +565,7 @@
|
|
|
564
565
|
}
|
|
565
566
|
},
|
|
566
567
|
"windsurf": {
|
|
567
|
-
"docs_hash": "
|
|
568
|
+
"docs_hash": "8bf9d2e8b6d36350",
|
|
568
569
|
"headings": [
|
|
569
570
|
"Accounts",
|
|
570
571
|
"Advanced",
|
|
@@ -26,8 +26,11 @@ active `CODEX_HOME` (default `~/.codex`) and shared user skills use
|
|
|
26
26
|
Codex user surface.
|
|
27
27
|
|
|
28
28
|
Claude Chat/Desktop/Cowork is a separate runtime. It does not read the
|
|
29
|
-
filesystem surfaces under `~/.claude`; it receives ai-toolkit
|
|
30
|
-
uploaded plugin plus app-managed global/folder
|
|
29
|
+
filesystem surfaces under `~/.claude`; it receives ai-toolkit skills, agents,
|
|
30
|
+
hooks, and rules through an uploaded plugin plus app-managed global/folder
|
|
31
|
+
instructions. Its one file-based surface is `claude_desktop_config.json`, which
|
|
32
|
+
the app parses for local MCP servers -- `ai-toolkit mcp install --editor
|
|
33
|
+
claude-app --scope global` targets it directly, without a plugin.
|
|
31
34
|
|
|
32
35
|
## Command Responsibilities
|
|
33
36
|
|
|
@@ -3,9 +3,9 @@ title: "AI Toolkit - MCP Editor Compatibility"
|
|
|
3
3
|
category: reference
|
|
4
4
|
service: ai-toolkit
|
|
5
5
|
tags: [mcp, editors, compatibility, codex, cursor, antigravity]
|
|
6
|
-
version: "1.
|
|
6
|
+
version: "1.4.0"
|
|
7
7
|
created: "2026-04-12"
|
|
8
|
-
last_updated: "2026-08-
|
|
8
|
+
last_updated: "2026-08-21"
|
|
9
9
|
description: "Official MCP support matrix and native config targets for editors supported by ai-toolkit."
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -19,7 +19,8 @@ ai-toolkit keeps `.mcp.json` as the project-level canonical template format and
|
|
|
19
19
|
|
|
20
20
|
| Editor | Scope | Native Config Path | Adapter Behavior |
|
|
21
21
|
|--------|-------|--------------------|------------------|
|
|
22
|
-
| Claude Code | project + global | `.
|
|
22
|
+
| Claude Code | project + global | `.mcp.json`, `~/.claude.json` | Merges `mcpServers` while preserving other top-level keys |
|
|
23
|
+
| Claude Chat / Cowork | global | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%/Claude/claude_desktop_config.json` (Windows), `~/.config/Claude/claude_desktop_config.json` (Linux); `CLAUDE_USER_DATA_DIR` overrides the root | Emits the app's stdio-only `{command, args, env}` schema and bridges HTTP/SSE servers through `mcp-remote`; preserves `preferences`, `coworkUserFilesPath`, and user-owned servers |
|
|
23
24
|
| Cursor | project + global | `.cursor/mcp.json`, `~/.cursor/mcp.json` | Mirrors `mcpServers` directly |
|
|
24
25
|
| GitHub Copilot | project + global | `.github/mcp.json`, `$COPILOT_HOME/mcp-config.json` (default `~/.copilot/mcp-config.json`) | Adds Copilot-required `type` and `tools` fields |
|
|
25
26
|
| Gemini CLI | project + global | `.gemini/settings.json`, `~/.gemini/settings.json` | Merges `mcpServers` into settings JSON |
|
|
@@ -46,9 +47,32 @@ ai-toolkit mcp install --editor cursor --scope project github --target .
|
|
|
46
47
|
ai-toolkit mcp install --editor antigravity --scope project context7 --target .
|
|
47
48
|
ai-toolkit mcp install --editor codex --scope project context7 --target .
|
|
48
49
|
ai-toolkit mcp install --editor codex context7
|
|
50
|
+
ai-toolkit mcp install --editor claude-app --scope global context7
|
|
49
51
|
ai-toolkit mcp remove github --editor cursor --scope project --target .
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
## Claude Chat / Cowork
|
|
55
|
+
|
|
56
|
+
The Claude app is the one target whose MCP surface is file-based while everything
|
|
57
|
+
else about it is not. Skills, agents, hooks, and rules reach Chat/Cowork only
|
|
58
|
+
through the uploaded plugin ZIP (`ai-toolkit claude-app export`), because the app
|
|
59
|
+
scans no filesystem location for them. Local MCP servers are different: the app
|
|
60
|
+
parses `claude_desktop_config.json` on startup and reports invalid entries in its
|
|
61
|
+
own warning dialog.
|
|
62
|
+
|
|
63
|
+
Two constraints shape the adapter:
|
|
64
|
+
|
|
65
|
+
- **stdio only.** Each entry is validated as `{command, args, env}`. Remote
|
|
66
|
+
endpoints live in a separate `remoteMcpServers` surface that the app manages
|
|
67
|
+
through its Connectors UI and does not read from this file. Portable HTTP/SSE
|
|
68
|
+
templates are therefore wrapped in `mcp-remote`, which negotiates the transport
|
|
69
|
+
itself, so one bridge shape covers both spellings.
|
|
70
|
+
- **The file is not ours.** It also holds `preferences` and `coworkUserFilesPath`,
|
|
71
|
+
which the app rewrites on its own. The adapter merges only `mcpServers` and
|
|
72
|
+
leaves every other key untouched.
|
|
73
|
+
|
|
74
|
+
The app must be restarted for a config change to take effect.
|
|
75
|
+
|
|
52
76
|
## Install Flow Integration
|
|
53
77
|
|
|
54
78
|
When `.mcp.json` exists in a project, `ai-toolkit install --local` mirrors its servers into:
|
|
@@ -3,9 +3,9 @@ title: "MCP Server Templates"
|
|
|
3
3
|
category: reference
|
|
4
4
|
service: ai-toolkit
|
|
5
5
|
tags: [mcp, templates, servers, configuration, editors, inject-mcp, external-templates]
|
|
6
|
-
version: "1.
|
|
6
|
+
version: "1.5.0"
|
|
7
7
|
created: "2026-04-07"
|
|
8
|
-
last_updated: "2026-08-
|
|
8
|
+
last_updated: "2026-08-21"
|
|
9
9
|
description: "Reference for 26 built-in MCP server templates, external template injection via inject-mcp, and native editor MCP installation support."
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -39,6 +39,7 @@ The `add` command merges the `mcpServers` block from the template into `.mcp.jso
|
|
|
39
39
|
The `install` command renders the same canonical template into an editor-native config format:
|
|
40
40
|
- JSON clients with `mcpServers` blocks: Claude Code, Cursor, Gemini CLI, Google Antigravity, Roo Code, Windsurf, Cline, Augment
|
|
41
41
|
- JSON clients with additional transport metadata: GitHub Copilot
|
|
42
|
+
- JSON clients restricted to stdio: Claude Chat/Cowork (`claude-app`) -- remote servers are bridged through `mcp-remote`
|
|
42
43
|
- TOML clients: Codex CLI (`[mcp_servers.<name>]`)
|
|
43
44
|
|
|
44
45
|
When `install` runs with `--scope project`, ai-toolkit also updates the project's `.mcp.json` so it remains the source of truth for later syncs.
|
|
@@ -47,7 +48,8 @@ When `install` runs with `--scope project`, ai-toolkit also updates the project'
|
|
|
47
48
|
|
|
48
49
|
| Editor | Scope | Native Config Path | Notes |
|
|
49
50
|
|--------|-------|--------------------|-------|
|
|
50
|
-
| `claude` | project + global | `.
|
|
51
|
+
| `claude` | project + global | `.mcp.json`, `~/.claude.json` | Preserves unrelated top-level keys |
|
|
52
|
+
| `claude-app` | global | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%/Claude/claude_desktop_config.json` (Windows), `~/.config/Claude/claude_desktop_config.json` (Linux) | Claude Chat/Cowork; stdio-only schema, bridges HTTP/SSE through `mcp-remote`, preserves `preferences` and `coworkUserFilesPath`; `CLAUDE_USER_DATA_DIR` overrides the root |
|
|
51
53
|
| `cursor` | project + global | `.cursor/mcp.json`, `~/.cursor/mcp.json` | Mirrors canonical `mcpServers` |
|
|
52
54
|
| `copilot` | project + global | `.github/mcp.json`, `$COPILOT_HOME/mcp-config.json` (default `~/.copilot/mcp-config.json`) | Adds `type` and `tools: ["*"]` automatically |
|
|
53
55
|
| `gemini` | project + global | `.gemini/settings.json`, `~/.gemini/settings.json` | Uses Gemini CLI `mcpServers` format |
|
|
@@ -49,11 +49,12 @@ The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed b
|
|
|
49
49
|
| ID | `claude-app` |
|
|
50
50
|
| Docs | https://support.claude.com/en/articles/13345190-get-started-with-claude-cowork |
|
|
51
51
|
| Plugin docs | https://support.claude.com/en/articles/13837440-use-plugins-in-claude |
|
|
52
|
-
| Config surfaces | `Settings > Cowork > Global instructions`, Cowork folder instructions, `Customize > Skills`,
|
|
52
|
+
| Config surfaces | `Settings > Cowork > Global instructions`, Cowork folder instructions, `Customize > Skills`, `Customize > Plugins`, plus the one file-based surface: `claude_desktop_config.json` (macOS `~/Library/Application Support/Claude/`, Windows `%APPDATA%/Claude/`, Linux `~/.config/Claude/`; `CLAUDE_USER_DATA_DIR` overrides the root) |
|
|
53
53
|
| Plugin layout | `.claude-plugin/plugin.json`, `skills/*/SKILL.md`, `agents/*.md`, `hooks/hooks.json`; ai-toolkit uses manifest paths under `claude-app/` for its generated app-only rules and hooks |
|
|
54
|
-
| Our generator | `scripts/claude_app.py` (`ai-toolkit claude-app export`) |
|
|
54
|
+
| Our generator | `scripts/claude_app.py` (`ai-toolkit claude-app export`); `scripts/mcp_editors.py` for the `claude-app` MCP adapter |
|
|
55
55
|
| Runtime split | Skills work in Chat (web/Desktop) and Cowork. Hooks and sub-agents run only in Cowork. Claude app does **not** scan Claude Code's `~/.claude/rules/`, `CLAUDE.md`, or `~/.claude/settings.json`. |
|
|
56
|
-
|
|
|
56
|
+
| MCP | `ai-toolkit mcp install --editor claude-app --scope global <template>` writes `claude_desktop_config.json` directly -- no plugin involved. Entries are validated by the app as `{command, args, env}`; remote endpoints belong to the separate UI-managed `remoteMcpServers` surface, so HTTP/SSE templates are bridged through `mcp-remote`. Restart the app to load a change. |
|
|
57
|
+
| Install/update | Export the ZIP, upload it from `Customize > Plugins`, then paste the generated global-instructions file into `Settings > Cowork > Global instructions`. Re-export/re-upload after toolkit updates. MCP config is the exception -- it updates from the CLI like any other editor. |
|
|
57
58
|
|
|
58
59
|
---
|
|
59
60
|
|
package/llms-full.txt
CHANGED
|
@@ -11730,8 +11730,11 @@ active `CODEX_HOME` (default `~/.codex`) and shared user skills use
|
|
|
11730
11730
|
Codex user surface.
|
|
11731
11731
|
|
|
11732
11732
|
Claude Chat/Desktop/Cowork is a separate runtime. It does not read the
|
|
11733
|
-
filesystem surfaces under `~/.claude`; it receives ai-toolkit
|
|
11734
|
-
uploaded plugin plus app-managed global/folder
|
|
11733
|
+
filesystem surfaces under `~/.claude`; it receives ai-toolkit skills, agents,
|
|
11734
|
+
hooks, and rules through an uploaded plugin plus app-managed global/folder
|
|
11735
|
+
instructions. Its one file-based surface is `claude_desktop_config.json`, which
|
|
11736
|
+
the app parses for local MCP servers -- `ai-toolkit mcp install --editor
|
|
11737
|
+
claude-app --scope global` targets it directly, without a plugin.
|
|
11735
11738
|
|
|
11736
11739
|
## Command Responsibilities
|
|
11737
11740
|
|
|
@@ -13532,9 +13535,9 @@ title: "AI Toolkit - MCP Editor Compatibility"
|
|
|
13532
13535
|
category: reference
|
|
13533
13536
|
service: ai-toolkit
|
|
13534
13537
|
tags: [mcp, editors, compatibility, codex, cursor, antigravity]
|
|
13535
|
-
version: "1.
|
|
13538
|
+
version: "1.4.0"
|
|
13536
13539
|
created: "2026-04-12"
|
|
13537
|
-
last_updated: "2026-08-
|
|
13540
|
+
last_updated: "2026-08-21"
|
|
13538
13541
|
description: "Official MCP support matrix and native config targets for editors supported by ai-toolkit."
|
|
13539
13542
|
---
|
|
13540
13543
|
|
|
@@ -13548,7 +13551,8 @@ ai-toolkit keeps `.mcp.json` as the project-level canonical template format and
|
|
|
13548
13551
|
|
|
13549
13552
|
| Editor | Scope | Native Config Path | Adapter Behavior |
|
|
13550
13553
|
|--------|-------|--------------------|------------------|
|
|
13551
|
-
| Claude Code | project + global | `.
|
|
13554
|
+
| Claude Code | project + global | `.mcp.json`, `~/.claude.json` | Merges `mcpServers` while preserving other top-level keys |
|
|
13555
|
+
| Claude Chat / Cowork | global | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%/Claude/claude_desktop_config.json` (Windows), `~/.config/Claude/claude_desktop_config.json` (Linux); `CLAUDE_USER_DATA_DIR` overrides the root | Emits the app's stdio-only `{command, args, env}` schema and bridges HTTP/SSE servers through `mcp-remote`; preserves `preferences`, `coworkUserFilesPath`, and user-owned servers |
|
|
13552
13556
|
| Cursor | project + global | `.cursor/mcp.json`, `~/.cursor/mcp.json` | Mirrors `mcpServers` directly |
|
|
13553
13557
|
| GitHub Copilot | project + global | `.github/mcp.json`, `$COPILOT_HOME/mcp-config.json` (default `~/.copilot/mcp-config.json`) | Adds Copilot-required `type` and `tools` fields |
|
|
13554
13558
|
| Gemini CLI | project + global | `.gemini/settings.json`, `~/.gemini/settings.json` | Merges `mcpServers` into settings JSON |
|
|
@@ -13575,9 +13579,32 @@ ai-toolkit mcp install --editor cursor --scope project github --target .
|
|
|
13575
13579
|
ai-toolkit mcp install --editor antigravity --scope project context7 --target .
|
|
13576
13580
|
ai-toolkit mcp install --editor codex --scope project context7 --target .
|
|
13577
13581
|
ai-toolkit mcp install --editor codex context7
|
|
13582
|
+
ai-toolkit mcp install --editor claude-app --scope global context7
|
|
13578
13583
|
ai-toolkit mcp remove github --editor cursor --scope project --target .
|
|
13579
13584
|
```
|
|
13580
13585
|
|
|
13586
|
+
## Claude Chat / Cowork
|
|
13587
|
+
|
|
13588
|
+
The Claude app is the one target whose MCP surface is file-based while everything
|
|
13589
|
+
else about it is not. Skills, agents, hooks, and rules reach Chat/Cowork only
|
|
13590
|
+
through the uploaded plugin ZIP (`ai-toolkit claude-app export`), because the app
|
|
13591
|
+
scans no filesystem location for them. Local MCP servers are different: the app
|
|
13592
|
+
parses `claude_desktop_config.json` on startup and reports invalid entries in its
|
|
13593
|
+
own warning dialog.
|
|
13594
|
+
|
|
13595
|
+
Two constraints shape the adapter:
|
|
13596
|
+
|
|
13597
|
+
- **stdio only.** Each entry is validated as `{command, args, env}`. Remote
|
|
13598
|
+
endpoints live in a separate `remoteMcpServers` surface that the app manages
|
|
13599
|
+
through its Connectors UI and does not read from this file. Portable HTTP/SSE
|
|
13600
|
+
templates are therefore wrapped in `mcp-remote`, which negotiates the transport
|
|
13601
|
+
itself, so one bridge shape covers both spellings.
|
|
13602
|
+
- **The file is not ours.** It also holds `preferences` and `coworkUserFilesPath`,
|
|
13603
|
+
which the app rewrites on its own. The adapter merges only `mcpServers` and
|
|
13604
|
+
leaves every other key untouched.
|
|
13605
|
+
|
|
13606
|
+
The app must be restarted for a config change to take effect.
|
|
13607
|
+
|
|
13581
13608
|
## Install Flow Integration
|
|
13582
13609
|
|
|
13583
13610
|
When `.mcp.json` exists in a project, `ai-toolkit install --local` mirrors its servers into:
|
|
@@ -13621,9 +13648,9 @@ title: "MCP Server Templates"
|
|
|
13621
13648
|
category: reference
|
|
13622
13649
|
service: ai-toolkit
|
|
13623
13650
|
tags: [mcp, templates, servers, configuration, editors, inject-mcp, external-templates]
|
|
13624
|
-
version: "1.
|
|
13651
|
+
version: "1.5.0"
|
|
13625
13652
|
created: "2026-04-07"
|
|
13626
|
-
last_updated: "2026-08-
|
|
13653
|
+
last_updated: "2026-08-21"
|
|
13627
13654
|
description: "Reference for 26 built-in MCP server templates, external template injection via inject-mcp, and native editor MCP installation support."
|
|
13628
13655
|
---
|
|
13629
13656
|
|
|
@@ -13657,6 +13684,7 @@ The `add` command merges the `mcpServers` block from the template into `.mcp.jso
|
|
|
13657
13684
|
The `install` command renders the same canonical template into an editor-native config format:
|
|
13658
13685
|
- JSON clients with `mcpServers` blocks: Claude Code, Cursor, Gemini CLI, Google Antigravity, Roo Code, Windsurf, Cline, Augment
|
|
13659
13686
|
- JSON clients with additional transport metadata: GitHub Copilot
|
|
13687
|
+
- JSON clients restricted to stdio: Claude Chat/Cowork (`claude-app`) -- remote servers are bridged through `mcp-remote`
|
|
13660
13688
|
- TOML clients: Codex CLI (`[mcp_servers.<name>]`)
|
|
13661
13689
|
|
|
13662
13690
|
When `install` runs with `--scope project`, ai-toolkit also updates the project's `.mcp.json` so it remains the source of truth for later syncs.
|
|
@@ -13665,7 +13693,8 @@ When `install` runs with `--scope project`, ai-toolkit also updates the project'
|
|
|
13665
13693
|
|
|
13666
13694
|
| Editor | Scope | Native Config Path | Notes |
|
|
13667
13695
|
|--------|-------|--------------------|-------|
|
|
13668
|
-
| `claude` | project + global | `.
|
|
13696
|
+
| `claude` | project + global | `.mcp.json`, `~/.claude.json` | Preserves unrelated top-level keys |
|
|
13697
|
+
| `claude-app` | global | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%/Claude/claude_desktop_config.json` (Windows), `~/.config/Claude/claude_desktop_config.json` (Linux) | Claude Chat/Cowork; stdio-only schema, bridges HTTP/SSE through `mcp-remote`, preserves `preferences` and `coworkUserFilesPath`; `CLAUDE_USER_DATA_DIR` overrides the root |
|
|
13669
13698
|
| `cursor` | project + global | `.cursor/mcp.json`, `~/.cursor/mcp.json` | Mirrors canonical `mcpServers` |
|
|
13670
13699
|
| `copilot` | project + global | `.github/mcp.json`, `$COPILOT_HOME/mcp-config.json` (default `~/.copilot/mcp-config.json`) | Adds `type` and `tools: ["*"]` automatically |
|
|
13671
13700
|
| `gemini` | project + global | `.gemini/settings.json`, `~/.gemini/settings.json` | Uses Gemini CLI `mcpServers` format |
|
|
@@ -15491,11 +15520,12 @@ The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed b
|
|
|
15491
15520
|
| ID | `claude-app` |
|
|
15492
15521
|
| Docs | https://support.claude.com/en/articles/13345190-get-started-with-claude-cowork |
|
|
15493
15522
|
| Plugin docs | https://support.claude.com/en/articles/13837440-use-plugins-in-claude |
|
|
15494
|
-
| Config surfaces | `Settings > Cowork > Global instructions`, Cowork folder instructions, `Customize > Skills`,
|
|
15523
|
+
| Config surfaces | `Settings > Cowork > Global instructions`, Cowork folder instructions, `Customize > Skills`, `Customize > Plugins`, plus the one file-based surface: `claude_desktop_config.json` (macOS `~/Library/Application Support/Claude/`, Windows `%APPDATA%/Claude/`, Linux `~/.config/Claude/`; `CLAUDE_USER_DATA_DIR` overrides the root) |
|
|
15495
15524
|
| Plugin layout | `.claude-plugin/plugin.json`, `skills/*/SKILL.md`, `agents/*.md`, `hooks/hooks.json`; ai-toolkit uses manifest paths under `claude-app/` for its generated app-only rules and hooks |
|
|
15496
|
-
| Our generator | `scripts/claude_app.py` (`ai-toolkit claude-app export`) |
|
|
15525
|
+
| Our generator | `scripts/claude_app.py` (`ai-toolkit claude-app export`); `scripts/mcp_editors.py` for the `claude-app` MCP adapter |
|
|
15497
15526
|
| Runtime split | Skills work in Chat (web/Desktop) and Cowork. Hooks and sub-agents run only in Cowork. Claude app does **not** scan Claude Code's `~/.claude/rules/`, `CLAUDE.md`, or `~/.claude/settings.json`. |
|
|
15498
|
-
|
|
|
15527
|
+
| MCP | `ai-toolkit mcp install --editor claude-app --scope global <template>` writes `claude_desktop_config.json` directly -- no plugin involved. Entries are validated by the app as `{command, args, env}`; remote endpoints belong to the separate UI-managed `remoteMcpServers` surface, so HTTP/SSE templates are bridged through `mcp-remote`. Restart the app to load a change. |
|
|
15528
|
+
| Install/update | Export the ZIP, upload it from `Customize > Plugins`, then paste the generated global-instructions file into `Settings > Cowork > Global instructions`. Re-export/re-upload after toolkit updates. MCP config is the exception -- it updates from the CLI like any other editor. |
|
|
15499
15529
|
|
|
15500
15530
|
---
|
|
15501
15531
|
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softspark/ai-toolkit",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.28.0",
|
|
4
4
|
"description": "AI coding toolkit: 109 skills, 44 agents, 12 developer-tool integrations, recoverable native tool-output filtering, Claude Chat/Cowork export, safety constitution, SARIF audit, and signed npm provenance.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -110,18 +110,23 @@
|
|
|
110
110
|
"UI: Customize > Plugins",
|
|
111
111
|
".claude-plugin/plugin.json",
|
|
112
112
|
"claude-app/hooks/hooks.json",
|
|
113
|
-
"claude-app/skills/*/SKILL.md"
|
|
113
|
+
"claude-app/skills/*/SKILL.md",
|
|
114
|
+
"~/Library/Application Support/Claude/claude_desktop_config.json",
|
|
115
|
+
"%APPDATA%/Claude/claude_desktop_config.json",
|
|
116
|
+
"~/.config/Claude/claude_desktop_config.json"
|
|
114
117
|
],
|
|
115
118
|
"our_generators": [
|
|
116
|
-
"scripts/claude_app.py"
|
|
119
|
+
"scripts/claude_app.py",
|
|
120
|
+
"scripts/mcp_editors.py"
|
|
117
121
|
],
|
|
118
|
-
"status_note": "Claude Chat/Desktop/Cowork does not scan ~/.claude/rules, CLAUDE.md, or Claude Code's user settings
|
|
122
|
+
"status_note": "Claude Chat/Desktop/Cowork does not scan ~/.claude/rules, CLAUDE.md, or Claude Code's user settings, so skills, agents, hooks, and rules ship only as an uploadable plugin ZIP plus Cowork global instructions. Local MCP servers are the exception: the app reads claude_desktop_config.json directly, so `ai-toolkit mcp install --editor claude-app --scope global` configures them without a plugin. That file accepts stdio entries only; HTTP/SSE templates are bridged through mcp-remote. Skills work in Chat and Cowork; plugin hooks and sub-agents run only in Cowork.",
|
|
119
123
|
"capability_markers": [
|
|
120
124
|
"Global instructions",
|
|
121
125
|
"Folder instructions",
|
|
122
126
|
"plugins",
|
|
123
127
|
"skills",
|
|
124
|
-
"sub-agents"
|
|
128
|
+
"sub-agents",
|
|
129
|
+
"MCP"
|
|
125
130
|
],
|
|
126
131
|
"version_probe": null
|
|
127
132
|
},
|
package/scripts/mcp_editors.py
CHANGED
|
@@ -13,6 +13,7 @@ import json
|
|
|
13
13
|
import math
|
|
14
14
|
import os
|
|
15
15
|
import re
|
|
16
|
+
import sys
|
|
16
17
|
import tempfile
|
|
17
18
|
from dataclasses import dataclass
|
|
18
19
|
from pathlib import Path
|
|
@@ -23,6 +24,18 @@ except ModuleNotFoundError: # pragma: no cover - Python 3.11+ should have tomll
|
|
|
23
24
|
tomllib = None
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
def _claude_app_config_relpath() -> str:
|
|
28
|
+
"""Home-relative Claude app MCP config path for the running platform."""
|
|
29
|
+
if sys.platform == "darwin":
|
|
30
|
+
return "Library/Application Support/Claude/claude_desktop_config.json"
|
|
31
|
+
if os.name == "nt":
|
|
32
|
+
return "AppData/Roaming/Claude/claude_desktop_config.json"
|
|
33
|
+
return ".config/Claude/claude_desktop_config.json"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
CLAUDE_APP_CONFIG_RELPATH = _claude_app_config_relpath()
|
|
37
|
+
|
|
38
|
+
|
|
26
39
|
EDITOR_SPECS: dict[str, dict[str, str | None]] = {
|
|
27
40
|
"claude": {
|
|
28
41
|
"label": "Claude Code",
|
|
@@ -94,6 +107,13 @@ EDITOR_SPECS: dict[str, dict[str, str | None]] = {
|
|
|
94
107
|
"format": "toml",
|
|
95
108
|
"doc_scope": "project + global",
|
|
96
109
|
},
|
|
110
|
+
"claude-app": {
|
|
111
|
+
"label": "Claude Chat / Cowork",
|
|
112
|
+
"project_path": None,
|
|
113
|
+
"global_path": CLAUDE_APP_CONFIG_RELPATH,
|
|
114
|
+
"format": "json",
|
|
115
|
+
"doc_scope": "global",
|
|
116
|
+
},
|
|
97
117
|
}
|
|
98
118
|
|
|
99
119
|
|
|
@@ -202,6 +222,11 @@ def _resolve_global_config_root(
|
|
|
202
222
|
if not configured:
|
|
203
223
|
return (Path.home() / default_dir).absolute()
|
|
204
224
|
|
|
225
|
+
return _validate_configured_config_root(env_name, configured)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _validate_configured_config_root(env_name: str, configured: str) -> Path:
|
|
229
|
+
"""Validate an operator-supplied config root without resolving symlinks."""
|
|
205
230
|
config_root = Path(configured).expanduser()
|
|
206
231
|
if not config_root.is_absolute():
|
|
207
232
|
raise ValueError(f"Configured {env_name} must be absolute: {configured}")
|
|
@@ -219,6 +244,30 @@ def _resolve_global_config_root(
|
|
|
219
244
|
return config_root
|
|
220
245
|
|
|
221
246
|
|
|
247
|
+
def _resolve_claude_app_config_path(*, home: Path | None) -> Path:
|
|
248
|
+
"""Resolve ``claude_desktop_config.json`` for the Claude app.
|
|
249
|
+
|
|
250
|
+
The Claude app honors ``CLAUDE_USER_DATA_DIR`` for its user-data root, so we
|
|
251
|
+
honor it too. Unlike ``COPILOT_HOME``/``CODEX_HOME`` the default directory is
|
|
252
|
+
platform-specific and need not exist yet -- ``_atomic_write_bytes`` creates it
|
|
253
|
+
-- so only an explicitly configured root is validated.
|
|
254
|
+
"""
|
|
255
|
+
if home is not None:
|
|
256
|
+
return (home / CLAUDE_APP_CONFIG_RELPATH).expanduser().absolute()
|
|
257
|
+
|
|
258
|
+
configured = os.environ.get("CLAUDE_USER_DATA_DIR", "").strip()
|
|
259
|
+
if configured:
|
|
260
|
+
root = _validate_configured_config_root("CLAUDE_USER_DATA_DIR", configured)
|
|
261
|
+
return root / "claude_desktop_config.json"
|
|
262
|
+
|
|
263
|
+
if os.name == "nt": # pragma: no cover - exercised on Windows only
|
|
264
|
+
appdata = os.environ.get("APPDATA", "").strip()
|
|
265
|
+
if appdata:
|
|
266
|
+
return (Path(appdata) / "Claude" / "claude_desktop_config.json").absolute()
|
|
267
|
+
|
|
268
|
+
return (Path.home() / CLAUDE_APP_CONFIG_RELPATH).absolute()
|
|
269
|
+
|
|
270
|
+
|
|
222
271
|
def resolve_editor_path(
|
|
223
272
|
editor: str,
|
|
224
273
|
scope: str,
|
|
@@ -256,6 +305,8 @@ def resolve_editor_path(
|
|
|
256
305
|
default_dir=".codex",
|
|
257
306
|
)
|
|
258
307
|
return codex_home / "config.toml"
|
|
308
|
+
if editor == "claude-app":
|
|
309
|
+
return _resolve_claude_app_config_path(home=home)
|
|
259
310
|
return (home or Path.home()) / str(rel)
|
|
260
311
|
raise ValueError(f"Unsupported scope: {scope}")
|
|
261
312
|
|
|
@@ -509,6 +560,8 @@ def _rollback_config_update(update: ConfigUpdate) -> None:
|
|
|
509
560
|
def _normalize_server(editor: str, server: dict) -> dict:
|
|
510
561
|
if editor == "antigravity":
|
|
511
562
|
return _normalize_antigravity_server(server)
|
|
563
|
+
if editor == "claude-app":
|
|
564
|
+
return _normalize_claude_app_server(server)
|
|
512
565
|
data = copy.deepcopy(server)
|
|
513
566
|
if editor == "copilot":
|
|
514
567
|
if "url" in data:
|
|
@@ -519,6 +572,65 @@ def _normalize_server(editor: str, server: dict) -> dict:
|
|
|
519
572
|
return data
|
|
520
573
|
|
|
521
574
|
|
|
575
|
+
MCP_REMOTE_PACKAGE = "mcp-remote"
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
def _normalize_claude_app_server(server: dict) -> dict:
|
|
579
|
+
"""Emit the Claude app's stdio-only MCP schema, bridging remote endpoints.
|
|
580
|
+
|
|
581
|
+
``claude_desktop_config.json`` validates each entry as ``{command, args,
|
|
582
|
+
env}``; remote servers live in a separate app-managed ``remoteMcpServers``
|
|
583
|
+
surface that is not file-configurable. Portable HTTP/SSE templates are
|
|
584
|
+
therefore wrapped in ``mcp-remote``, which negotiates the transport itself,
|
|
585
|
+
so one bridge shape covers both the ``http`` and ``sse`` spellings.
|
|
586
|
+
"""
|
|
587
|
+
if not isinstance(server, dict):
|
|
588
|
+
raise ValueError("Claude app MCP server configuration must be an object")
|
|
589
|
+
|
|
590
|
+
data = copy.deepcopy(server)
|
|
591
|
+
for key in ("_source", "transport", "type", "tools"):
|
|
592
|
+
data.pop(key, None)
|
|
593
|
+
|
|
594
|
+
url = data.pop("url", None)
|
|
595
|
+
server_url = data.pop("serverUrl", None)
|
|
596
|
+
if url is not None and server_url is not None:
|
|
597
|
+
raise ValueError(
|
|
598
|
+
"Claude app MCP server requires exactly one of 'url' or 'serverUrl'"
|
|
599
|
+
)
|
|
600
|
+
url = url if url is not None else server_url
|
|
601
|
+
|
|
602
|
+
if "command" in data and url is not None:
|
|
603
|
+
raise ValueError(
|
|
604
|
+
"Claude app MCP server requires either 'command' or a URL, not both"
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
if url is not None:
|
|
608
|
+
if not isinstance(url, str) or not url.strip():
|
|
609
|
+
raise ValueError("Claude app MCP server URL must be a non-empty string")
|
|
610
|
+
headers = data.pop("headers", None)
|
|
611
|
+
args = ["-y", MCP_REMOTE_PACKAGE, url.strip()]
|
|
612
|
+
if headers is not None:
|
|
613
|
+
if not isinstance(headers, dict):
|
|
614
|
+
raise ValueError("Claude app MCP 'headers' must be an object")
|
|
615
|
+
for name, value in headers.items():
|
|
616
|
+
if not isinstance(name, str) or not isinstance(value, str):
|
|
617
|
+
raise ValueError(
|
|
618
|
+
"Claude app MCP 'headers' must map strings to strings"
|
|
619
|
+
)
|
|
620
|
+
args.extend(["--header", f"{name}: {value}"])
|
|
621
|
+
bridged: dict = {"command": "npx", "args": args}
|
|
622
|
+
if "env" in data:
|
|
623
|
+
bridged["env"] = data["env"]
|
|
624
|
+
return bridged
|
|
625
|
+
|
|
626
|
+
command = data.get("command")
|
|
627
|
+
if not isinstance(command, str) or not command.strip():
|
|
628
|
+
raise ValueError(
|
|
629
|
+
"Claude app MCP server requires a non-empty 'command' or a URL"
|
|
630
|
+
)
|
|
631
|
+
return {key: data[key] for key in ("command", "args", "env") if key in data}
|
|
632
|
+
|
|
633
|
+
|
|
522
634
|
def _normalize_antigravity_server(server: dict) -> dict:
|
|
523
635
|
"""Validate and emit Antigravity's current ``serverUrl`` MCP schema."""
|
|
524
636
|
if not isinstance(server, dict):
|