@wootsup/mcp 0.1.0-rc.1

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 (135) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/LICENSE +21 -0
  3. package/README.md +179 -0
  4. package/SECURITY.md +163 -0
  5. package/dist/auth/keychain.d.ts +47 -0
  6. package/dist/auth/keychain.js +262 -0
  7. package/dist/auth/keychain.js.map +1 -0
  8. package/dist/auth/oauth-provider.d.ts +68 -0
  9. package/dist/auth/oauth-provider.js +232 -0
  10. package/dist/auth/oauth-provider.js.map +1 -0
  11. package/dist/auth/profiles.d.ts +52 -0
  12. package/dist/auth/profiles.js +200 -0
  13. package/dist/auth/profiles.js.map +1 -0
  14. package/dist/auth/token.d.ts +27 -0
  15. package/dist/auth/token.js +88 -0
  16. package/dist/auth/token.js.map +1 -0
  17. package/dist/index.d.ts +13 -0
  18. package/dist/index.js +137 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/install-skill.d.ts +23 -0
  21. package/dist/install-skill.js +73 -0
  22. package/dist/install-skill.js.map +1 -0
  23. package/dist/modules/apimapper/cache.d.ts +2 -0
  24. package/dist/modules/apimapper/cache.js +71 -0
  25. package/dist/modules/apimapper/cache.js.map +1 -0
  26. package/dist/modules/apimapper/client.d.ts +85 -0
  27. package/dist/modules/apimapper/client.js +523 -0
  28. package/dist/modules/apimapper/client.js.map +1 -0
  29. package/dist/modules/apimapper/connections.d.ts +2 -0
  30. package/dist/modules/apimapper/connections.js +406 -0
  31. package/dist/modules/apimapper/connections.js.map +1 -0
  32. package/dist/modules/apimapper/credential-sanitizer.d.ts +7 -0
  33. package/dist/modules/apimapper/credential-sanitizer.js +70 -0
  34. package/dist/modules/apimapper/credential-sanitizer.js.map +1 -0
  35. package/dist/modules/apimapper/credentials.d.ts +2 -0
  36. package/dist/modules/apimapper/credentials.js +258 -0
  37. package/dist/modules/apimapper/credentials.js.map +1 -0
  38. package/dist/modules/apimapper/diagnose.d.ts +18 -0
  39. package/dist/modules/apimapper/diagnose.js +305 -0
  40. package/dist/modules/apimapper/diagnose.js.map +1 -0
  41. package/dist/modules/apimapper/flows.d.ts +2 -0
  42. package/dist/modules/apimapper/flows.js +372 -0
  43. package/dist/modules/apimapper/flows.js.map +1 -0
  44. package/dist/modules/apimapper/get-skill.d.ts +4 -0
  45. package/dist/modules/apimapper/get-skill.js +88 -0
  46. package/dist/modules/apimapper/get-skill.js.map +1 -0
  47. package/dist/modules/apimapper/graph-builder.d.ts +47 -0
  48. package/dist/modules/apimapper/graph-builder.js +117 -0
  49. package/dist/modules/apimapper/graph-builder.js.map +1 -0
  50. package/dist/modules/apimapper/graph.d.ts +2 -0
  51. package/dist/modules/apimapper/graph.js +117 -0
  52. package/dist/modules/apimapper/graph.js.map +1 -0
  53. package/dist/modules/apimapper/index.d.ts +2 -0
  54. package/dist/modules/apimapper/index.js +43 -0
  55. package/dist/modules/apimapper/index.js.map +1 -0
  56. package/dist/modules/apimapper/inspect.d.ts +20 -0
  57. package/dist/modules/apimapper/inspect.js +86 -0
  58. package/dist/modules/apimapper/inspect.js.map +1 -0
  59. package/dist/modules/apimapper/library.d.ts +2 -0
  60. package/dist/modules/apimapper/library.js +237 -0
  61. package/dist/modules/apimapper/library.js.map +1 -0
  62. package/dist/modules/apimapper/license.d.ts +2 -0
  63. package/dist/modules/apimapper/license.js +142 -0
  64. package/dist/modules/apimapper/license.js.map +1 -0
  65. package/dist/modules/apimapper/local-sources.d.ts +2 -0
  66. package/dist/modules/apimapper/local-sources.js +123 -0
  67. package/dist/modules/apimapper/local-sources.js.map +1 -0
  68. package/dist/modules/apimapper/misc.d.ts +2 -0
  69. package/dist/modules/apimapper/misc.js +149 -0
  70. package/dist/modules/apimapper/misc.js.map +1 -0
  71. package/dist/modules/apimapper/node-schema.d.ts +217 -0
  72. package/dist/modules/apimapper/node-schema.js +218 -0
  73. package/dist/modules/apimapper/node-schema.js.map +1 -0
  74. package/dist/modules/apimapper/normalizers.d.ts +13 -0
  75. package/dist/modules/apimapper/normalizers.js +37 -0
  76. package/dist/modules/apimapper/normalizers.js.map +1 -0
  77. package/dist/modules/apimapper/onboarding.d.ts +51 -0
  78. package/dist/modules/apimapper/onboarding.js +201 -0
  79. package/dist/modules/apimapper/onboarding.js.map +1 -0
  80. package/dist/modules/apimapper/schema.d.ts +2 -0
  81. package/dist/modules/apimapper/schema.js +84 -0
  82. package/dist/modules/apimapper/schema.js.map +1 -0
  83. package/dist/modules/apimapper/settings.d.ts +2 -0
  84. package/dist/modules/apimapper/settings.js +157 -0
  85. package/dist/modules/apimapper/settings.js.map +1 -0
  86. package/dist/modules/apimapper/skill-resources.d.ts +4 -0
  87. package/dist/modules/apimapper/skill-resources.js +85 -0
  88. package/dist/modules/apimapper/skill-resources.js.map +1 -0
  89. package/dist/modules/apimapper/types.d.ts +111 -0
  90. package/dist/modules/apimapper/types.js +14 -0
  91. package/dist/modules/apimapper/types.js.map +1 -0
  92. package/dist/modules/apimapper/use-profile.d.ts +34 -0
  93. package/dist/modules/apimapper/use-profile.js +176 -0
  94. package/dist/modules/apimapper/use-profile.js.map +1 -0
  95. package/dist/modules/apimapper/workflows.d.ts +2 -0
  96. package/dist/modules/apimapper/workflows.js +301 -0
  97. package/dist/modules/apimapper/workflows.js.map +1 -0
  98. package/dist/platform/index.d.ts +71 -0
  99. package/dist/platform/index.js +377 -0
  100. package/dist/platform/index.js.map +1 -0
  101. package/dist/server-http.d.ts +22 -0
  102. package/dist/server-http.js +159 -0
  103. package/dist/server-http.js.map +1 -0
  104. package/dist/setup/detect-clients.d.ts +39 -0
  105. package/dist/setup/detect-clients.js +152 -0
  106. package/dist/setup/detect-clients.js.map +1 -0
  107. package/dist/setup/probe-handshake.d.ts +26 -0
  108. package/dist/setup/probe-handshake.js +159 -0
  109. package/dist/setup/probe-handshake.js.map +1 -0
  110. package/dist/setup/write-config.d.ts +25 -0
  111. package/dist/setup/write-config.js +247 -0
  112. package/dist/setup/write-config.js.map +1 -0
  113. package/dist/setup-cli.d.ts +49 -0
  114. package/dist/setup-cli.js +292 -0
  115. package/dist/setup-cli.js.map +1 -0
  116. package/dist/skill-instructions.d.ts +10 -0
  117. package/dist/skill-instructions.js +68 -0
  118. package/dist/skill-instructions.js.map +1 -0
  119. package/dist/transports/http.d.ts +29 -0
  120. package/dist/transports/http.js +267 -0
  121. package/dist/transports/http.js.map +1 -0
  122. package/dist/transports/stdio.d.ts +9 -0
  123. package/dist/transports/stdio.js +19 -0
  124. package/dist/transports/stdio.js.map +1 -0
  125. package/docs/architecture.md +140 -0
  126. package/docs/customgraph-internal-migration.md +210 -0
  127. package/docs/security.md +126 -0
  128. package/docs/tools.md +230 -0
  129. package/manifest.json +76 -0
  130. package/package.json +61 -0
  131. package/skills/apimapper/SKILL.md +57 -0
  132. package/skills/apimapper/reference/joomla.md +85 -0
  133. package/skills/apimapper/reference/oauth.md +94 -0
  134. package/skills/apimapper/reference/troubleshooting.md +123 -0
  135. package/skills/apimapper/reference/yootheme.md +96 -0
