@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.
- package/CHANGELOG.md +91 -0
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/SECURITY.md +163 -0
- package/dist/auth/keychain.d.ts +47 -0
- package/dist/auth/keychain.js +262 -0
- package/dist/auth/keychain.js.map +1 -0
- package/dist/auth/oauth-provider.d.ts +68 -0
- package/dist/auth/oauth-provider.js +232 -0
- package/dist/auth/oauth-provider.js.map +1 -0
- package/dist/auth/profiles.d.ts +52 -0
- package/dist/auth/profiles.js +200 -0
- package/dist/auth/profiles.js.map +1 -0
- package/dist/auth/token.d.ts +27 -0
- package/dist/auth/token.js +88 -0
- package/dist/auth/token.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +137 -0
- package/dist/index.js.map +1 -0
- package/dist/install-skill.d.ts +23 -0
- package/dist/install-skill.js +73 -0
- package/dist/install-skill.js.map +1 -0
- package/dist/modules/apimapper/cache.d.ts +2 -0
- package/dist/modules/apimapper/cache.js +71 -0
- package/dist/modules/apimapper/cache.js.map +1 -0
- package/dist/modules/apimapper/client.d.ts +85 -0
- package/dist/modules/apimapper/client.js +523 -0
- package/dist/modules/apimapper/client.js.map +1 -0
- package/dist/modules/apimapper/connections.d.ts +2 -0
- package/dist/modules/apimapper/connections.js +406 -0
- package/dist/modules/apimapper/connections.js.map +1 -0
- package/dist/modules/apimapper/credential-sanitizer.d.ts +7 -0
- package/dist/modules/apimapper/credential-sanitizer.js +70 -0
- package/dist/modules/apimapper/credential-sanitizer.js.map +1 -0
- package/dist/modules/apimapper/credentials.d.ts +2 -0
- package/dist/modules/apimapper/credentials.js +258 -0
- package/dist/modules/apimapper/credentials.js.map +1 -0
- package/dist/modules/apimapper/diagnose.d.ts +18 -0
- package/dist/modules/apimapper/diagnose.js +305 -0
- package/dist/modules/apimapper/diagnose.js.map +1 -0
- package/dist/modules/apimapper/flows.d.ts +2 -0
- package/dist/modules/apimapper/flows.js +372 -0
- package/dist/modules/apimapper/flows.js.map +1 -0
- package/dist/modules/apimapper/get-skill.d.ts +4 -0
- package/dist/modules/apimapper/get-skill.js +88 -0
- package/dist/modules/apimapper/get-skill.js.map +1 -0
- package/dist/modules/apimapper/graph-builder.d.ts +47 -0
- package/dist/modules/apimapper/graph-builder.js +117 -0
- package/dist/modules/apimapper/graph-builder.js.map +1 -0
- package/dist/modules/apimapper/graph.d.ts +2 -0
- package/dist/modules/apimapper/graph.js +117 -0
- package/dist/modules/apimapper/graph.js.map +1 -0
- package/dist/modules/apimapper/index.d.ts +2 -0
- package/dist/modules/apimapper/index.js +43 -0
- package/dist/modules/apimapper/index.js.map +1 -0
- package/dist/modules/apimapper/inspect.d.ts +20 -0
- package/dist/modules/apimapper/inspect.js +86 -0
- package/dist/modules/apimapper/inspect.js.map +1 -0
- package/dist/modules/apimapper/library.d.ts +2 -0
- package/dist/modules/apimapper/library.js +237 -0
- package/dist/modules/apimapper/library.js.map +1 -0
- package/dist/modules/apimapper/license.d.ts +2 -0
- package/dist/modules/apimapper/license.js +142 -0
- package/dist/modules/apimapper/license.js.map +1 -0
- package/dist/modules/apimapper/local-sources.d.ts +2 -0
- package/dist/modules/apimapper/local-sources.js +123 -0
- package/dist/modules/apimapper/local-sources.js.map +1 -0
- package/dist/modules/apimapper/misc.d.ts +2 -0
- package/dist/modules/apimapper/misc.js +149 -0
- package/dist/modules/apimapper/misc.js.map +1 -0
- package/dist/modules/apimapper/node-schema.d.ts +217 -0
- package/dist/modules/apimapper/node-schema.js +218 -0
- package/dist/modules/apimapper/node-schema.js.map +1 -0
- package/dist/modules/apimapper/normalizers.d.ts +13 -0
- package/dist/modules/apimapper/normalizers.js +37 -0
- package/dist/modules/apimapper/normalizers.js.map +1 -0
- package/dist/modules/apimapper/onboarding.d.ts +51 -0
- package/dist/modules/apimapper/onboarding.js +201 -0
- package/dist/modules/apimapper/onboarding.js.map +1 -0
- package/dist/modules/apimapper/schema.d.ts +2 -0
- package/dist/modules/apimapper/schema.js +84 -0
- package/dist/modules/apimapper/schema.js.map +1 -0
- package/dist/modules/apimapper/settings.d.ts +2 -0
- package/dist/modules/apimapper/settings.js +157 -0
- package/dist/modules/apimapper/settings.js.map +1 -0
- package/dist/modules/apimapper/skill-resources.d.ts +4 -0
- package/dist/modules/apimapper/skill-resources.js +85 -0
- package/dist/modules/apimapper/skill-resources.js.map +1 -0
- package/dist/modules/apimapper/types.d.ts +111 -0
- package/dist/modules/apimapper/types.js +14 -0
- package/dist/modules/apimapper/types.js.map +1 -0
- package/dist/modules/apimapper/use-profile.d.ts +34 -0
- package/dist/modules/apimapper/use-profile.js +176 -0
- package/dist/modules/apimapper/use-profile.js.map +1 -0
- package/dist/modules/apimapper/workflows.d.ts +2 -0
- package/dist/modules/apimapper/workflows.js +301 -0
- package/dist/modules/apimapper/workflows.js.map +1 -0
- package/dist/platform/index.d.ts +71 -0
- package/dist/platform/index.js +377 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/server-http.d.ts +22 -0
- package/dist/server-http.js +159 -0
- package/dist/server-http.js.map +1 -0
- package/dist/setup/detect-clients.d.ts +39 -0
- package/dist/setup/detect-clients.js +152 -0
- package/dist/setup/detect-clients.js.map +1 -0
- package/dist/setup/probe-handshake.d.ts +26 -0
- package/dist/setup/probe-handshake.js +159 -0
- package/dist/setup/probe-handshake.js.map +1 -0
- package/dist/setup/write-config.d.ts +25 -0
- package/dist/setup/write-config.js +247 -0
- package/dist/setup/write-config.js.map +1 -0
- package/dist/setup-cli.d.ts +49 -0
- package/dist/setup-cli.js +292 -0
- package/dist/setup-cli.js.map +1 -0
- package/dist/skill-instructions.d.ts +10 -0
- package/dist/skill-instructions.js +68 -0
- package/dist/skill-instructions.js.map +1 -0
- package/dist/transports/http.d.ts +29 -0
- package/dist/transports/http.js +267 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/stdio.d.ts +9 -0
- package/dist/transports/stdio.js +19 -0
- package/dist/transports/stdio.js.map +1 -0
- package/docs/architecture.md +140 -0
- package/docs/customgraph-internal-migration.md +210 -0
- package/docs/security.md +126 -0
- package/docs/tools.md +230 -0
- package/manifest.json +76 -0
- package/package.json +61 -0
- package/skills/apimapper/SKILL.md +57 -0
- package/skills/apimapper/reference/joomla.md +85 -0
- package/skills/apimapper/reference/oauth.md +94 -0
- package/skills/apimapper/reference/troubleshooting.md +123 -0
- package/skills/apimapper/reference/yootheme.md +96 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@wootsup/mcp` will be documented here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
6
|
+
this project uses [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [0.1.0-rc.1] - 2026-05-18 (unreleased)
|
|
9
|
+
|
|
10
|
+
First public release candidate. Ships the full 74-tool MCP surface
|
|
11
|
+
plus a complete setup story (`npx setup` wizard + Claude Desktop DXT
|
|
12
|
+
bundle). Built across Phases 0–10 of the
|
|
13
|
+
`apimapper-mcp-implementation-plan` (vault).
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Stripe-style HMAC-SHA256 auth.** `amk_live_…` / `amk_test_…`
|
|
18
|
+
token format, server-side signing key, identity-probe handshake
|
|
19
|
+
with site-title confirmation in the setup wizard.
|
|
20
|
+
- **WordPress plugin foundation.** REST routes under
|
|
21
|
+
`/wp-json/api-mapper/v1/mcp/*`, key generation UI under
|
|
22
|
+
*API Mapper → Connections → MCP Access*, key list + rotate +
|
|
23
|
+
revoke endpoints.
|
|
24
|
+
- **Joomla plugin foundation.** Mirror surface via `com_ajax`
|
|
25
|
+
envelope; same key lifecycle as WordPress. Joomla envelope unwrap
|
|
26
|
+
is handled by the client layer transparently.
|
|
27
|
+
- **5 admin UI components** for MCP key management: KeyList,
|
|
28
|
+
CreateKey, KeyDetail, RotateKey, RevokeKey — shared between
|
|
29
|
+
WordPress and Joomla via the platform abstraction.
|
|
30
|
+
- **Platform abstraction.** Each MCP tool routes through a single
|
|
31
|
+
platform-router that detects WordPress vs. Joomla from the site
|
|
32
|
+
URL + `APIMAPPER_PLATFORM` env, then dispatches to the correct
|
|
33
|
+
REST shape.
|
|
34
|
+
- **Keychain + Profiles.** OS keychain integration via
|
|
35
|
+
`@napi-rs/keyring` (macOS Keychain, Windows Credential Manager,
|
|
36
|
+
Linux libsecret) with named profile support (`APIMAPPER_PROFILE`)
|
|
37
|
+
and a `0600` file fallback when no keychain is available.
|
|
38
|
+
- **Setup CLI (`apimapper-mcp` binary).** Interactive
|
|
39
|
+
`@clack/prompts` wizard with subcommands: `setup` (default),
|
|
40
|
+
`install-skill`, `help`. Auto-detects Claude Desktop, Claude Code,
|
|
41
|
+
Cursor, VS Code, Cline, Codex. Idempotent config writers; rollback
|
|
42
|
+
on probe failure.
|
|
43
|
+
- **Skills bundling.** `skills/apimapper/SKILL.md` plus four reference
|
|
44
|
+
docs (`oauth.md`, `joomla.md`, `yootheme.md`, `troubleshooting.md`)
|
|
45
|
+
shipped with every install. Resources surfaced via
|
|
46
|
+
`apimapper_get_skill` tool.
|
|
47
|
+
- **Composite tools.** `apimapper_flow_setup_with_sources` (create
|
|
48
|
+
flow + add sources + compile + publish), `apimapper_diagnose`
|
|
49
|
+
(pre-flight: health + license + platform parity + connection probe
|
|
50
|
+
+ recent flow status). Reduces multi-turn back-and-forth for the
|
|
51
|
+
most common workflows.
|
|
52
|
+
- **Multi-transport.** stdio transport (default, local install) plus
|
|
53
|
+
HTTP transport with OAuth 2.0 (PKCE-required, S256) for remote
|
|
54
|
+
consumption. Bearer tokens are site-bound (rejected on origin
|
|
55
|
+
mismatch).
|
|
56
|
+
- **DXT bundle.** `apimapper-mcp.dxt` packaged via `build-dxt.js`
|
|
57
|
+
for one-click Claude Desktop install. User-config keys
|
|
58
|
+
(`APIMAPPER_TOKEN`, `APIMAPPER_SITE_URL`, `APIMAPPER_PLATFORM`)
|
|
59
|
+
bridged into the runtime via env shimming. Build verified with a
|
|
60
|
+
grep-gate that ensures every declared user-config key has a
|
|
61
|
+
runtime consumer.
|
|
62
|
+
- **74 MCP tools** spanning: connections, credentials, flows, graph
|
|
63
|
+
preview/validate, local sources, schema profile, library catalog,
|
|
64
|
+
cache, settings, license, releases, brandfetch, feedback,
|
|
65
|
+
workflows, plus health / onboarding / diagnose / inspect-token /
|
|
66
|
+
use-profile.
|
|
67
|
+
|
|
68
|
+
### Engineering
|
|
69
|
+
|
|
70
|
+
- **Test suite.** 243 tests across 27 files
|
|
71
|
+
(vitest + `tsx watch` dev). Includes a stdio-transport spawn
|
|
72
|
+
smoke-test, HTTP+Bearer transport tests, build-dxt manifest
|
|
73
|
+
invariants, and unit coverage of every register file.
|
|
74
|
+
- **CI matrix.** ubuntu-latest, macos-latest, windows-latest × Node
|
|
75
|
+
22.x, gated by path filter and concurrency-cancel per ref
|
|
76
|
+
(`.github/workflows/apimapper-mcp-ci.yml`).
|
|
77
|
+
- **Publish workflow.** Tag-triggered (`apimapper-mcp-v*`),
|
|
78
|
+
verifies tag-version vs. `package.json#version` before publishing,
|
|
79
|
+
publishes with `--provenance`, uploads DXT bundle to GitHub
|
|
80
|
+
Release (`.github/workflows/apimapper-mcp-publish.yml`).
|
|
81
|
+
|
|
82
|
+
### Known issues
|
|
83
|
+
|
|
84
|
+
- `@getimo/mcp-toolkit@1.0.0` declares a `workspace:*` peer-dep on
|
|
85
|
+
`@pipeline-studio/screenshot-capture` that is unresolvable outside
|
|
86
|
+
the source monorepo. Install with `npm install --legacy-peer-deps`
|
|
87
|
+
(or `npm ci --legacy-peer-deps` in CI). Tracked upstream; will be
|
|
88
|
+
fixed in `@getimo/mcp-toolkit@1.1.0`. Does not affect runtime —
|
|
89
|
+
`npx @wootsup/mcp` and the DXT bundle work without intervention.
|
|
90
|
+
|
|
91
|
+
[0.1.0-rc.1]: https://github.com/wootsup/api-mapper/releases/tag/apimapper-mcp-v0.1.0-rc.1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WootsUp / getimo productions
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# @wootsup/mcp
|
|
2
|
+
|
|
3
|
+
**Build YOOtheme dynamic content via natural conversation.** The official MCP
|
|
4
|
+
server for [API Mapper](https://wootsup.com/products/api-mapper) — connect
|
|
5
|
+
your AI assistant to API Mapper running on WordPress or Joomla, then create
|
|
6
|
+
flows, manage OAuth credentials, and publish sources without leaving the
|
|
7
|
+
chat.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@wootsup/mcp)
|
|
10
|
+
[](https://github.com/wootsup/api-mapper/actions/workflows/apimapper-mcp-ci.yml)
|
|
11
|
+
[](./LICENSE)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
Two paths, pick one.
|
|
18
|
+
|
|
19
|
+
### Option A — `npx` (Claude Code, Cursor, VS Code, Cline, Codex, ChatGPT)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx -y @wootsup/mcp setup
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The interactive wizard:
|
|
26
|
+
|
|
27
|
+
1. Asks which AI client(s) you use (auto-detected when possible).
|
|
28
|
+
2. Prompts for your API Mapper site URL and MCP key.
|
|
29
|
+
3. Runs an identity-probe handshake against your site.
|
|
30
|
+
4. Patches the client's MCP config (`~/.claude.json`, `~/.cursor/mcp.json`,
|
|
31
|
+
VS Code `settings.json`, etc.) idempotently.
|
|
32
|
+
5. Installs the bundled skill to `~/.claude/skills/apimapper/`.
|
|
33
|
+
|
|
34
|
+
Re-run any time — writers are idempotent. Use `--help` to see all
|
|
35
|
+
subcommands.
|
|
36
|
+
|
|
37
|
+
### Option B — Claude Desktop (DXT bundle)
|
|
38
|
+
|
|
39
|
+
1. Download `apimapper-mcp.dxt` from the latest
|
|
40
|
+
[GitHub Release](https://github.com/wootsup/api-mapper/releases?q=apimapper-mcp).
|
|
41
|
+
2. Drag it onto the Claude Desktop window (or **Settings → Developer →
|
|
42
|
+
Install from file**).
|
|
43
|
+
3. Enter your site URL, MCP key, and platform when prompted.
|
|
44
|
+
|
|
45
|
+
## Setup (3 steps)
|
|
46
|
+
|
|
47
|
+
1. **Install the API Mapper plugin** on your site:
|
|
48
|
+
- **WordPress:** plugin from
|
|
49
|
+
[wootsup.com](https://wootsup.com/products/api-mapper)
|
|
50
|
+
- **Joomla:** extension from
|
|
51
|
+
[wootsup.com](https://wootsup.com/products/api-mapper)
|
|
52
|
+
2. **Generate an MCP key** in the admin:
|
|
53
|
+
- WordPress: click **API Mapper** in the WP admin menu — the flow
|
|
54
|
+
editor opens. In the editor header (top-right), click the **⋮**
|
|
55
|
+
(three-dot) menu → **Settings**. In the modal's left sidebar,
|
|
56
|
+
click **MCP Access** → **New API key**.
|
|
57
|
+
- Joomla: **Components → API Mapper** loads the same editor — use
|
|
58
|
+
the same **⋮** → **Settings** → **MCP Access** path.
|
|
59
|
+
- Token shape: `amk_live_…` (production) or `amk_test_…` (sandbox).
|
|
60
|
+
3. **Run `npx -y @wootsup/mcp setup`** (or install the DXT) and paste
|
|
61
|
+
the key. The wizard verifies it with an HMAC-SHA256 identity probe
|
|
62
|
+
before writing config.
|
|
63
|
+
|
|
64
|
+
Verify in your AI client:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
You: apimapper_health
|
|
68
|
+
LLM: ✅ status: ok, platform: wordpress, version: 2.0.7
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Common tools
|
|
72
|
+
|
|
73
|
+
A small set of high-leverage tools — the full 74-tool surface is
|
|
74
|
+
[documented in detail in the bundled skill](./skills/apimapper/SKILL.md).
|
|
75
|
+
|
|
76
|
+
| Tool | What it does |
|
|
77
|
+
|------|--------------|
|
|
78
|
+
| `apimapper_health` | Connectivity + auth probe. **Run this first.** |
|
|
79
|
+
| `apimapper_onboarding` | Lists platform, existing flows, next-step suggestions. |
|
|
80
|
+
| `apimapper_flow_setup_with_sources` | Composite: create flow + add sources + compile + publish. |
|
|
81
|
+
| `apimapper_connection_list` | List connections (paginated, table-formatted). |
|
|
82
|
+
| `apimapper_credential_create` | Add OAuth or Bearer credentials. |
|
|
83
|
+
| `apimapper_oauth_authorize_begin` | Start an OAuth 2.0 PKCE flow. |
|
|
84
|
+
| `apimapper_graph_preview` | Preview a flow's output without saving. |
|
|
85
|
+
| `apimapper_library_catalog` | Browse pre-built connection templates. |
|
|
86
|
+
| `apimapper_get_skill` | Fetch the bundled skill text on demand. |
|
|
87
|
+
|
|
88
|
+
See [`skills/apimapper/SKILL.md`](./skills/apimapper/SKILL.md) for the
|
|
89
|
+
canonical workflow guide, and
|
|
90
|
+
[`skills/apimapper/reference/`](./skills/apimapper/reference/) for OAuth,
|
|
91
|
+
Joomla, YOOtheme, and troubleshooting deep-dives.
|
|
92
|
+
|
|
93
|
+
## Multi-platform: WordPress and Joomla
|
|
94
|
+
|
|
95
|
+
Every tool routes through a platform abstraction that detects WordPress
|
|
96
|
+
(`/wp-json/api-mapper/v1/*`) vs. Joomla (`/index.php?option=com_apimapper`)
|
|
97
|
+
from the site URL and platform setting. You write the same prompt; the
|
|
98
|
+
server speaks the right dialect — including the Joomla `com_ajax`
|
|
99
|
+
envelope unwrap.
|
|
100
|
+
|
|
101
|
+
## Multi-client
|
|
102
|
+
|
|
103
|
+
Supported AI clients (auto-detected by the setup wizard):
|
|
104
|
+
|
|
105
|
+
- **Claude Desktop** — DXT bundle or `~/Library/Application Support/Claude/`
|
|
106
|
+
- **Claude Code** — `~/.claude.json`
|
|
107
|
+
- **Cursor** — `~/.cursor/mcp.json` (or project-local `.cursor/mcp.json`)
|
|
108
|
+
- **VS Code** — workspace `.vscode/settings.json` `mcp.servers`
|
|
109
|
+
- **Cline** — VS Code extension settings
|
|
110
|
+
- **Codex** — `~/.config/codex/mcp.json`
|
|
111
|
+
- **ChatGPT Desktop** — when MCP support ships
|
|
112
|
+
|
|
113
|
+
Both transports are supported: **stdio** (default, local install) and
|
|
114
|
+
**HTTP + OAuth 2.0** (remote use, see [`docs/architecture.md`](./docs/architecture.md)).
|
|
115
|
+
|
|
116
|
+
## Known issues
|
|
117
|
+
|
|
118
|
+
### `npm install` requires `--legacy-peer-deps` (developer-only)
|
|
119
|
+
|
|
120
|
+
**Most users don't need this.** If you install via:
|
|
121
|
+
|
|
122
|
+
- `npx @wootsup/mcp setup` — no action required.
|
|
123
|
+
- DXT bundle drag-and-drop into Claude Desktop — no action required.
|
|
124
|
+
- Claude Desktop one-click install — no action required.
|
|
125
|
+
|
|
126
|
+
…you can skip this section entirely. The `npx` and DXT paths ship a
|
|
127
|
+
pre-resolved dependency tree (no peer-dep resolution happens at install
|
|
128
|
+
or runtime), so the issue below cannot bite you.
|
|
129
|
+
|
|
130
|
+
**For developers who clone this repo:**
|
|
131
|
+
|
|
132
|
+
The dependency `@getimo/mcp-toolkit@1.0.0` declares a peer-dep on
|
|
133
|
+
`@pipeline-studio/screenshot-capture` with the `workspace:*` protocol.
|
|
134
|
+
That protocol is unresolvable outside the source monorepo, so a vanilla
|
|
135
|
+
`npm install` fails with `EUNSUPPORTEDPROTOCOL`. Workaround:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
npm install --legacy-peer-deps # local dev
|
|
139
|
+
npm ci --legacy-peer-deps # CI
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Tracked in the customgraph repo — fix lands in `@getimo/mcp-toolkit@1.0.1`,
|
|
143
|
+
at which point this section will be removed.
|
|
144
|
+
|
|
145
|
+
## Troubleshooting
|
|
146
|
+
|
|
147
|
+
See [`skills/apimapper/reference/troubleshooting.md`](./skills/apimapper/reference/troubleshooting.md).
|
|
148
|
+
Common cases:
|
|
149
|
+
|
|
150
|
+
- `403 invalid_token` → token expired or wrong site URL. Re-run setup.
|
|
151
|
+
- `404` on every tool → plugin not installed or REST routes disabled.
|
|
152
|
+
- Joomla `0` envelope → SEF/htaccess intercepting `com_ajax`; check
|
|
153
|
+
the reference doc.
|
|
154
|
+
|
|
155
|
+
## Contributing
|
|
156
|
+
|
|
157
|
+
PRs welcome. Source lives at
|
|
158
|
+
[github.com/wootsup/api-mapper](https://github.com/wootsup/api-mapper)
|
|
159
|
+
in `packages/apimapper-mcp/`. Run `npm test --workspace=@wootsup/mcp`
|
|
160
|
+
before opening a PR; the cross-platform CI matrix
|
|
161
|
+
([`apimapper-mcp-ci.yml`](../../.github/workflows/apimapper-mcp-ci.yml))
|
|
162
|
+
re-runs on ubuntu, macOS, and windows.
|
|
163
|
+
|
|
164
|
+
For the security disclosure process, see [`SECURITY.md`](./SECURITY.md).
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
[MIT](./LICENSE) © 2026 WootsUp / getimo productions.
|
|
169
|
+
|
|
170
|
+
## Links
|
|
171
|
+
|
|
172
|
+
- **Homepage:** <https://wootsup.com/products/api-mapper>
|
|
173
|
+
- **Plugin (WordPress + Joomla):** <https://wootsup.com/products/api-mapper>
|
|
174
|
+
- **Docs:** <https://docs.wootsup.com>
|
|
175
|
+
- **Issues:** <https://github.com/wootsup/api-mapper/issues>
|
|
176
|
+
- **Architecture:** [`docs/architecture.md`](./docs/architecture.md)
|
|
177
|
+
- **Security model:** [`docs/security.md`](./docs/security.md)
|
|
178
|
+
- **Tools reference:** [`docs/tools.md`](./docs/tools.md)
|
|
179
|
+
- **Changelog:** [`CHANGELOG.md`](./CHANGELOG.md)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Email **security@wootsup.com** with details. We aim to respond within
|
|
6
|
+
72 hours.
|
|
7
|
+
|
|
8
|
+
Please do not open public GitHub issues for security problems. If your
|
|
9
|
+
report is accepted we will coordinate disclosure and credit you in the
|
|
10
|
+
release notes (opt-in).
|
|
11
|
+
|
|
12
|
+
PGP key: available on request.
|
|
13
|
+
|
|
14
|
+
## Supported versions
|
|
15
|
+
|
|
16
|
+
We patch security issues in the latest minor of `@wootsup/mcp`.
|
|
17
|
+
During the `0.x` development line, only the most recent published
|
|
18
|
+
version is supported.
|
|
19
|
+
|
|
20
|
+
| Version | Supported |
|
|
21
|
+
|---------|-----------|
|
|
22
|
+
| `0.1.x` | ✅ active |
|
|
23
|
+
| `< 0.1` | ❌ not yet published |
|
|
24
|
+
|
|
25
|
+
When `1.0.0` lands, the previous minor (`0.x`) will receive critical
|
|
26
|
+
security patches for 6 months.
|
|
27
|
+
|
|
28
|
+
## Authentication model
|
|
29
|
+
|
|
30
|
+
`@wootsup/mcp` uses a **Stripe-style HMAC-SHA256 token system**.
|
|
31
|
+
|
|
32
|
+
### Token format
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
amk_<env>_<hex-key-id>.<base64url-signature>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- `amk_live_…` — production keys (full scope).
|
|
39
|
+
- `amk_test_…` — sandbox keys (limited rate, no destructive ops).
|
|
40
|
+
|
|
41
|
+
Tokens carry an embedded HMAC signed by a server-side signing key. The
|
|
42
|
+
server validates the signature on every request before any business
|
|
43
|
+
logic runs — there is no "user lookup by token string". This means a
|
|
44
|
+
compromised replica of the database cannot mint valid tokens without
|
|
45
|
+
also possessing the signing key.
|
|
46
|
+
|
|
47
|
+
### Server-only signing key
|
|
48
|
+
|
|
49
|
+
The signing key is generated on plugin install, stored once in:
|
|
50
|
+
|
|
51
|
+
- **WordPress:** `wp_options.apimapper_signing_key` (autoload = false)
|
|
52
|
+
- **Joomla:** `#__apimapper_settings.signing_key`
|
|
53
|
+
|
|
54
|
+
It is **never** returned by any REST endpoint, never logged, never
|
|
55
|
+
echoed in tool responses, and never written to the `@wootsup/mcp`
|
|
56
|
+
keychain. The MCP server only sees the public token string.
|
|
57
|
+
|
|
58
|
+
### Identity probe (anti-phishing)
|
|
59
|
+
|
|
60
|
+
Before the setup wizard writes any config file, it issues a
|
|
61
|
+
`GET /api-mapper/v1/mcp/identity` request. The server responds with:
|
|
62
|
+
|
|
63
|
+
- the public `key_id`,
|
|
64
|
+
- a `siteSignature` (HMAC over `key_id + site_url + nonce`),
|
|
65
|
+
- and the user-visible site title.
|
|
66
|
+
|
|
67
|
+
The wizard re-computes the signature using the public token payload and
|
|
68
|
+
displays the site title + URL to the user for confirmation. A
|
|
69
|
+
copy-pasted token from a malicious actor cannot pass this probe because
|
|
70
|
+
the malicious server cannot forge the signature without the genuine
|
|
71
|
+
signing key.
|
|
72
|
+
|
|
73
|
+
### Scope semantics
|
|
74
|
+
|
|
75
|
+
Tokens carry an embedded scope list:
|
|
76
|
+
|
|
77
|
+
- `read` — list/get/inspect tools.
|
|
78
|
+
- `write` — create/update/compile.
|
|
79
|
+
- `destructive` — delete, reset-demo, license-deactivate.
|
|
80
|
+
- `oauth` — credential creation + OAuth begin.
|
|
81
|
+
|
|
82
|
+
Server-side enforcement runs **before** the platform abstraction layer.
|
|
83
|
+
Frontend tool-listing additionally filters tools by available scopes,
|
|
84
|
+
so an LLM with a read-only token never sees destructive tools in its
|
|
85
|
+
tool-list (eliminates one class of confused-deputy risk).
|
|
86
|
+
|
|
87
|
+
### No-secret-leak guarantees
|
|
88
|
+
|
|
89
|
+
| Endpoint / Tool | Returns token? |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `GET /mcp/keys` (list) | ❌ key IDs + scopes + last-used only. **Never** the token string. |
|
|
92
|
+
| `POST /mcp/keys` (create) | ✅ **Only on creation.** Subsequent reads cannot retrieve it. |
|
|
93
|
+
| `apimapper_credential_*` | ❌ Stored OAuth/Bearer creds are returned with values redacted (`***`). |
|
|
94
|
+
| `apimapper_inspect_token` | Returns the **decoded payload** (key_id, scopes, env) but **not** the signature. |
|
|
95
|
+
| `apimapper_settings_get` | Always strips `signing_key`, OAuth client secrets, and Brandfetch keys. |
|
|
96
|
+
|
|
97
|
+
Server-side, the `CredentialSanitizer` runs on every response that
|
|
98
|
+
could possibly contain a credential value — see
|
|
99
|
+
[`src/modules/apimapper/credential-sanitizer.ts`](./src/modules/apimapper/credential-sanitizer.ts).
|
|
100
|
+
Unit tests pin the redaction surface.
|
|
101
|
+
|
|
102
|
+
### Token rotation
|
|
103
|
+
|
|
104
|
+
- Rotate any time from **API Mapper → Connections → MCP Access →
|
|
105
|
+
Rotate**.
|
|
106
|
+
- Old tokens revoke immediately. The MCP server returns
|
|
107
|
+
`403 invalid_token` on the next request; the user re-runs
|
|
108
|
+
`npx @wootsup/mcp setup`.
|
|
109
|
+
- Rotation does **not** rotate the server-side signing key. The
|
|
110
|
+
signing key is rotated only on explicit "Reset all keys" — a
|
|
111
|
+
destructive op that requires re-issuing every active token.
|
|
112
|
+
|
|
113
|
+
### Token revocation
|
|
114
|
+
|
|
115
|
+
- Single token: **API Mapper → Connections → MCP Access → Revoke**.
|
|
116
|
+
- All tokens: **API Mapper → Connections → MCP Access → Revoke all**
|
|
117
|
+
(also rotates the signing key).
|
|
118
|
+
- Both operations are immediate; there is no caching of token validity
|
|
119
|
+
on the MCP server side.
|
|
120
|
+
|
|
121
|
+
### Keychain fallback
|
|
122
|
+
|
|
123
|
+
When OS keychain (`@napi-rs/keyring`) is unavailable (some Linux
|
|
124
|
+
distros, CI containers), tokens fall back to a profile file at
|
|
125
|
+
`~/.config/apimapper-mcp/profiles/<name>.json` with mode `0600`. The
|
|
126
|
+
file is plain JSON containing the token string — readable by the user
|
|
127
|
+
account only. If you operate in a hostile multi-user environment,
|
|
128
|
+
**use the OS keychain path** (the default on macOS and Windows).
|
|
129
|
+
|
|
130
|
+
### OAuth 2.0 (HTTP transport)
|
|
131
|
+
|
|
132
|
+
When `@wootsup/mcp` runs in HTTP mode (`server-http.ts`), it acts as
|
|
133
|
+
both an MCP server and an OAuth 2.0 authorization server with **PKCE
|
|
134
|
+
required** (RFC 7636 S256). No implicit flow, no `code` grant without
|
|
135
|
+
PKCE. Bearer tokens are bound to the issuing site URL and rejected if
|
|
136
|
+
the `Origin` header differs.
|
|
137
|
+
|
|
138
|
+
## Threat model summary
|
|
139
|
+
|
|
140
|
+
| Threat | Mitigation |
|
|
141
|
+
|---|---|
|
|
142
|
+
| Token leak via logs | Sanitizer strips on every response path; tokens never logged. |
|
|
143
|
+
| Token leak via tool output | List endpoints structurally exclude the token string. |
|
|
144
|
+
| Replay across sites | HMAC includes site URL; cross-site replay fails sig check. |
|
|
145
|
+
| Forged tokens | Server-side signing key never leaves the install. |
|
|
146
|
+
| Phishing setup link | Identity probe + site-title confirmation in wizard. |
|
|
147
|
+
| Confused-deputy / over-privileged LLM | Scope filter excludes destructive tools from token-restricted lists. |
|
|
148
|
+
| Local-fs token theft (no keychain) | `0600` perms on profile file; keychain default on macOS/Windows. |
|
|
149
|
+
|
|
150
|
+
See [`docs/security.md`](./docs/security.md) for the long-form threat
|
|
151
|
+
model.
|
|
152
|
+
|
|
153
|
+
## Disclosure timeline
|
|
154
|
+
|
|
155
|
+
| Day | Action |
|
|
156
|
+
|---|---|
|
|
157
|
+
| 0 | Report received. Acknowledgement within 72h. |
|
|
158
|
+
| 0-14 | Triage + reproduction + patch development. |
|
|
159
|
+
| 14-30 | Coordinated patch release + security advisory. |
|
|
160
|
+
| 30+ | Public disclosure (CVE if applicable). |
|
|
161
|
+
|
|
162
|
+
For critical issues (active exploitation, supply chain) we will
|
|
163
|
+
expedite and ship out-of-band.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface Keychain {
|
|
2
|
+
set(ref: string, value: string): Promise<void>;
|
|
3
|
+
get(ref: string): Promise<string | null>;
|
|
4
|
+
delete(ref: string): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export declare class SystemKeychain implements Keychain {
|
|
7
|
+
private readonly service;
|
|
8
|
+
constructor(service?: string);
|
|
9
|
+
set(ref: string, value: string): Promise<void>;
|
|
10
|
+
get(ref: string): Promise<string | null>;
|
|
11
|
+
delete(ref: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare class EncryptedFileKeychain implements Keychain {
|
|
14
|
+
private readonly dir;
|
|
15
|
+
private readonly vaultPath;
|
|
16
|
+
private readonly saltPath;
|
|
17
|
+
private cachedKey?;
|
|
18
|
+
private writeChain;
|
|
19
|
+
constructor(configDir: string);
|
|
20
|
+
private deriveKey;
|
|
21
|
+
private readVault;
|
|
22
|
+
private writeVault;
|
|
23
|
+
private encrypt;
|
|
24
|
+
private decrypt;
|
|
25
|
+
set(ref: string, value: string): Promise<void>;
|
|
26
|
+
get(ref: string): Promise<string | null>;
|
|
27
|
+
delete(ref: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export interface CreateKeychainOptions {
|
|
30
|
+
/** Directory holding the encrypted vault + salt for the file fallback. */
|
|
31
|
+
configDir: string;
|
|
32
|
+
/**
|
|
33
|
+
* Override for tests — injecting a throwing or stub System ctor exercises
|
|
34
|
+
* the fallback / preference logic deterministically. Defaults to the real
|
|
35
|
+
* SystemKeychain.
|
|
36
|
+
*/
|
|
37
|
+
systemKeychainCtor?: typeof SystemKeychain;
|
|
38
|
+
/** Service name passed to SystemKeychain. Defaults to "@wootsup/mcp". */
|
|
39
|
+
service?: string;
|
|
40
|
+
/**
|
|
41
|
+
* When false (default), the factory writes a one-line warning to stderr if
|
|
42
|
+
* it falls back to the file impl. Tests set this to true to keep output
|
|
43
|
+
* clean.
|
|
44
|
+
*/
|
|
45
|
+
silent?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function createKeychain(opts: CreateKeychainOptions): Promise<Keychain>;
|