@wootsup/mcp 0.1.0 → 0.3.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 +148 -83
- package/README.md +31 -27
- package/SECURITY.md +15 -6
- package/dist/auth/keychain.d.ts +27 -1
- package/dist/auth/keychain.js +48 -2
- package/dist/auth/keychain.js.map +1 -1
- package/dist/cli-hint.d.ts +22 -0
- package/dist/cli-hint.js +55 -0
- package/dist/cli-hint.js.map +1 -0
- package/dist/index.js +97 -22
- package/dist/index.js.map +1 -1
- package/dist/install-skill.js +1 -1
- package/dist/modules/apimapper/cache.js +25 -17
- package/dist/modules/apimapper/cache.js.map +1 -1
- package/dist/modules/apimapper/client.d.ts +62 -1
- package/dist/modules/apimapper/client.js +555 -291
- package/dist/modules/apimapper/client.js.map +1 -1
- package/dist/modules/apimapper/connections.js +230 -75
- package/dist/modules/apimapper/connections.js.map +1 -1
- package/dist/modules/apimapper/credential-sanitizer.d.ts +5 -0
- package/dist/modules/apimapper/credential-sanitizer.js +60 -1
- package/dist/modules/apimapper/credential-sanitizer.js.map +1 -1
- package/dist/modules/apimapper/credentials.js +19 -47
- package/dist/modules/apimapper/credentials.js.map +1 -1
- package/dist/modules/apimapper/diagnose.js +21 -2
- package/dist/modules/apimapper/diagnose.js.map +1 -1
- package/dist/modules/apimapper/flows.js +60 -77
- package/dist/modules/apimapper/flows.js.map +1 -1
- package/dist/modules/apimapper/gateway/advanced-tool.js +56 -5
- package/dist/modules/apimapper/gateway/advanced-tool.js.map +1 -1
- package/dist/modules/apimapper/gateway/essentials.d.ts +1 -1
- package/dist/modules/apimapper/gateway/essentials.js +8 -1
- package/dist/modules/apimapper/gateway/essentials.js.map +1 -1
- package/dist/modules/apimapper/get-skill.d.ts +1 -1
- package/dist/modules/apimapper/get-skill.js +44 -6
- package/dist/modules/apimapper/get-skill.js.map +1 -1
- package/dist/modules/apimapper/graph.js +40 -36
- package/dist/modules/apimapper/graph.js.map +1 -1
- package/dist/modules/apimapper/index.js +2 -0
- package/dist/modules/apimapper/index.js.map +1 -1
- package/dist/modules/apimapper/library.js +425 -83
- package/dist/modules/apimapper/library.js.map +1 -1
- package/dist/modules/apimapper/license.js +12 -36
- package/dist/modules/apimapper/license.js.map +1 -1
- package/dist/modules/apimapper/local-sources.js +20 -34
- package/dist/modules/apimapper/local-sources.js.map +1 -1
- package/dist/modules/apimapper/misc.js +13 -27
- package/dist/modules/apimapper/misc.js.map +1 -1
- package/dist/modules/apimapper/onboarding.d.ts +30 -1
- package/dist/modules/apimapper/onboarding.js +114 -19
- package/dist/modules/apimapper/onboarding.js.map +1 -1
- package/dist/modules/apimapper/schema.js +9 -18
- package/dist/modules/apimapper/schema.js.map +1 -1
- package/dist/modules/apimapper/settings.js +49 -52
- package/dist/modules/apimapper/settings.js.map +1 -1
- package/dist/modules/apimapper/sites-tools.d.ts +29 -0
- package/dist/modules/apimapper/sites-tools.js +165 -0
- package/dist/modules/apimapper/sites-tools.js.map +1 -0
- package/dist/modules/apimapper/tool-result.d.ts +46 -0
- package/dist/modules/apimapper/tool-result.js +63 -0
- package/dist/modules/apimapper/tool-result.js.map +1 -0
- package/dist/modules/apimapper/toolslist-size.d.ts +11 -10
- package/dist/modules/apimapper/toolslist-size.js +16 -14
- package/dist/modules/apimapper/toolslist-size.js.map +1 -1
- package/dist/modules/apimapper/types.d.ts +21 -0
- package/dist/modules/apimapper/types.js.map +1 -1
- package/dist/modules/apimapper/whitelist-drift.d.ts +85 -0
- package/dist/modules/apimapper/whitelist-drift.js +360 -0
- package/dist/modules/apimapper/whitelist-drift.js.map +1 -0
- package/dist/modules/apimapper/workflows.js +82 -27
- package/dist/modules/apimapper/workflows.js.map +1 -1
- package/dist/modules/apimapper/yootheme-binding.d.ts +35 -0
- package/dist/modules/apimapper/yootheme-binding.js +186 -0
- package/dist/modules/apimapper/yootheme-binding.js.map +1 -0
- package/dist/platform/index.d.ts +56 -0
- package/dist/platform/index.js +151 -2
- package/dist/platform/index.js.map +1 -1
- package/dist/setup/detect-clients.d.ts +40 -1
- package/dist/setup/detect-clients.js +148 -1
- package/dist/setup/detect-clients.js.map +1 -1
- package/dist/setup/probe-handshake.js +40 -7
- package/dist/setup/probe-handshake.js.map +1 -1
- package/dist/setup/remove-config.d.ts +8 -0
- package/dist/setup/remove-config.js +145 -0
- package/dist/setup/remove-config.js.map +1 -0
- package/dist/setup/uninstall.d.ts +34 -0
- package/dist/setup/uninstall.js +147 -0
- package/dist/setup/uninstall.js.map +1 -0
- package/dist/setup-cli.d.ts +7 -0
- package/dist/setup-cli.js +29 -1
- package/dist/setup-cli.js.map +1 -1
- package/dist/sites/loader.d.ts +41 -0
- package/dist/sites/loader.js +119 -0
- package/dist/sites/loader.js.map +1 -0
- package/dist/sites/schema.d.ts +69 -0
- package/dist/sites/schema.js +71 -0
- package/dist/sites/schema.js.map +1 -0
- package/dist/sites/secret-resolver.d.ts +47 -0
- package/dist/sites/secret-resolver.js +150 -0
- package/dist/sites/secret-resolver.js.map +1 -0
- package/dist/skill-instructions.d.ts +1 -1
- package/dist/skill-instructions.js +5 -0
- package/dist/skill-instructions.js.map +1 -1
- package/dist/transports/stdio.js +4 -4
- package/dist/transports/stdio.js.map +1 -1
- package/dist/uninstall-skill.d.ts +27 -0
- package/dist/uninstall-skill.js +89 -0
- package/dist/uninstall-skill.js.map +1 -0
- package/docs/architecture.md +21 -21
- package/docs/customgraph-internal-migration.md +4 -4
- package/docs/security.md +2 -21
- package/docs/tools.md +40 -12
- package/manifest.json +77 -79
- package/package.json +68 -65
- package/skills/apimapper/SKILL.md +53 -7
- package/skills/apimapper/reference/conditional-style-multi-items.md +114 -0
- package/skills/apimapper/reference/jmespath-pitfalls.md +108 -0
- package/skills/apimapper/reference/joomla.md +1 -1
- package/skills/apimapper/reference/library-template-discovery.md +65 -0
- package/skills/apimapper/reference/merge-two-sources-on-key.md +99 -0
- package/skills/apimapper/reference/troubleshooting.md +20 -0
- package/skills/apimapper/reference/yootheme.md +1 -1
- package/dist/auth/oauth-provider.d.ts +0 -68
- package/dist/auth/oauth-provider.js +0 -232
- package/dist/auth/oauth-provider.js.map +0 -1
- package/dist/server-http.d.ts +0 -22
- package/dist/server-http.js +0 -159
- package/dist/server-http.js.map +0 -1
- package/dist/transports/http.d.ts +0 -29
- package/dist/transports/http.js +0 -267
- package/dist/transports/http.js.map +0 -1
package/dist/cli-hint.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/cli-hint.ts — interactive "this is the MCP stdio server" hint.
|
|
2
|
+
//
|
|
3
|
+
// `npx @wootsup/mcp` with no subcommand boots the stdio MCP server, which
|
|
4
|
+
// then sits silently waiting for JSON-RPC on stdin. An AI client pipes stdin
|
|
5
|
+
// (so the server gets its protocol and works) — but a human running it in a
|
|
6
|
+
// terminal sees nothing and assumes it has hung.
|
|
7
|
+
//
|
|
8
|
+
// We disambiguate purely on `process.stdin.isTTY`:
|
|
9
|
+
// • TTY (interactive human) → no known subcommand means they almost
|
|
10
|
+
// certainly meant `setup` / `uninstall` / `help`; print a hint and exit
|
|
11
|
+
// 0 instead of booting a server they can't talk to.
|
|
12
|
+
// • non-TTY (piped — a real MCP client) → behave EXACTLY as before: boot
|
|
13
|
+
// the server, no hint, no exit. THIS is the load-bearing invariant.
|
|
14
|
+
//
|
|
15
|
+
// The decision is factored out as a pure function so it can be unit-tested
|
|
16
|
+
// without importing index.ts (which boots the server at module load).
|
|
17
|
+
/**
|
|
18
|
+
* Decide whether the bare/unknown-invocation interactive hint should be shown.
|
|
19
|
+
*
|
|
20
|
+
* Returns true ONLY when the invocation is interactive (a TTY on stdin) AND
|
|
21
|
+
* the given subcommand is not a recognised CLI subcommand (either absent —
|
|
22
|
+
* bare `npx @wootsup/mcp` — or an unknown typo).
|
|
23
|
+
*
|
|
24
|
+
* When stdin is NOT a TTY (piped, i.e. a real MCP client) this ALWAYS returns
|
|
25
|
+
* false so the server-boot path is never disturbed.
|
|
26
|
+
*
|
|
27
|
+
* @param subcommand The first positional CLI arg (`process.argv[2]`), or undefined.
|
|
28
|
+
* @param knownSubcommands The set of recognised CLI subcommands.
|
|
29
|
+
* @param isTTY Whether stdin is an interactive terminal (`process.stdin.isTTY`).
|
|
30
|
+
*/
|
|
31
|
+
export function shouldShowInteractiveHint(subcommand, knownSubcommands, isTTY) {
|
|
32
|
+
if (!isTTY)
|
|
33
|
+
return false;
|
|
34
|
+
if (subcommand !== undefined && knownSubcommands.has(subcommand))
|
|
35
|
+
return false;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build the human-facing hint message printed to stderr in interactive mode.
|
|
40
|
+
*
|
|
41
|
+
* When `subcommand` is a non-empty unknown token, the message is prefixed with
|
|
42
|
+
* an "unknown command" line so a typo is called out explicitly.
|
|
43
|
+
*/
|
|
44
|
+
export function buildInteractiveHint(subcommand) {
|
|
45
|
+
const lines = [];
|
|
46
|
+
if (subcommand !== undefined && subcommand.length > 0) {
|
|
47
|
+
lines.push(`unknown command "${subcommand}".`);
|
|
48
|
+
}
|
|
49
|
+
lines.push("This is the API Mapper MCP server (stdio). It's normally launched by your " +
|
|
50
|
+
"AI client, not run directly — that's why it sits here waiting.");
|
|
51
|
+
lines.push("Did you mean: `npx -y @wootsup/mcp setup`?");
|
|
52
|
+
lines.push("See also: `uninstall`, `help`.");
|
|
53
|
+
return lines.join("\n");
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=cli-hint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-hint.js","sourceRoot":"","sources":["../src/cli-hint.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,4EAA4E;AAC5E,iDAAiD;AACjD,EAAE;AACF,mDAAmD;AACnD,uEAAuE;AACvE,4EAA4E;AAC5E,wDAAwD;AACxD,2EAA2E;AAC3E,wEAAwE;AACxE,EAAE;AACF,2EAA2E;AAC3E,sEAAsE;AAEtE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAA8B,EAC9B,gBAAqC,EACrC,KAAc;IAEd,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,UAAU,KAAK,SAAS,IAAI,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAA8B;IACjE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,oBAAoB,UAAU,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,KAAK,CAAC,IAAI,CACR,4EAA4E;QAC1E,gEAAgE,CACnE,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @customgraph/mcp-adapter-apimapper-rest — API Mapper REST MCP Server
|
|
3
|
-
// Full coverage of /wp-json/api-mapper/v1/*
|
|
3
|
+
// Full coverage of /wp-json/api-mapper/v1/* — 79 registered tools (15 module
|
|
4
|
+
// essentials + the apimapper_advanced gateway + 60 advanced-registry tools + 3
|
|
5
|
+
// top-level tools registered below). Only 19 are first-class in tools/list; the
|
|
6
|
+
// 60 advanced tools route through apimapper_advanced to stay under Cursor's ~40
|
|
7
|
+
// surface cap. Canonical counts are asserted in gateway/gateway.test.ts (A2).
|
|
4
8
|
//
|
|
5
9
|
// Auth: API Mapper MCP-key (amk_live_...) generated via the API Mapper
|
|
6
10
|
// admin UI → Settings → MCP Access. The legacy WordPress Application
|
|
@@ -33,10 +37,12 @@ if (process.env.APIMAPPER_SITE_URL && !process.env.APIMAPPER_WP_BASE) {
|
|
|
33
37
|
if (process.env.APIMAPPER_BASE_URL && !process.env.APIMAPPER_WP_BASE) {
|
|
34
38
|
process.env.APIMAPPER_WP_BASE = process.env.APIMAPPER_BASE_URL;
|
|
35
39
|
}
|
|
36
|
-
// APIMAPPER_PLATFORM is consumed by
|
|
37
|
-
// (
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
+
// APIMAPPER_PLATFORM is consumed by client.ts (Phase 1, 2026-06-03): the
|
|
41
|
+
// legacy `request()` path reads it as the explicit env→kind HINT
|
|
42
|
+
// (PLATFORM_KIND) and, when it is unset or "auto", layers a network
|
|
43
|
+
// identity probe on top to auto-detect WordPress vs Joomla. Kept as an
|
|
44
|
+
// explicit no-op read here too so the build-dxt grep gate confirms every
|
|
45
|
+
// user_config key has a runtime consumer — see scripts/build-dxt.js.
|
|
40
46
|
void process.env.APIMAPPER_PLATFORM;
|
|
41
47
|
// APIMAPPER_PROFILE (F-49 / W1.27) — optional profile label for multi-site
|
|
42
48
|
// setups. The setup-cli writes it into the MCP client entry env; the
|
|
@@ -45,6 +51,13 @@ void process.env.APIMAPPER_PLATFORM;
|
|
|
45
51
|
// bridge runs inside main() once the ProfileStore is constructed; see
|
|
46
52
|
// `bootstrapActiveProfile` below for the A6-P3-INTEG-02 wiring + tests.
|
|
47
53
|
void process.env.APIMAPPER_PROFILE;
|
|
54
|
+
// APIMAPPER_SITES_FILE (Phase 3, 2026-06-03) — optional path to a multi-site
|
|
55
|
+
// sites.json (the .dxt one-click / agency path). client.ts reads it lazily
|
|
56
|
+
// (getSitesRegistry) to drive the ACTIVE site's URL/token/platform in
|
|
57
|
+
// request(); main() wires the sites-file-backed profile tools when it loads
|
|
58
|
+
// non-empty. Explicit no-op read here too so the build-dxt grep gate confirms
|
|
59
|
+
// every user_config key has a runtime consumer — see scripts/build-dxt.js.
|
|
60
|
+
void process.env.APIMAPPER_SITES_FILE;
|
|
48
61
|
import { createRequire } from "node:module";
|
|
49
62
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
50
63
|
import { loadModules, formatResult, readOnly } from "@getimo/mcp-toolkit";
|
|
@@ -54,6 +67,9 @@ import { connectStdio } from "./transports/stdio.js";
|
|
|
54
67
|
import { createKeychain } from "./auth/keychain.js";
|
|
55
68
|
import { ProfileStore, resolveConfigDir } from "./auth/profiles.js";
|
|
56
69
|
import { registerUseProfileTool, registerListProfilesTool, } from "./modules/apimapper/use-profile.js";
|
|
70
|
+
import { registerSitesUseProfileTool, registerSitesListProfilesTool, } from "./modules/apimapper/sites-tools.js";
|
|
71
|
+
import { getSitesRegistry, getActiveSiteId, setActiveSite, } from "./modules/apimapper/client.js";
|
|
72
|
+
import { shouldShowInteractiveHint, buildInteractiveHint } from "./cli-hint.js";
|
|
57
73
|
// Single source of truth for the package version (F-41 / W1.23).
|
|
58
74
|
// Reads ../package.json at runtime so we never drift between the manifest
|
|
59
75
|
// version (used by npm + DXT) and what we advertise to MCP clients.
|
|
@@ -141,25 +157,73 @@ server.registerTool("apimapper_rest_modules_status", {
|
|
|
141
157
|
});
|
|
142
158
|
async function main() {
|
|
143
159
|
moduleStatuses = await loadModules(server, [apimapperRestModule]);
|
|
144
|
-
// Profile
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
// file
|
|
148
|
-
//
|
|
149
|
-
//
|
|
160
|
+
// Profile tools for apimapper_use_profile / apimapper_list_profiles.
|
|
161
|
+
//
|
|
162
|
+
// Phase 3 (2026-06-03) — TWO multi-site mechanisms, branched on presence of a
|
|
163
|
+
// sites-file:
|
|
164
|
+
// • APIMAPPER_SITES_FILE set + non-empty → the sites-file IS the profile
|
|
165
|
+
// registry. The tools list its entries and switch the active site via the
|
|
166
|
+
// client's setActiveSite() (which retargets request()). No keychain.
|
|
167
|
+
// • otherwise → the legacy keychain ProfileStore path (the secure
|
|
168
|
+
// single-machine wizard default), unchanged.
|
|
169
|
+
//
|
|
170
|
+
// Best-effort: log + skip if init throws on a locked-down host so the rest of
|
|
171
|
+
// the MCP surface still boots.
|
|
172
|
+
let sitesFileActive = false;
|
|
150
173
|
try {
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
174
|
+
const registry = getSitesRegistry();
|
|
175
|
+
if (registry) {
|
|
176
|
+
sitesFileActive = true;
|
|
177
|
+
// A sites-file is present → honour APIMAPPER_PROFILE as the initial
|
|
178
|
+
// active-site selection (a site_id). Unknown / "default" / unset → leave
|
|
179
|
+
// the file's default entry active. setActiveSite throws on an unknown id,
|
|
180
|
+
// so guard with has() to avoid a phantom selection on a stale env var.
|
|
181
|
+
const desired = process.env.APIMAPPER_PROFILE?.trim();
|
|
182
|
+
if (desired && desired !== "default" && registry.has(desired)) {
|
|
183
|
+
setActiveSite(desired);
|
|
184
|
+
}
|
|
185
|
+
registerSitesListProfilesTool(server, {
|
|
186
|
+
getRegistry: () => {
|
|
187
|
+
const r = getSitesRegistry();
|
|
188
|
+
if (!r)
|
|
189
|
+
throw new Error("sites-file unloaded since boot");
|
|
190
|
+
return r;
|
|
191
|
+
},
|
|
192
|
+
getActiveSiteId,
|
|
193
|
+
});
|
|
194
|
+
registerSitesUseProfileTool(server, {
|
|
195
|
+
getRegistry: () => {
|
|
196
|
+
const r = getSitesRegistry();
|
|
197
|
+
if (!r)
|
|
198
|
+
throw new Error("sites-file unloaded since boot");
|
|
199
|
+
return r;
|
|
200
|
+
},
|
|
201
|
+
setActiveSite,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
160
204
|
}
|
|
161
205
|
catch (err) {
|
|
162
|
-
console.error("[apimapper-rest]
|
|
206
|
+
console.error("[apimapper-rest] sites-file profile tools disabled — sites-file init failed:", err instanceof Error ? err.message : err);
|
|
207
|
+
}
|
|
208
|
+
if (!sitesFileActive) {
|
|
209
|
+
// Keychain ProfileStore path (legacy single-machine default). Phase 5
|
|
210
|
+
// deferred this to the server entrypoint because constructing the keychain
|
|
211
|
+
// is async (probes the OS Secret-Service, falling back to a file impl) and
|
|
212
|
+
// the module-level register() signature is sync.
|
|
213
|
+
try {
|
|
214
|
+
const configDir = resolveConfigDir();
|
|
215
|
+
const keychain = await createKeychain({ configDir });
|
|
216
|
+
const profileStore = new ProfileStore(configDir);
|
|
217
|
+
// A6-P3-INTEG-02: honour APIMAPPER_PROFILE env var. Must run AFTER the
|
|
218
|
+
// ProfileStore is constructed but BEFORE the tools register so any
|
|
219
|
+
// subsequent tool call sees the corrected active pointer.
|
|
220
|
+
await bootstrapActiveProfile(profileStore);
|
|
221
|
+
registerUseProfileTool(server, { store: profileStore, keychain });
|
|
222
|
+
registerListProfilesTool(server, { store: profileStore, keychain });
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
console.error("[apimapper-rest] use-profile tool disabled — keychain/profile init failed:", err instanceof Error ? err.message : err);
|
|
226
|
+
}
|
|
163
227
|
}
|
|
164
228
|
process.stdout.on("error", (err) => {
|
|
165
229
|
if (err.code === "EPIPE" || err.code === "ERR_STREAM_DESTROYED")
|
|
@@ -180,7 +244,7 @@ async function main() {
|
|
|
180
244
|
// lazily inside the subcommand branch so the AI-client startup path
|
|
181
245
|
// stays free of clack/prompts side-effects.
|
|
182
246
|
const subcommand = process.argv[2];
|
|
183
|
-
const CLI_SUBCOMMANDS = new Set(["setup", "install-skill", "install", "help", "--help", "-h"]);
|
|
247
|
+
const CLI_SUBCOMMANDS = new Set(["setup", "install-skill", "install", "uninstall", "remove", "help", "--help", "-h"]);
|
|
184
248
|
if (subcommand && CLI_SUBCOMMANDS.has(subcommand)) {
|
|
185
249
|
void (async () => {
|
|
186
250
|
try {
|
|
@@ -194,6 +258,17 @@ if (subcommand && CLI_SUBCOMMANDS.has(subcommand)) {
|
|
|
194
258
|
}
|
|
195
259
|
})();
|
|
196
260
|
}
|
|
261
|
+
else if (shouldShowInteractiveHint(subcommand, CLI_SUBCOMMANDS, !!process.stdin.isTTY)) {
|
|
262
|
+
// Interactive human ran `npx @wootsup/mcp` (bare) or a typo'd subcommand in
|
|
263
|
+
// a terminal. Booting the stdio server here would just sit waiting for
|
|
264
|
+
// JSON-RPC on stdin and LOOK hung. Print a one-screen hint and exit 0.
|
|
265
|
+
//
|
|
266
|
+
// Load-bearing invariant: when stdin is NOT a TTY (an MCP client pipes it),
|
|
267
|
+
// shouldShowInteractiveHint() returns false and we fall through to main()
|
|
268
|
+
// below — the server-boot path is byte-for-byte unchanged.
|
|
269
|
+
console.error(buildInteractiveHint(subcommand));
|
|
270
|
+
process.exit(0);
|
|
271
|
+
}
|
|
197
272
|
else {
|
|
198
273
|
main().catch((error) => {
|
|
199
274
|
console.error("[apimapper-rest] Fatal error:", error);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,uEAAuE;AACvE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/install-skill.js
CHANGED
|
@@ -18,7 +18,7 @@ const MARKER_BLOCK = `
|
|
|
18
18
|
## API Mapper MCP
|
|
19
19
|
|
|
20
20
|
${MARKER_LINE}
|
|
21
|
-
The API Mapper skill is installed at \`~/.claude/skills/apimapper/\`. Refer to it for flow, connection, OAuth, YOOtheme, and Joomla guidance.
|
|
21
|
+
The API Mapper skill is installed at \`~/.claude/skills/apimapper/\`. Refer to it for flow, connection, OAuth, YOOtheme, and Joomla guidance. Docs: https://wootsup.com/docs/mcp/api-mapper/.
|
|
22
22
|
`;
|
|
23
23
|
function defaultPkgRoot() {
|
|
24
24
|
// <pkg-root>/src/install-skill.ts → up one.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { formatResult, statsResult,
|
|
3
|
-
import { request
|
|
2
|
+
import { formatResult, statsResult, readOnly, destructive, } from "@getimo/mcp-toolkit";
|
|
3
|
+
import { request } from "./client.js";
|
|
4
|
+
import { restErrorResult } from "./tool-result.js";
|
|
4
5
|
// rc.13 Welle 3 (2026-05-20) — cache_stats migrated to the toolkit's
|
|
5
6
|
// statsResult builder; both tools' error branches upgraded to errorResult.
|
|
6
7
|
// The migration is purely additive (text `content` block preserved, `_meta.ui`
|
|
@@ -12,6 +13,16 @@ import { request, hintFor } from "./client.js";
|
|
|
12
13
|
// F-A6-07: canonical PHP enum from CacheInvalidateController::scopeToEvent.
|
|
13
14
|
// Legacy aliases (`flow`, `connection`, `credential`, `user`) are accepted
|
|
14
15
|
// by Wave 1B PHP but the dotted form is the documented contract.
|
|
16
|
+
//
|
|
17
|
+
// Wave-12 F12 (2026-05-31): `yootheme.schema` is a direct-file flush scope
|
|
18
|
+
// that bypasses the InvalidationBus. PHP invokes
|
|
19
|
+
// `YOOthemeSchemaCacheBuster::flushNow()` directly when this scope arrives,
|
|
20
|
+
// deleting `schema-*.{php,gql,error.gql}` from the active YOOtheme theme
|
|
21
|
+
// cache directory. Pairs with Wave-12 F8 — that fix closes the auto-flush
|
|
22
|
+
// gap on flow publish; this scope is the manual escape hatch when a
|
|
23
|
+
// customer hits a stale schema and wants to recompile without re-publishing
|
|
24
|
+
// every flow. See `skills/apimapper/reference/troubleshooting.md` for
|
|
25
|
+
// triage.
|
|
15
26
|
const CACHE_INVALIDATE_SCOPES = [
|
|
16
27
|
"connection.updated",
|
|
17
28
|
"connection.deleted",
|
|
@@ -19,6 +30,7 @@ const CACHE_INVALIDATE_SCOPES = [
|
|
|
19
30
|
"flow.published",
|
|
20
31
|
"user.refresh",
|
|
21
32
|
"user.fetch_data",
|
|
33
|
+
"yootheme.schema",
|
|
22
34
|
];
|
|
23
35
|
// W1.15 (F-27): cap top_keys envelope size — PHP can return arbitrary
|
|
24
36
|
// counts but the MCP response stays bounded for AI-client legibility.
|
|
@@ -30,15 +42,21 @@ export function registerCacheTools(server) {
|
|
|
30
42
|
description: "Publish a cache-invalidation event to the InvalidationBus (Admin-UI BroadcastChannel + render cache). " +
|
|
31
43
|
"Scope is the dotted event id matching the PHP CacheInvalidationEvent subclass. " +
|
|
32
44
|
"Legacy aliases (`flow`, `connection`, `credential`, `user`) are accepted server-side " +
|
|
33
|
-
"but the canonical scopes are documented here." +
|
|
34
|
-
"
|
|
45
|
+
"but the canonical scopes are documented here. " +
|
|
46
|
+
"`yootheme.schema` is a manual escape hatch that directly flushes the YOOtheme GraphQL schema " +
|
|
47
|
+
"cache files (`schema-*.{php,gql,error.gql}`) — use it when a newly-published flow is missing " +
|
|
48
|
+
"from the YOOtheme Builder source list. See troubleshooting topic for triage." +
|
|
49
|
+
"\n\nExamples:" +
|
|
50
|
+
"\n apimapper_cache_invalidate({ scope: 'connection.updated', payload: { connection_id: 'con_abc' } })" +
|
|
51
|
+
"\n apimapper_cache_invalidate({ scope: 'yootheme.schema' }) // force-flush the YT schema cache",
|
|
35
52
|
inputSchema: {
|
|
36
53
|
scope: z
|
|
37
54
|
.enum(CACHE_INVALIDATE_SCOPES)
|
|
38
55
|
.describe("Cache invalidation scope (dotted event id). " +
|
|
39
56
|
"Required payload fields: connection.updated→{connection_id, credential_id?}, " +
|
|
40
57
|
"connection.deleted→{connection_id}, credential.reauth→{credential_id, affected_connection_ids?}, " +
|
|
41
|
-
"flow.published→{flow_id, connection_ids?}, user.refresh→{}, user.fetch_data→{node_id?, connection_id?}
|
|
58
|
+
"flow.published→{flow_id, connection_ids?}, user.refresh→{}, user.fetch_data→{node_id?, connection_id?}, " +
|
|
59
|
+
"yootheme.schema→{} (no payload — direct-file flush, bypasses the InvalidationBus)."),
|
|
42
60
|
payload: z
|
|
43
61
|
.record(z.string(), z.unknown())
|
|
44
62
|
.optional()
|
|
@@ -54,12 +72,7 @@ export function registerCacheTools(server) {
|
|
|
54
72
|
body.payload = payload;
|
|
55
73
|
const r = await request("/cache/admin/invalidate", { method: "POST", body: JSON.stringify(body) });
|
|
56
74
|
if (!r.success) {
|
|
57
|
-
return
|
|
58
|
-
message: r.error ?? "cache invalidation failed",
|
|
59
|
-
code: r.errorCode ?? (r.status ? String(r.status) : undefined),
|
|
60
|
-
suggestion: hintFor(r.errorCode),
|
|
61
|
-
details: { scope, payload_keys: payload ? Object.keys(payload) : [] },
|
|
62
|
-
});
|
|
75
|
+
return restErrorResult(r, { scope, payload_keys: payload ? Object.keys(payload) : [] }, { message: "cache invalidation failed" });
|
|
63
76
|
}
|
|
64
77
|
const ok = r.data?.ok === true;
|
|
65
78
|
return formatResult({
|
|
@@ -83,12 +96,7 @@ export function registerCacheTools(server) {
|
|
|
83
96
|
}, async () => {
|
|
84
97
|
const r = await request("/cache-stats");
|
|
85
98
|
if (!r.success) {
|
|
86
|
-
return
|
|
87
|
-
message: r.error ?? "cache stats failed",
|
|
88
|
-
code: r.errorCode ?? (r.status ? String(r.status) : undefined),
|
|
89
|
-
suggestion: hintFor(r.errorCode),
|
|
90
|
-
details: {},
|
|
91
|
-
});
|
|
99
|
+
return restErrorResult(r, {}, { message: "cache stats failed" });
|
|
92
100
|
}
|
|
93
101
|
const tiers = r.data?.tiers ?? {};
|
|
94
102
|
const admin = tiers.admin ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/modules/apimapper/cache.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/modules/apimapper/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ApiResponse } from "@getimo/mcp-toolkit";
|
|
2
2
|
import { type Platform } from "../../platform/index.js";
|
|
3
|
+
import { type SitesRegistry } from "../../sites/loader.js";
|
|
3
4
|
/**
|
|
4
5
|
* WordPress / Joomla site base URL.
|
|
5
6
|
*
|
|
@@ -45,7 +46,7 @@ export declare function sanitizeErrorString(s: string): string;
|
|
|
45
46
|
* The underlying toolkit `ApiResponse` only carries `{success, data?, error?}`.
|
|
46
47
|
* We wrap each call so we capture the HTTP code via `fetch` and merge.
|
|
47
48
|
*/
|
|
48
|
-
export type ApiErrorCode = "auth" | "not_found" | "rate_limit" | "server" | "network" | "unknown";
|
|
49
|
+
export type ApiErrorCode = "auth" | "not_found" | "conflict" | "rate_limit" | "server" | "network" | "unknown";
|
|
49
50
|
export interface ExtApiResponse<T = unknown> extends ApiResponse<T> {
|
|
50
51
|
status?: number;
|
|
51
52
|
errorCode?: ApiErrorCode;
|
|
@@ -105,6 +106,66 @@ export interface PlatformClient {
|
|
|
105
106
|
*/
|
|
106
107
|
export declare function createPlatformClient(platform: Platform): PlatformClient;
|
|
107
108
|
export declare const PLATFORM_KIND: "wordpress" | "joomla";
|
|
109
|
+
/**
|
|
110
|
+
* Network platform auto-detect. Concurrently probes the WordPress REST identity
|
|
111
|
+
* endpoint and the Joomla com_ajax getIdentity task with the same auth header,
|
|
112
|
+
* and decides which CMS is actually running at WP_BASE:
|
|
113
|
+
*
|
|
114
|
+
* - Joomla wins if its probe is HTTP 200 AND the body parses to
|
|
115
|
+
* `{success:true, data:[{success:true, …}]}` (or `data[0].platform` set).
|
|
116
|
+
* - WordPress wins if its probe is HTTP 200 AND the body is a JSON object
|
|
117
|
+
* that is NOT a `{success:false}` error envelope.
|
|
118
|
+
* - If both look OK (shouldn't happen on a single CMS), prefer the one whose
|
|
119
|
+
* reported identity `.platform` matches its own kind; else WordPress.
|
|
120
|
+
* - If neither answers → return "wordpress" (graceful fallback — no worse
|
|
121
|
+
* than the pre-Phase-1 silent default).
|
|
122
|
+
*
|
|
123
|
+
* All fetch errors are swallowed → fallback. The token is sent on the wire but
|
|
124
|
+
* never logged. Short timeout so a blocked probe host can't stall startup.
|
|
125
|
+
*
|
|
126
|
+
* Phase 3 (2026-06-03): accepts optional `(baseUrl, token)` overrides so a
|
|
127
|
+
* per-site probe (sites-file path) can target the entry's own URL + token. The
|
|
128
|
+
* no-arg call preserves the env-path behaviour exactly (module WP_BASE +
|
|
129
|
+
* probeAuthHeader()).
|
|
130
|
+
*/
|
|
131
|
+
export declare function probePlatform(baseUrl?: string, token?: string): Promise<"wordpress" | "joomla">;
|
|
132
|
+
/**
|
|
133
|
+
* Lazily load + memoize the sites-file registry from APIMAPPER_SITES_FILE.
|
|
134
|
+
* Returns `null` when the env var is unset/empty, the file is absent, or it has
|
|
135
|
+
* zero sites — in all those cases the caller falls through to the env path.
|
|
136
|
+
* A malformed / schema-invalid file throws `SitesFileError` (loud-fail at first
|
|
137
|
+
* use rather than silently degrading multi-site to single-site).
|
|
138
|
+
*/
|
|
139
|
+
export declare function getSitesRegistry(): SitesRegistry | null;
|
|
140
|
+
/**
|
|
141
|
+
* The currently-active site_id, or `null` when none has been explicitly set
|
|
142
|
+
* (the file's default entry is then used) or when no sites-file is loaded.
|
|
143
|
+
*/
|
|
144
|
+
export declare function getActiveSiteId(): string | null;
|
|
145
|
+
/**
|
|
146
|
+
* Switch the active site. Validates that `id` exists in the loaded sites-file
|
|
147
|
+
* registry, updates the in-memory pointer, and resets the resolution memo so
|
|
148
|
+
* the next `request()` re-resolves (URL + token + platform) against the new
|
|
149
|
+
* site. Throws when no sites-file is loaded or the id is unknown — the pointer
|
|
150
|
+
* is NOT changed on error.
|
|
151
|
+
*/
|
|
152
|
+
export declare function setActiveSite(id: string): void;
|
|
153
|
+
/**
|
|
154
|
+
* Drop the memoized platform resolution (and the cached sites-file registry +
|
|
155
|
+
* active-site pointer) so the next `request()` re-resolves from scratch —
|
|
156
|
+
* re-reading APIMAPPER_SITES_FILE, re-running the env-check / network probe.
|
|
157
|
+
*
|
|
158
|
+
* Production callers: invoke after deliberately changing the active selection
|
|
159
|
+
* outside `setActiveSite()` (the tool wiring uses `setActiveSite`, which already
|
|
160
|
+
* resets the memo). Safe to call any time.
|
|
161
|
+
*/
|
|
162
|
+
export declare function resetPlatformResolution(): void;
|
|
163
|
+
/**
|
|
164
|
+
* Test-only alias of {@link resetPlatformResolution}, kept for the existing
|
|
165
|
+
* Phase-1 client tests that reference it by this name. New code should call
|
|
166
|
+
* `resetPlatformResolution()`.
|
|
167
|
+
*/
|
|
168
|
+
export declare function __resetPlatformResolutionForTests(): void;
|
|
108
169
|
/**
|
|
109
170
|
* Issue a request through the toolkit HTTP client + capture HTTP status.
|
|
110
171
|
*
|