@@ -0,0 +1,210 @@
1
+ # CustomGraph internal-use migration
2
+
3
+ CustomGraph (Pipeline Studio, `~/Projekte/customgraph/`) is the
4
+ **first internal consumer** of `@wootsup/mcp`. Today it ships a
5
+ local-build adapter — `packages/mcp-adapter-apimapper/` — wired
6
+ through a shell wrapper. Once Task 10.4 publishes `@wootsup/mcp` to
7
+ npm (G2 gate), the wrapper goes away and CustomGraph consumes the
8
+ published package like every external customer.
9
+
10
+ This document is a **prep tracker only**. No file outside
11
+ `packages/apimapper-mcp/` is modified by this commit.
12
+
13
+ ## Files involved
14
+
15
+ | File | Repo | Role |
16
+ |---|---|---|
17
+ | `~/.claude.json` | (user home) | Claude Code MCP-server registry. The `apimapper` entry lives here. |
18
+ | `~/.claude-tools/run-mcp-apimapper.sh` | (user home) | Today's wrapper. Sets env + execs the local-build adapter. |
19
+ | `packages/mcp-adapter-apimapper/` | `customgraph` repo | Local-build adapter that the wrapper currently invokes. |
20
+
21
+ ## BEFORE state (today, 2026-05-18)
22
+
23
+ ### `~/.claude.json` (relevant slice)
24
+
25
+ ```json
26
+ "apimapper": {
27
+ "type": "stdio",
28
+ "command": "/Users/getimo/.claude-tools/run-mcp-apimapper.sh",
29
+ "args": []
30
+ }
31
+ ```
32
+
33
+ ### `~/.claude-tools/run-mcp-apimapper.sh`
34
+
35
+ ```bash
36
+ #!/bin/bash
37
+ # Wrapper for apimapper MCP adapter — hardcodes env vars.
38
+ export DEVTOOLS_URL="https://dev.wootsup.com/dev-tools/api"
39
+ export WP_BASE_URL="https://dev.wootsup.com/wordpress"
40
+ export JOOMLA_BASE_URL="https://dev.wootsup.com/joomla"
41
+ export NODE_ENV="production"
42
+ cd /Users/getimo/Projekte/customgraph
43
+ exec bun packages/mcp-adapter-apimapper/dist/index.js
44
+ ```
45
+
46
+ **Drawbacks of this setup:**
47
+
48
+ - Depends on a built local checkout of `customgraph` at a hard-coded
49
+ path. If that checkout is moved or the `dist/` is stale, the MCP
50
+ server breaks.
51
+ - Uses `bun` (CustomGraph's runtime) instead of Node — divergence from
52
+ the public package's tested runtime.
53
+ - Env vars (`WP_BASE_URL`, `JOOMLA_BASE_URL`) are the legacy contract;
54
+ the published package uses `APIMAPPER_SITE_URL` + `APIMAPPER_PLATFORM`
55
+ with a runtime bridge in `src/index.ts`.
56
+ - No keychain integration — credentials live in the wrapper as env
57
+ vars, not encrypted at rest.
58
+
59
+ ## AFTER state (post-G2)
60
+
61
+ ### `~/.claude.json` (relevant slice)
62
+
63
+ ```json
64
+ "apimapper": {
65
+ "type": "stdio",
66
+ "command": "npx",
67
+ "args": ["-y", "@wootsup/mcp@latest"],
68
+ "env": {
69
+ "APIMAPPER_PROFILE": "default"
70
+ }
71
+ }
72
+ ```
73
+
74
+ That's it. The token + site URL come from the OS keychain (or
75
+ `~/.config/apimapper-mcp/profiles/default.json` fallback), set during
76
+ `npx @wootsup/mcp setup`.
77
+
78
+ ### Wrapper script
79
+
80
+ Deprecated. Either delete `~/.claude-tools/run-mcp-apimapper.sh` or
81
+ keep it around as a backup pointing at the local dev build for
82
+ adapter-internal debugging. Recommend: rename to `.bak` for one cycle,
83
+ then delete.
84
+
85
+ ## Migration steps (post-G2 only — do not execute now)
86
+
87
+ 1. **Confirm npm publish succeeded**
88
+
89
+ ```bash
90
+ gh run list \
91
+ --workflow apimapper-mcp-publish.yml \
92
+ --limit 1 --json conclusion,name,status,databaseId
93
+ ```
94
+
95
+ Expect `conclusion: success`, both `publish-npm` and `publish-dxt`
96
+ jobs green.
97
+
98
+ 2. **Confirm npm registry has the version**
99
+
100
+ ```bash
101
+ npm view @wootsup/mcp version
102
+ # Expect: 0.1.0-rc.1 (or whatever the published tag was)
103
+
104
+ npm view @wootsup/mcp dist-tags
105
+ # Expect: { latest: ..., rc: '0.1.0-rc.1' } for the rc tag
106
+ ```
107
+
108
+ 3. **Run the setup wizard with the published package**
109
+
110
+ ```bash
111
+ npx -y @wootsup/mcp@latest setup
112
+ ```
113
+
114
+ This:
115
+ - Auto-detects Claude Code (`~/.claude.json`).
116
+ - Prompts for site URL + MCP key.
117
+ - Runs identity-probe handshake.
118
+ - Writes the new `apimapper` entry (idempotent — replaces the
119
+ existing one).
120
+ - Stores the token in the macOS keychain under the `default`
121
+ profile.
122
+
123
+ 4. **Manual sanity check on `~/.claude.json`**
124
+
125
+ Confirm the entry now matches the AFTER state above. Note: the
126
+ wizard writes `command: "npx"` and `args: ["-y", "@wootsup/mcp@latest"]`
127
+ exactly — if it picks a different shape, file an issue against
128
+ the wizard (`src/setup-cli.ts`).
129
+
130
+ 5. **Move the wrapper out of the way**
131
+
132
+ ```bash
133
+ mv ~/.claude-tools/run-mcp-apimapper.sh \
134
+ ~/.claude-tools/run-mcp-apimapper.sh.bak
135
+ ```
136
+
137
+ 6. **Restart Claude Code**
138
+
139
+ The MCP server is launched at session start. A `/mcp` slash-command
140
+ shows the loaded servers — `apimapper` should report **connected**
141
+ with the new `npx` command line.
142
+
143
+ 7. **Verify `apimapper_health` works**
144
+
145
+ In a Claude Code session:
146
+
147
+ ```
148
+ apimapper_health
149
+ ```
150
+
151
+ Expect:
152
+
153
+ ```
154
+ status: ok
155
+ platform: wordpress (or joomla)
156
+ site_url: https://dev.wootsup.com/wordpress
157
+ plugin_version: 2.0.7
158
+ tool_count: 74
159
+ ```
160
+
161
+ 8. **Run the full smoke suite**
162
+
163
+ ```
164
+ apimapper_onboarding
165
+ apimapper_connection_list
166
+ apimapper_flow_list
167
+ ```
168
+
169
+ All three should return tables. If any returns
170
+ `403 invalid_token`, re-run step 3.
171
+
172
+ ## Rollback
173
+
174
+ If any step fails:
175
+
176
+ ```bash
177
+ # Restore the wrapper
178
+ mv ~/.claude-tools/run-mcp-apimapper.sh.bak \
179
+ ~/.claude-tools/run-mcp-apimapper.sh
180
+
181
+ # Revert ~/.claude.json (manual edit; jq if you have it)
182
+ # — set the `apimapper` entry back to the BEFORE shape above.
183
+ ```
184
+
185
+ Restart Claude Code. The local-build adapter is back in play.
186
+
187
+ ## Open question: when to drop the CustomGraph adapter?
188
+
189
+ `packages/mcp-adapter-apimapper/` in the CustomGraph repo becomes
190
+ obsolete after the migration — its 65-tool surface is now in
191
+ `@wootsup/mcp`, and the wrapper is gone. **Removal is a separate
192
+ session**: it requires Auditing CustomGraph for any other consumer
193
+ (none expected — the only caller was Claude Code via the wrapper)
194
+ and a deprecation note in the CustomGraph CHANGELOG.
195
+
196
+ Filed as a CustomGraph followup, not part of API Mapper Phase 10.
197
+
198
+ ## Out-of-scope reminder
199
+
200
+ This document is **prep only**. The actual migration is gated on:
201
+
202
+ - ✅ Task 10.1 (CI) — done.
203
+ - ✅ Task 10.2 (publish workflow) — done.
204
+ - ✅ Task 10.3 (docs) — done.
205
+ - ⏳ **Task 10.4 (G2 user-gate) — pending Thomas's approval.**
206
+ - ⏳ Task 10.5 (this migration) — executes after 10.4.
207
+ - ⏳ Task 10.6 (stable v1.0.0) — separate cycle.
208
+
209
+ Until Task 10.4 lands, do not modify `~/.claude.json` or
210
+ `~/.claude-tools/`.
@@ -0,0 +1,126 @@
1
+ # Security Model
2
+
3
+ Long-form threat model and mitigations for `@wootsup/mcp`. For the
4
+ reporting process and supported-version policy, see
5
+ [`../SECURITY.md`](../SECURITY.md).
6
+
7
+ ## Threat model
8
+
9
+ | ID | Threat | Likelihood | Impact | Mitigation |
10
+ |----|--------|------------|--------|------------|
11
+ | T1 | Token leak via logs / stderr | Med | High | All response sanitizer (`credential-sanitizer.ts`); no token in stack traces; pin tests assert. |
12
+ | T2 | Token leak via tool response | Low | Critical | List endpoints structurally omit token string; tests pin redaction surface. |
13
+ | T3 | Token replay across sites | Med | High | HMAC includes site URL; cross-site replay fails server-side signature check. |
14
+ | T4 | Forged tokens | Low | Critical | Signing key never leaves the install; tokens unforgeable without it. |
15
+ | T5 | Phishing setup link | Med | Med | Identity probe + site-title confirmation in wizard; user must explicitly confirm. |
16
+ | T6 | Confused-deputy LLM (read-only token gets `*_delete` tools listed) | High | Med | Scope filter excludes destructive tools from tool-list when the token lacks the scope. |
17
+ | T7 | Local-fs token theft (no keychain) | Med | Med | `0600` file mode; keychain default on macOS/Windows; SECURITY.md warns about multi-user environments. |
18
+ | T8 | DXT supply-chain (malicious .dxt) | Low | Critical | DXT bundle uploaded as a signed GitHub Release asset; `apimapper-mcp-publish.yml` workflow publishes with `--provenance`. |
19
+ | T9 | OAuth callback hijack (HTTP transport) | Med | High | PKCE-required (S256); state param checked; loopback callback only. |
20
+ | T10 | TOCTOU on rotate (old token works after rotate UI shows success) | Low | Med | Rotation is atomic on the server; the response shows the new token only after the old one is invalidated. |
21
+
22
+ ## Token rotation
23
+
24
+ - **From admin UI:** API Mapper → Connections → MCP Access → **Rotate**.
25
+ - **From CLI:** `apimapper_credential_*` tools do **not** rotate MCP keys
26
+ themselves — by design, key rotation is an admin-UI gesture (not a
27
+ tool the LLM can call) to prevent confused-deputy rotation. Rotation
28
+ is intentionally human-in-the-loop.
29
+ - After rotation, the next request with the old token returns
30
+ `403 invalid_token`. The user re-runs `npx @wootsup/mcp setup` to
31
+ paste the new key.
32
+
33
+ ## Revocation
34
+
35
+ - Per-token revoke is immediate (no server-side cache).
36
+ - "Revoke all" also rotates the signing key — invalidates every active
37
+ token in one operation. Use after suspected compromise.
38
+
39
+ ## Scope semantics
40
+
41
+ | Scope | Tools | Default for amk_test_? |
42
+ |---|---|---|
43
+ | `read` | `*_list`, `*_get`, `*_inspect`, `apimapper_health`, `apimapper_onboarding` | ✅ |
44
+ | `write` | `*_create`, `*_update`, `*_compile`, `*_publish` | ✅ |
45
+ | `destructive` | `*_delete`, `apimapper_settings_reset_demo`, `apimapper_license_deactivate` | ❌ |
46
+ | `oauth` | `apimapper_credential_create`, `apimapper_oauth_authorize_begin` | ✅ |
47
+
48
+ The MCP server **filters tool registration by available scopes**. A
49
+ token without `destructive` scope causes the matching tools to be
50
+ omitted from `tools/list` entirely — the LLM cannot accidentally
51
+ suggest them.
52
+
53
+ ## Anti-phishing identity probe
54
+
55
+ When the wizard contacts an unverified site URL:
56
+
57
+ 1. `GET <url>/api-mapper/v1/mcp/identity` (no auth).
58
+ 2. Server responds with `{ key_id, site_title, site_signature }`
59
+ where `site_signature = HMAC(signing_key, key_id + site_url + nonce)`.
60
+ 3. Wizard decodes the token to extract its `key_id` claim.
61
+ 4. Wizard sends a second probe with the token; server proves it can
62
+ sign over the same nonce.
63
+ 5. User sees: **"You are connecting to: '<site_title>' (<site_url>).
64
+ Proceed?"** with explicit confirm.
65
+
66
+ A malicious server cannot pass both probes because it lacks the genuine
67
+ signing key. The user-visible site title (rendered by the wizard from
68
+ the server's response, not the URL bar) gives one more verification
69
+ surface for the user.
70
+
71
+ ## OAuth 2.0 PKCE (HTTP transport)
72
+
73
+ When `@wootsup/mcp` runs in HTTP mode:
74
+
75
+ - **Grants supported:** `authorization_code` with PKCE-S256 only.
76
+ - **Implicit grant:** disabled.
77
+ - **`code` grant without PKCE:** rejected with `invalid_request`.
78
+ - **Loopback callbacks only:** `redirect_uri` must be
79
+ `http://127.0.0.1:<port>/callback` or `http://localhost:<port>/callback`.
80
+ - **State param:** required and verified.
81
+ - **Origin header:** Bearer tokens are bound to the issuing site URL.
82
+ A request from a different `Origin` is rejected (`401`).
83
+ - **Token TTL:** 1 hour. Refresh tokens are not issued — the client
84
+ re-runs the auth flow.
85
+
86
+ See `src/server-http.ts` for the implementation and
87
+ `src/server-http.test.ts` (2 tests) + `src/transports/http.test.ts`
88
+ (10 tests) for the pinning.
89
+
90
+ ## Keychain fallback security
91
+
92
+ When `@napi-rs/keyring` cannot reach an OS keychain:
93
+
94
+ 1. The wizard prints a warning: **"OS keychain unavailable. Falling
95
+ back to ~/.config/apimapper-mcp/profiles/<name>.json (mode 0600)."**
96
+ 2. The user explicitly confirms before any token is written to disk.
97
+ 3. The file is written with mode `0600` (owner-only) on POSIX. On
98
+ Windows, NTFS ACL is set to the current user only.
99
+ 4. The file contains the bare token string + the site URL — no
100
+ signing key, no signature data.
101
+
102
+ **Hostile-multi-user environments:** Even with `0600`, a root user can
103
+ read the file. If you operate in such an environment, use the OS
104
+ keychain path explicitly (it is the default on macOS/Windows; on Linux
105
+ install `libsecret` to enable it).
106
+
107
+ ## Sanitization surface
108
+
109
+ The `CredentialSanitizer` runs in two places:
110
+
111
+ 1. **Server-side**, in the WordPress / Joomla plugin — every REST
112
+ response is rewritten to mask credential values (`***`) before
113
+ transit.
114
+ 2. **Client-side**, in `@wootsup/mcp` — defense-in-depth. If a
115
+ server forgets to sanitize (or a new endpoint is added without the
116
+ wrap), the MCP server still won't leak the value to the LLM.
117
+
118
+ Unit tests pin both sides:
119
+
120
+ - `src/modules/apimapper/credential-sanitizer.test.ts` (client side).
121
+ - `tests/Unit/Auth/CredentialSanitizerTest.php` (server side, in the
122
+ main plugin repo).
123
+
124
+ ## Reporting
125
+
126
+ See [`../SECURITY.md`](../SECURITY.md).
package/docs/tools.md ADDED
@@ -0,0 +1,230 @@
1
+ # Tools reference
2
+
3
+ Auto-extracted from `src/modules/apimapper/*.ts` on **2026-05-18**.
4
+
5
+ To regenerate after adding tools, run:
6
+
7
+ ```bash
8
+ cd packages/apimapper-mcp
9
+ node scripts/extract-tools.mjs
10
+ ```
11
+
12
+ …and paste the `---MD---` output into the sections below. (The
13
+ extractor is intentionally simple; a fully auto-generated build-step
14
+ is tracked as a future improvement.)
15
+
16
+ ## Summary
17
+
18
+ - **Total tools:** 74 registered (+ a few system surfaces brought in
19
+ via `@getimo/mcp-toolkit`).
20
+ - **Annotation breakdown:** 43 `readOnly`, 15 `mutating`, 10 `creating`,
21
+ 6 `destructive`.
22
+
23
+ The annotation tells the AI client what kind of side-effect each tool
24
+ has. Destructive tools additionally require a `confirm: true`
25
+ parameter — see the
26
+ [Goldstandard skill](../../../docs/MCP-Module-Goldstandard.md) (private
27
+ vault) for the full convention.
28
+
29
+ ## Quick map
30
+
31
+ | Module | Tools | Notes |
32
+ |---|---:|---|
33
+ | `connections.ts` | 11 | CRUD + probe + sample-data + resources |
34
+ | `flows.ts` | 11 | CRUD + compile + import/export + trace |
35
+ | `library.ts` | 9 | Catalog + activate / deactivate templates |
36
+ | `credentials.ts` | 7 | CRUD + link + OAuth begin |
37
+ | `settings.ts` | 7 | Settings + features + platform parity + warnings |
38
+ | `license.ts` | 6 | Activate / status / beta-channel / refresh |
39
+ | `local-sources.ts` | 4 | WP posts/users, Joomla articles, … |
40
+ | `misc.ts` | 4 | Releases + Brandfetch + feedback |
41
+ | `workflows.ts` | 3 | Composite multi-step ops |
42
+ | `graph.ts` | 2 | Preview + validate |
43
+ | `cache.ts` | 2 | Stats + invalidate |
44
+ | `schema.ts` | 2 | Profile + snapshot list |
45
+ | `onboarding.ts` | 1 | Composite startup report |
46
+ | `diagnose.ts` | 1 | Composite token + identity probe |
47
+ | `inspect.ts` | 1 | Token decode (network-free) |
48
+ | `get-skill.ts` | 1 | Read bundled skill doc |
49
+ | `use-profile.ts` | 1 | Switch active profile |
50
+ | `index.ts` | 1 | `apimapper_rest_modules_status` |
51
+
52
+ ### Adapter Status (`index.ts`)
53
+
54
+ | Tool | Annotation | Description |
55
+ |------|------------|-------------|
56
+ | `apimapper_rest_modules_status` | `readOnly` | Module-loading status for this MCP adapter (which sub-modules registered cleanly). |
57
+
58
+ ### Health, Releases, Brandfetch & Feedback (`misc.ts`)
59
+
60
+ | Tool | Annotation | Description |
61
+ |------|------------|-------------|
62
+ | `apimapper_brandfetch` | `readOnly` | Fetch a brand's logo metadata via the Brandfetch proxy. |
63
+ | `apimapper_feedback_submit` | `creating` | Submit user feedback (bug report, feature request, support question) to the API Mapper team. |
64
+ | `apimapper_release_download` | `creating` | Request a signed download URL for a release ZIP. |
65
+ | `apimapper_release_list` | `readOnly` | List API Mapper plugin releases available for download. |
66
+
67
+ ### Onboarding (`onboarding.ts`)
68
+
69
+ | Tool | Annotation | Description |
70
+ |------|------------|-------------|
71
+ | `apimapper_onboarding` | `readOnly` | Aggregate health, license, connections, flows, and popular library items into a single onboarding report with suggested next actions. |
72
+
73
+ ### Diagnose (`diagnose.ts`)
74
+
75
+ | Tool | Annotation | Description |
76
+ |------|------------|-------------|
77
+ | `apimapper_diagnose` | `readOnly` | Validate a token + siteUrl pair before profile creation (token decode + identity probe + reachability). |
78
+
79
+ ### Token Inspection (`inspect.ts`)
80
+
81
+ | Tool | Annotation | Description |
82
+ |------|------------|-------------|
83
+ | `apimapper_inspect_token` | `readOnly` | Decode an API Mapper token (`amk_live_…` or `amk_test_…`) WITHOUT calling the network. |
84
+
85
+ ### Connections (`connections.ts`)
86
+
87
+ | Tool | Annotation | Description |
88
+ |------|------------|-------------|
89
+ | `apimapper_connection_create` | `creating` | Create a new connection (custom — not from library). |
90
+ | `apimapper_connection_data` | `readOnly` | Fetch sample data from a connection's configured endpoint. |
91
+ | `apimapper_connection_delete` | `destructive` | Permanently delete a connection. Any flow referencing it will break. |
92
+ | `apimapper_connection_get` | `readOnly` | Fetch full configuration of a single connection by ID. |
93
+ | `apimapper_connection_health_check` | `readOnly` | Probe a set of connections in one batch and report status. May take 10-30s. |
94
+ | `apimapper_connection_list` | `readOnly` | List all API Mapper connections. Use `apimapper_connection_get` for full details. |
95
+ | `apimapper_connection_pipeline_update` | `mutating` | Update the connection's pipeline (endpoints, default_params, headers, items_path, items_shape). |
96
+ | `apimapper_connection_resources` | `readOnly` | List browseable resources on a connection (drive files, sheets, IG media). |
97
+ | `apimapper_connection_test` | `readOnly` | Probe a connection's upstream endpoint to verify reachability + auth. |
98
+ | `apimapper_connection_update` | `mutating` | Update fields on an existing connection. Only provided fields are changed; wire-format is snake_case. |
99
+ | `apimapper_health` | `readOnly` | Check connectivity + auth against the API Mapper REST namespace. |
100
+
101
+ ### Credentials & OAuth (`credentials.ts`)
102
+
103
+ | Tool | Annotation | Description |
104
+ |------|------------|-------------|
105
+ | `apimapper_credential_create` | `creating` | Create a new credential. Secrets are encrypted server-side. REST contract uses snake_case keys: `auth_type`, `auth_data`, `oauth_provider`. |
106
+ | `apimapper_credential_delete` | `destructive` | Permanently delete a credential. Any connection using it will lose auth. |
107
+ | `apimapper_credential_get` | `readOnly` | Fetch credential metadata. **Secret values are stripped at the MCP boundary** (`auth_data`, `refresh_token`, `access_token`, `api_key` → `'[REDACTED]'`). |
108
+ | `apimapper_credential_link` | `mutating` | Attach a credential to a connection. PUT `/connections/{id}` with `credential_id`. |
109
+ | `apimapper_credential_list` | `readOnly` | List all stored credentials (sanitised — secrets omitted). |
110
+ | `apimapper_credential_update` | `mutating` | Update credential metadata or rotate secret. |
111
+ | `apimapper_oauth_authorize_begin` | `creating` | Initiate the OAuth2 authorization-code flow for a credential. Returns the upstream authorize URL the user opens in a browser. |
112
+
113
+ ### Flows (`flows.ts`)
114
+
115
+ | Tool | Annotation | Description |
116
+ |------|------------|-------------|
117
+ | `apimapper_flow_compile` | `mutating` | Compile flow into executable pipeline (validation + topo sort + step generation + schema). |
118
+ | `apimapper_flow_create` | `creating` | Create a new flow with full nodes + edges JSON. |
119
+ | `apimapper_flow_delete` | `destructive` | Permanently delete a flow. If published, it disappears from YOOtheme. Preview-mode (`confirm:false`) fetches metadata first. |
120
+ | `apimapper_flow_detect_schema` | `mutating` | Re-detect/refresh the output schema by sampling the upstream API. |
121
+ | `apimapper_flow_export` | `readOnly` | Export a flow as a portable JSON bundle (incl. connection refs). |
122
+ | `apimapper_flow_get` | `readOnly` | Fetch full flow definition (nodes, edges, viewport, compiled artifact). |
123
+ | `apimapper_flow_import` | `creating` | Import a flow JSON bundle. Always validate first with `apimapper_flow_import_validate`. Rename via `bundle.data.flow.name` or `rename_to`. |
124
+ | `apimapper_flow_import_validate` | `readOnly` | Validate a flow JSON bundle before importing. Reports missing connections, schema mismatches, conflicts. |
125
+ | `apimapper_flow_list` | `readOnly` | List all API Mapper flows. Use `apimapper_flow_get` for full structure. |
126
+ | `apimapper_flow_trace` | `readOnly` | Fetch the execution trace from the last run (timing per step, item counts, errors). |
127
+ | `apimapper_flow_update` | `mutating` | Update flow fields. Use to modify nodes/edges (e.g., toggle merge.strategy, change joinKey). After update, call `apimapper_flow_compile`. |
128
+
129
+ ### Graph Preview / Validate (`graph.ts`)
130
+
131
+ | Tool | Annotation | Description |
132
+ |------|------------|-------------|
133
+ | `apimapper_graph_preview` | `readOnly` | Execute an ad-hoc graph (nodes + edges) and return rendered items at the target node. |
134
+ | `apimapper_graph_validate` | `readOnly` | Validate a graph's structure (cycles, disconnected nodes, missing outputs, type mismatches) WITHOUT executing the pipeline. |
135
+
136
+ ### Local Sources (`local-sources.ts`)
137
+
138
+ | Tool | Annotation | Description |
139
+ |------|------------|-------------|
140
+ | `apimapper_local_source_filter_options` | `readOnly` | Fetch dropdown options for a filter on a local source (e.g., available categories/tags). |
141
+ | `apimapper_local_source_query` | `readOnly` | Execute a query against a local source and return data. Body uses camelCase keys. |
142
+ | `apimapper_local_source_schema` | `readOnly` | Fetch field schema for a local-source type (e.g., `wordpress/posts`). |
143
+ | `apimapper_local_source_types` | `readOnly` | List available local-source types (e.g., `wordpress/posts`, `wordpress/users`, `joomla/articles`). |
144
+
145
+ ### Schema (`schema.ts`)
146
+
147
+ | Tool | Annotation | Description |
148
+ |------|------------|-------------|
149
+ | `apimapper_node_snapshot_list` | `readOnly` | List node-level data snapshots (per-flow/per-node cached payloads used by preview hydrate path). |
150
+ | `apimapper_schema_profile` | `readOnly` | Analyse a JSON payload and detect field names, types, nullability, sample values, and candidate `items_path`. |
151
+
152
+ ### Library (Templates) (`library.ts`)
153
+
154
+ | Tool | Annotation | Description |
155
+ |------|------------|-------------|
156
+ | `apimapper_library_activate` | `creating` | Activate a library template — creates a new connection. |
157
+ | `apimapper_library_activated` | `readOnly` | List library items the user has activated (= has a connection for). |
158
+ | `apimapper_library_catalog` | `readOnly` | Fetch the entire library catalog (all categories + items + featured/popular in one shot). |
159
+ | `apimapper_library_categories` | `readOnly` | Fetch all library category slugs + counts. |
160
+ | `apimapper_library_connection_detail` | `readOnly` | Fetch the full connection template (endpoints, default_params, auth scheme) for one library item. |
161
+ | `apimapper_library_deactivate` | `destructive` | Deactivate a library template — deletes the underlying connection. |
162
+ | `apimapper_library_featured` | `readOnly` | Fetch curated/featured library items shown on the catalog landing. |
163
+ | `apimapper_library_list` | `readOnly` | List all library items (connection templates) shipping with API Mapper. |
164
+ | `apimapper_library_popular` | `readOnly` | Fetch most-activated library items. |
165
+
166
+ ### Cache (`cache.ts`)
167
+
168
+ | Tool | Annotation | Description |
169
+ |------|------------|-------------|
170
+ | `apimapper_cache_invalidate` | `mutating` | Trigger admin-cache invalidation via the event bus. Pushes events to all subscribers (Admin-UI BroadcastChannel + render cache). |
171
+ | `apimapper_cache_stats` | `readOnly` | Fetch cache observability stats (hits, misses, ttl distribution, sizes). |
172
+
173
+ ### Settings & Platform (`settings.ts`)
174
+
175
+ | Tool | Annotation | Description |
176
+ |------|------------|-------------|
177
+ | `apimapper_features_get` | `readOnly` | Fetch the feature-flag matrix for the current license tier (Free/Pro/Developer). |
178
+ | `apimapper_health_warnings_dismiss` | `mutating` | Dismiss a specific health-warning banner by ID. |
179
+ | `apimapper_health_warnings_list` | `readOnly` | List active admin health-warnings (banners shown in the Admin UI). |
180
+ | `apimapper_platform_parity` | `readOnly` | Compare feature parity between WordPress and Joomla versions of API Mapper. |
181
+ | `apimapper_settings_get` | `readOnly` | Fetch all API Mapper plugin settings (telemetry, beta_channel, debug flags, etc.). |
182
+ | `apimapper_settings_reset_demo` | `destructive` | Reset demo connections + demo flows back to factory state. Removes user modifications. |
183
+ | `apimapper_settings_update` | `mutating` | Update plugin settings. Only provided keys are changed. Common keys: `beta_channel`, `debug_mode`, `telemetry_enabled`. |
184
+
185
+ ### License (`license.ts`)
186
+
187
+ | Tool | Annotation | Description |
188
+ |------|------------|-------------|
189
+ | `apimapper_license_activate` | `creating` | Activate the API Mapper plugin with a license key. |
190
+ | `apimapper_license_beta_channel` | `mutating` | Enable/disable the beta release channel for this license. |
191
+ | `apimapper_license_deactivate` | `destructive` | Deactivate the license, freeing the activation slot. Plugin reverts to Free tier. |
192
+ | `apimapper_license_refresh` | `mutating` | Refresh the local cache of the license response (no upstream call — faster than revalidate). |
193
+ | `apimapper_license_revalidate` | `mutating` | Force a fresh validation call to the license server (network round-trip). |
194
+ | `apimapper_license_status` | `readOnly` | Fetch the current license tier, expiry, beta-channel state, and feature flags. |
195
+
196
+ ### Composite Workflows (`workflows.ts`)
197
+
198
+ | Tool | Annotation | Description |
199
+ |------|------------|-------------|
200
+ | `apimapper_flow_change_merge_strategy` | `mutating` | Toggle a flow's merge-node strategy (`append` ↔ `coalesce`) and re-compile. |
201
+ | `apimapper_flow_full_recompile_publish` | `mutating` | Compile a flow + invalidate admin cache in one call. Use after upstream API changes. |
202
+ | `apimapper_flow_setup_with_sources` | `creating` | Compose a complete flow from connections in one call. Sequence: create + add sources + compile + (optional) publish. |
203
+
204
+ ### Skill Doc (`get-skill.ts`)
205
+
206
+ | Tool | Annotation | Description |
207
+ |------|------------|-------------|
208
+ | `apimapper_get_skill` | `readOnly` | Returns the markdown content of a bundled API Mapper skill doc. |
209
+
210
+ ### Profiles (`use-profile.ts`)
211
+
212
+ | Tool | Annotation | Description |
213
+ |------|------------|-------------|
214
+ | `apimapper_use_profile` | `readOnly` | Activate a configured site profile and probe its identity endpoint to confirm the site is reachable and the plugin signature matches. |
215
+
216
+ ## Convention reminders
217
+
218
+ - `readOnly` — no side effects; safe to retry.
219
+ - `mutating` — modifies server state (idempotent).
220
+ - `creating` — creates new server state (POST).
221
+ - `destructive` — irreversible. **Always paired with a `confirm: true`
222
+ parameter and a preview guard**, per the Goldstandard.
223
+
224
+ ## Future work
225
+
226
+ - Auto-generate this file in CI via `scripts/extract-tools.mjs` and
227
+ diff against the committed copy as a quality gate.
228
+ - Add per-tool input-schema dumps (currently only name + annotation
229
+ are extracted).
230
+ - Cross-link each tool to its source file with permalink anchors.
package/manifest.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "dxt_version": "0.1",
3
+ "name": "@wootsup/mcp",
4
+ "display_name": "API Mapper for WordPress & Joomla",
5
+ "version": "0.1.0-rc.1",
6
+ "description": "Build API integrations, OAuth credentials, and YOOtheme sources via natural conversation. Connects your AI assistant to API Mapper running on WordPress or Joomla.",
7
+ "author": {
8
+ "name": "WootsUp",
9
+ "url": "https://wootsup.com"
10
+ },
11
+ "homepage": "https://wootsup.com/products/api-mapper",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/wootsup/api-mapper"
15
+ },
16
+ "license": "MIT",
17
+ "keywords": [
18
+ "api-mapper",
19
+ "wordpress",
20
+ "joomla",
21
+ "yootheme",
22
+ "mcp",
23
+ "claude"
24
+ ],
25
+ "server": {
26
+ "type": "node",
27
+ "entry_point": "dist/index.js",
28
+ "mcp_config": {
29
+ "command": "node",
30
+ "args": [
31
+ "${__dirname}/dist/index.js"
32
+ ],
33
+ "env": {
34
+ "APIMAPPER_TOKEN": "${user_config.APIMAPPER_TOKEN}",
35
+ "APIMAPPER_SITE_URL": "${user_config.APIMAPPER_SITE_URL}",
36
+ "APIMAPPER_PLATFORM": "${user_config.APIMAPPER_PLATFORM}"
37
+ }
38
+ }
39
+ },
40
+ "user_config": [
41
+ {
42
+ "key": "APIMAPPER_TOKEN",
43
+ "type": "string",
44
+ "title": "API Mapper MCP key",
45
+ "description": "Your amk_live_... key from API Mapper → Settings → MCP Keys",
46
+ "required": true,
47
+ "secret": true
48
+ },
49
+ {
50
+ "key": "APIMAPPER_SITE_URL",
51
+ "type": "string",
52
+ "title": "Site URL",
53
+ "description": "The base URL of your WordPress or Joomla site (e.g. https://example.com)",
54
+ "required": true
55
+ },
56
+ {
57
+ "key": "APIMAPPER_PLATFORM",
58
+ "type": "string",
59
+ "title": "Platform",
60
+ "description": "Either 'wordpress' or 'joomla'",
61
+ "required": true,
62
+ "default": "wordpress"
63
+ }
64
+ ],
65
+ "compatibility": {
66
+ "claude_desktop": ">=0.10.0",
67
+ "platforms": [
68
+ "darwin",
69
+ "win32",
70
+ "linux"
71
+ ],
72
+ "runtimes": {
73
+ "node": ">=22.0.0"
74
+ }
75
+ }
76
+ }