@wootsup/mcp 0.3.0 → 0.4.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.
Files changed (141) hide show
  1. package/CHANGELOG.md +14 -5
  2. package/dist/catalog/build-catalog.d.ts +31 -0
  3. package/dist/catalog/build-catalog.js +68 -0
  4. package/dist/catalog/build-catalog.js.map +1 -0
  5. package/dist/index.js +37 -5
  6. package/dist/index.js.map +1 -1
  7. package/dist/modules/apimapper/auto-layout.d.ts +21 -0
  8. package/dist/modules/apimapper/auto-layout.js +54 -0
  9. package/dist/modules/apimapper/auto-layout.js.map +1 -0
  10. package/dist/modules/apimapper/client.d.ts +54 -4
  11. package/dist/modules/apimapper/client.js +145 -14
  12. package/dist/modules/apimapper/client.js.map +1 -1
  13. package/dist/modules/apimapper/connections-format.d.ts +31 -1
  14. package/dist/modules/apimapper/connections-format.js +97 -5
  15. package/dist/modules/apimapper/connections-format.js.map +1 -1
  16. package/dist/modules/apimapper/connections.d.ts +9 -7
  17. package/dist/modules/apimapper/connections.js +225 -58
  18. package/dist/modules/apimapper/connections.js.map +1 -1
  19. package/dist/modules/apimapper/credentials.js +86 -14
  20. package/dist/modules/apimapper/credentials.js.map +1 -1
  21. package/dist/modules/apimapper/elicitation.d.ts +29 -0
  22. package/dist/modules/apimapper/elicitation.js +62 -0
  23. package/dist/modules/apimapper/elicitation.js.map +1 -1
  24. package/dist/modules/apimapper/example-extract.d.ts +13 -0
  25. package/dist/modules/apimapper/example-extract.js +111 -0
  26. package/dist/modules/apimapper/example-extract.js.map +1 -0
  27. package/dist/modules/apimapper/filter-operators.d.ts +24 -0
  28. package/dist/modules/apimapper/filter-operators.js +103 -0
  29. package/dist/modules/apimapper/filter-operators.js.map +1 -0
  30. package/dist/modules/apimapper/flows-format.js +92 -22
  31. package/dist/modules/apimapper/flows-format.js.map +1 -1
  32. package/dist/modules/apimapper/flows.d.ts +8 -7
  33. package/dist/modules/apimapper/flows.js +216 -44
  34. package/dist/modules/apimapper/flows.js.map +1 -1
  35. package/dist/modules/apimapper/gateway/advanced-read-tool.d.ts +9 -0
  36. package/dist/modules/apimapper/gateway/advanced-read-tool.js +172 -0
  37. package/dist/modules/apimapper/gateway/advanced-read-tool.js.map +1 -0
  38. package/dist/modules/apimapper/gateway/advanced-tool.js +39 -130
  39. package/dist/modules/apimapper/gateway/advanced-tool.js.map +1 -1
  40. package/dist/modules/apimapper/gateway/collect-module-tools.d.ts +17 -0
  41. package/dist/modules/apimapper/gateway/collect-module-tools.js +44 -0
  42. package/dist/modules/apimapper/gateway/collect-module-tools.js.map +1 -0
  43. package/dist/modules/apimapper/gateway/essentials.d.ts +1 -1
  44. package/dist/modules/apimapper/gateway/essentials.js +19 -7
  45. package/dist/modules/apimapper/gateway/essentials.js.map +1 -1
  46. package/dist/modules/apimapper/gateway/gateway-shared.d.ts +21 -0
  47. package/dist/modules/apimapper/gateway/gateway-shared.js +124 -0
  48. package/dist/modules/apimapper/gateway/gateway-shared.js.map +1 -0
  49. package/dist/modules/apimapper/gateway/test-support.d.ts +1 -17
  50. package/dist/modules/apimapper/gateway/test-support.js +4 -33
  51. package/dist/modules/apimapper/gateway/test-support.js.map +1 -1
  52. package/dist/modules/apimapper/get-skill-cores.d.ts +4 -0
  53. package/dist/modules/apimapper/get-skill-cores.js +220 -0
  54. package/dist/modules/apimapper/get-skill-cores.js.map +1 -0
  55. package/dist/modules/apimapper/get-skill.d.ts +1 -1
  56. package/dist/modules/apimapper/get-skill.js +30 -3
  57. package/dist/modules/apimapper/get-skill.js.map +1 -1
  58. package/dist/modules/apimapper/graph-builder.d.ts +85 -2
  59. package/dist/modules/apimapper/graph-builder.js +151 -15
  60. package/dist/modules/apimapper/graph-builder.js.map +1 -1
  61. package/dist/modules/apimapper/graph.js +115 -15
  62. package/dist/modules/apimapper/graph.js.map +1 -1
  63. package/dist/modules/apimapper/index.js +25 -13
  64. package/dist/modules/apimapper/index.js.map +1 -1
  65. package/dist/modules/apimapper/jmespath-test.d.ts +4 -0
  66. package/dist/modules/apimapper/jmespath-test.js +152 -0
  67. package/dist/modules/apimapper/jmespath-test.js.map +1 -0
  68. package/dist/modules/apimapper/library.js +131 -8
  69. package/dist/modules/apimapper/library.js.map +1 -1
  70. package/dist/modules/apimapper/list-footer.d.ts +27 -0
  71. package/dist/modules/apimapper/list-footer.js +57 -0
  72. package/dist/modules/apimapper/list-footer.js.map +1 -0
  73. package/dist/modules/apimapper/local-sources.js +88 -31
  74. package/dist/modules/apimapper/local-sources.js.map +1 -1
  75. package/dist/modules/apimapper/mcp-client-identity.d.ts +32 -0
  76. package/dist/modules/apimapper/mcp-client-identity.js +70 -0
  77. package/dist/modules/apimapper/mcp-client-identity.js.map +1 -0
  78. package/dist/modules/apimapper/merge-constants.d.ts +6 -0
  79. package/dist/modules/apimapper/merge-constants.js +26 -0
  80. package/dist/modules/apimapper/merge-constants.js.map +1 -0
  81. package/dist/modules/apimapper/node-schema.d.ts +52 -2
  82. package/dist/modules/apimapper/node-schema.js +95 -4
  83. package/dist/modules/apimapper/node-schema.js.map +1 -1
  84. package/dist/modules/apimapper/onboarding.d.ts +29 -0
  85. package/dist/modules/apimapper/onboarding.js +117 -9
  86. package/dist/modules/apimapper/onboarding.js.map +1 -1
  87. package/dist/modules/apimapper/read-cache.d.ts +16 -3
  88. package/dist/modules/apimapper/read-cache.js +59 -4
  89. package/dist/modules/apimapper/read-cache.js.map +1 -1
  90. package/dist/modules/apimapper/render/index.js +26 -5
  91. package/dist/modules/apimapper/render/index.js.map +1 -1
  92. package/dist/modules/apimapper/resource-id.d.ts +13 -0
  93. package/dist/modules/apimapper/resource-id.js +69 -0
  94. package/dist/modules/apimapper/resource-id.js.map +1 -0
  95. package/dist/modules/apimapper/tool-result.d.ts +20 -0
  96. package/dist/modules/apimapper/tool-result.js +67 -5
  97. package/dist/modules/apimapper/tool-result.js.map +1 -1
  98. package/dist/modules/apimapper/toolslist-size.d.ts +10 -10
  99. package/dist/modules/apimapper/toolslist-size.js +29 -18
  100. package/dist/modules/apimapper/toolslist-size.js.map +1 -1
  101. package/dist/modules/apimapper/types.d.ts +13 -0
  102. package/dist/modules/apimapper/types.js +1 -1
  103. package/dist/modules/apimapper/types.js.map +1 -1
  104. package/dist/modules/apimapper/whitelist-drift.js +16 -1
  105. package/dist/modules/apimapper/whitelist-drift.js.map +1 -1
  106. package/dist/modules/apimapper/workflows.js +221 -32
  107. package/dist/modules/apimapper/workflows.js.map +1 -1
  108. package/dist/modules/apimapper/yootheme-binding.js +103 -22
  109. package/dist/modules/apimapper/yootheme-binding.js.map +1 -1
  110. package/dist/platform/index.js +7 -0
  111. package/dist/platform/index.js.map +1 -1
  112. package/dist/proxy/bridge.d.ts +35 -0
  113. package/dist/proxy/bridge.js +129 -0
  114. package/dist/proxy/bridge.js.map +1 -0
  115. package/dist/proxy/mode.d.ts +9 -0
  116. package/dist/proxy/mode.js +20 -0
  117. package/dist/proxy/mode.js.map +1 -0
  118. package/dist/setup/probe-auth.d.ts +51 -0
  119. package/dist/setup/probe-auth.js +141 -0
  120. package/dist/setup/probe-auth.js.map +1 -0
  121. package/dist/setup-cli.d.ts +9 -0
  122. package/dist/setup-cli.js +34 -0
  123. package/dist/setup-cli.js.map +1 -1
  124. package/dist/sites/loader.d.ts +7 -0
  125. package/dist/sites/loader.js +16 -1
  126. package/dist/sites/loader.js.map +1 -1
  127. package/dist/skill-instructions.d.ts +14 -1
  128. package/dist/skill-instructions.js +30 -6
  129. package/dist/skill-instructions.js.map +1 -1
  130. package/manifest.json +2 -2
  131. package/package.json +3 -2
  132. package/skills/apimapper/SKILL.md +78 -3
  133. package/skills/apimapper/reference/dynamize-existing-layout.md +158 -0
  134. package/skills/apimapper/reference/jmespath-cookbook.md +241 -0
  135. package/skills/apimapper/reference/jmespath-pitfalls.md +81 -0
  136. package/skills/apimapper/reference/library-template-discovery.md +1 -1
  137. package/skills/apimapper/reference/merge-two-sources-on-key.md +117 -12
  138. package/skills/apimapper/reference/oauth.md +143 -52
  139. package/skills/apimapper/reference/troubleshooting.md +2 -2
  140. package/skills/apimapper/reference/yootheme-source-to-builder-handoff.md +348 -0
  141. package/skills/apimapper/reference/yootheme.md +75 -44
package/CHANGELOG.md CHANGED
@@ -5,13 +5,20 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project follows [Semantic Versioning](https://semver.org/).
7
7
 
8
- ## [0.3.0] `Latest` - 2026-06-08
8
+ ## [0.4.0] `Latest` - 2026-06-21
9
+
10
+ ### Added
11
+
12
+ - **Proxy mode: the server now connects through your site's plugin-served MCP endpoint. New setups use it automatically; existing installs keep working unchanged.**
13
+ - **Smoother client setup: tool-catalog export and a Connect to Claude handoff.**
14
+
15
+ ## [0.3.0] - 2026-06-08
9
16
 
10
17
  ### Added
11
18
 
12
19
  - **Library-first workflow: creating a custom connection for an API a curated library template already covers now returns a 409 that steers you to activate the template instead. Override with acknowledge_no_library:true for genuinely uncovered endpoints.**
13
- - **New tool apimapper_yootheme_binding_for_flow inspect the exact YOOtheme binding a published flow exposes.**
14
- - **New tool apimapper_connection_recover repair stuck or corrupted connections.**
20
+ - **New tool apimapper_yootheme_binding_for_flow: inspect the exact YOOtheme binding a published flow exposes.**
21
+ - **New tool apimapper_connection_recover: repair stuck or corrupted connections.**
15
22
  - **JMESPath date primitives (date_weekday, date_iso_to_time, date_iso_to_date, time_in_window) plus a depth-overflow guard for deeply nested expressions.**
16
23
  - **Connection reads now explain why they returned 0 items instead of failing silently.**
17
24
  - **MCP keys can be minted from a permission level (read / write / admin) with additive scopes.**
@@ -20,8 +27,9 @@ and this project follows [Semantic Versioning](https://semver.org/).
20
27
 
21
28
  ### Changed
22
29
 
23
- - **library_activate is resource-aware: it never silently mutates a healthy existing connection reuse, heal, or fork is explicit (force_new + reused/mutated/healed semantics).**
30
+ - **library_activate is resource-aware: it never silently mutates a healthy existing connection: reuse, heal, or fork is explicit (force_new + reused/mutated/healed semantics).**
24
31
  - **Recompile/publish auto-fix is on by default.**
32
+ - **Version history note: the public npm line goes 0.1.0 → 0.3.0. The intermediate 0.2.0 / 0.2.1 bumps were internal build/test cuts and were never published to npm (npm registry: 0.1.0-rc.1…rc.12, rc.13-w3.0, rc.13-w3.1, 0.1.0, 0.3.0), so there is no 0.2.x release to upgrade from: 0.3.0 is the direct successor to 0.1.0.**
25
33
 
26
34
  ### Fixed
27
35
 
@@ -137,7 +145,8 @@ and this project follows [Semantic Versioning](https://semver.org/).
137
145
  - **Fixed** - Bug fixes
138
146
  - **Security** - Security updates
139
147
 
140
- [0.3.0]: https://github.com/wootsup/api-mapper/compare/v0.1.0...HEAD
148
+ [0.4.0]: https://github.com/wootsup/api-mapper/compare/v0.3.0...HEAD
149
+ [0.3.0]: https://github.com/wootsup/api-mapper/compare/v0.1.0...v0.3.0
141
150
  [0.1.0]: https://github.com/wootsup/api-mapper/compare/v0.1.0-rc.13-w3.1...v0.1.0
142
151
  [0.1.0-rc.13-w3.1]: https://github.com/wootsup/api-mapper/compare/v0.1.0-rc.13-w3.0...v0.1.0-rc.13-w3.1
143
152
  [0.1.0-rc.13-w3.0]: https://github.com/wootsup/api-mapper/compare/v0.1.0-rc.12...v0.1.0-rc.13-w3.0
@@ -0,0 +1,31 @@
1
+ import { type ModuleStatus } from "@getimo/mcp-toolkit";
2
+ /**
3
+ * Convert a captured tool inputSchema to JSON Schema. collectModuleTools yields a
4
+ * RAW Zod shape for advanced tools (entry.config.inputSchema) but a constructed Zod
5
+ * OBJECT for essentials (server._registeredTools[name].inputSchema, SDK mcp.js:611).
6
+ * Branch on the Zod-4 internal marker `_zod`. Native z.toJSONSchema (zod 4.4.3).
7
+ */
8
+ export declare function toJsonSchema(inputSchema: unknown): object;
9
+ /**
10
+ * Fail loud if module registration degraded. `loadModules` is graceful by
11
+ * design — when a module's `register()` throws it logs and records
12
+ * `{ status: "error" }` but RETURNS normally, so a registration failure would
13
+ * otherwise yield an empty/partial catalog that still resolves successfully.
14
+ * The catalog is a release artifact (SSOT for a future PHP MCP surface), so a
15
+ * silently-degraded export is worse than a hard failure — mirror the repo's
16
+ * fail-loud discipline (encryption golden-master, deploy key-survival).
17
+ */
18
+ export declare function assertModulesLoaded(statuses: ModuleStatus[]): void;
19
+ export interface CatalogTool {
20
+ name: string;
21
+ description: string;
22
+ jsonSchema: object;
23
+ annotations: Record<string, unknown>;
24
+ tier: "essential" | "advanced";
25
+ }
26
+ export interface Catalog {
27
+ version: string;
28
+ generatedFrom: "zod";
29
+ tools: CatalogTool[];
30
+ }
31
+ export declare function buildCatalog(): Promise<Catalog>;
@@ -0,0 +1,68 @@
1
+ // packages/apimapper-mcp/src/catalog/build-catalog.ts
2
+ import { z } from "zod";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { loadModules } from "@getimo/mcp-toolkit";
5
+ import { apimapperRestModule } from "../modules/apimapper/index.js";
6
+ import { collectModuleTools } from "../modules/apimapper/gateway/collect-module-tools.js";
7
+ /**
8
+ * Convert a captured tool inputSchema to JSON Schema. collectModuleTools yields a
9
+ * RAW Zod shape for advanced tools (entry.config.inputSchema) but a constructed Zod
10
+ * OBJECT for essentials (server._registeredTools[name].inputSchema, SDK mcp.js:611).
11
+ * Branch on the Zod-4 internal marker `_zod`. Native z.toJSONSchema (zod 4.4.3).
12
+ */
13
+ export function toJsonSchema(inputSchema) {
14
+ try {
15
+ if (inputSchema && typeof inputSchema === "object") {
16
+ const isZodObject = "_zod" in inputSchema;
17
+ const schema = isZodObject
18
+ ? inputSchema
19
+ : z.object(inputSchema);
20
+ return z.toJSONSchema(schema);
21
+ }
22
+ }
23
+ catch {
24
+ /* malformed/unsupported shape → safe fallback */
25
+ }
26
+ return { type: "object" };
27
+ }
28
+ /**
29
+ * Fail loud if module registration degraded. `loadModules` is graceful by
30
+ * design — when a module's `register()` throws it logs and records
31
+ * `{ status: "error" }` but RETURNS normally, so a registration failure would
32
+ * otherwise yield an empty/partial catalog that still resolves successfully.
33
+ * The catalog is a release artifact (SSOT for a future PHP MCP surface), so a
34
+ * silently-degraded export is worse than a hard failure — mirror the repo's
35
+ * fail-loud discipline (encryption golden-master, deploy key-survival).
36
+ */
37
+ export function assertModulesLoaded(statuses) {
38
+ const failed = statuses.filter((s) => s.status === "error");
39
+ if (failed.length) {
40
+ const detail = failed
41
+ .map((f) => `${f.name}: ${f.error ?? "unknown error"}`)
42
+ .join(", ");
43
+ throw new Error(`buildCatalog: module registration failed: ${detail}`);
44
+ }
45
+ }
46
+ export async function buildCatalog() {
47
+ const server = new McpServer({ name: "API Mapper MCP", version: "0.0.0" });
48
+ const statuses = await loadModules(server, [apimapperRestModule]);
49
+ assertModulesLoaded(statuses);
50
+ const collected = collectModuleTools(server, apimapperRestModule); // 78 module tools
51
+ const advancedKeys = new Set(apimapperRestModule.getAdvancedRegistry()?.keys() ?? []);
52
+ const tools = Object.entries(collected).map(([name, t]) => ({
53
+ name,
54
+ description: t.description ?? "",
55
+ jsonSchema: toJsonSchema(t.inputSchema),
56
+ annotations: t.annotations ?? {},
57
+ tier: advancedKeys.has(name) ? "advanced" : "essential",
58
+ }));
59
+ if (tools.length === 0) {
60
+ throw new Error("buildCatalog produced 0 tools — registration likely failed");
61
+ }
62
+ return {
63
+ version: process.env.npm_package_version ?? "0.0.0",
64
+ generatedFrom: "zod",
65
+ tools,
66
+ };
67
+ }
68
+ //# sourceMappingURL=build-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-catalog.js","sourceRoot":"","sources":["../../src/catalog/build-catalog.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,10 +1,15 @@
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/* — 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).
3
+ // Full coverage of /wp-json/api-mapper/v1/* — 81 registered tools (16 module
4
+ // essentials + the apimapper_advanced gateway + the apimapper_advanced_read
5
+ // gateway + 60 advanced-registry tools + 3 top-level tools registered below).
6
+ // Only 21 are first-class in tools/list; the 60 advanced tools route through
7
+ // the gateways to stay under Cursor's ~40 surface cap. Canonical counts are
8
+ // asserted in gateway/gateway.test.ts (A2).
9
+ // F115 (2026-06-11): apimapper_health promoted advanced→essential (15→16
10
+ // essentials, 60→59 advanced, surface 19→20, total then 79).
11
+ // F200b (2026-06-12): apimapper_advanced_read read-only gateway added
12
+ // (module-real 17→18, surface 20→21, total 80→81).
8
13
  //
9
14
  // Auth: API Mapper MCP-key (amk_live_...) generated via the API Mapper
10
15
  // admin UI → Settings → MCP Access. The legacy WordPress Application
@@ -70,6 +75,7 @@ import { registerUseProfileTool, registerListProfilesTool, } from "./modules/api
70
75
  import { registerSitesUseProfileTool, registerSitesListProfilesTool, } from "./modules/apimapper/sites-tools.js";
71
76
  import { getSitesRegistry, getActiveSiteId, setActiveSite, } from "./modules/apimapper/client.js";
72
77
  import { shouldShowInteractiveHint, buildInteractiveHint } from "./cli-hint.js";
78
+ import { setMcpClient } from "./modules/apimapper/mcp-client-identity.js";
73
79
  // Single source of truth for the package version (F-41 / W1.23).
74
80
  // Reads ../package.json at runtime so we never drift between the manifest
75
81
  // version (used by npm + DXT) and what we advertise to MCP clients.
@@ -156,6 +162,16 @@ server.registerTool("apimapper_rest_modules_status", {
156
162
  }, false, { maxChars: 2000 });
157
163
  });
158
164
  async function main() {
165
+ // Proxy mode: forward stdio 1:1 to the plugin-served PHP MCP endpoint and stop
166
+ // here — the fat catalog below is bypassed entirely. Default (fat) is unchanged.
167
+ // The dynamic import is gated on the env so the fat path never loads the proxy
168
+ // module (and the SDK client transport it pulls in) — keeps fat-mode startup
169
+ // lean and avoids loading proxy code (incl. under test) when it can't apply.
170
+ if (process.env.APIMAPPER_MODE === "proxy") {
171
+ const { maybeRunProxy } = await import("./proxy/bridge.js");
172
+ if (await maybeRunProxy(process.env))
173
+ return;
174
+ }
159
175
  moduleStatuses = await loadModules(server, [apimapperRestModule]);
160
176
  // Profile tools for apimapper_use_profile / apimapper_list_profiles.
161
177
  //
@@ -231,6 +247,22 @@ async function main() {
231
247
  throw err;
232
248
  });
233
249
  await connectStdio(server);
250
+ // Q1 (2026-06-14): capture the connected AI client's identity for the
251
+ // X-MCP-Client header. The SDK only knows the client name+version AFTER the
252
+ // handshake completes, so this read must follow connectStdio(). Stashed in a
253
+ // module-scoped slot (mcp-client-identity.ts) that the outbound REST
254
+ // chokepoint (client.ts performFetch) reads per request. Empty/missing
255
+ // clientInfo → null → no header attached.
256
+ //
257
+ // Defensive: `server.server` / `getClientVersion` are SDK internals; guard
258
+ // against a transport/SDK shape that doesn't expose them so a missing client
259
+ // identity degrades to "no header" and NEVER crashes server startup.
260
+ try {
261
+ setMcpClient(server.server?.getClientVersion?.());
262
+ }
263
+ catch {
264
+ setMcpClient(undefined);
265
+ }
234
266
  const ok = moduleStatuses.filter((m) => m.status === "ok").length;
235
267
  console.error(`[apimapper-rest] MCP Server v${PKG_VERSION} running — ${ok}/${moduleStatuses.length} modules loaded`);
236
268
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** Minimal node shape the layout needs; every other field is preserved. */
2
+ interface LayoutNode {
3
+ id: string;
4
+ type?: string;
5
+ position?: {
6
+ x: number;
7
+ y: number;
8
+ };
9
+ }
10
+ interface LayoutEdge {
11
+ source: string;
12
+ target: string;
13
+ }
14
+ /**
15
+ * Re-position every node into a clean layered grid derived from the edges.
16
+ * Returns a NEW array; each node keeps its id/type/data and gets a fresh
17
+ * `position`. Pure + deterministic (same graph → same positions). An empty
18
+ * `nodes` array is returned untouched.
19
+ */
20
+ export declare function autoLayoutNodes<T extends LayoutNode>(nodes: T[], edges: ReadonlyArray<LayoutEdge>): T[];
21
+ export {};
@@ -0,0 +1,54 @@
1
+ // auto-layout.ts — deterministic layered left-to-right layout for AI-authored
2
+ // flow graphs (Task X).
3
+ //
4
+ // Why: when the AI builds/edits a flow it should not have to compute pixel
5
+ // positions, and the customer wants the canvas tidy after every AI touch — no
6
+ // overlaps, logical source→…→output flow. This re-flows positions from the
7
+ // graph's topology so every AI write lands clean.
8
+ //
9
+ // IMPORTANT scope: this runs ONLY on the MCP (AI) flow-write path
10
+ // (flow_create / flow_update). It is deliberately NOT in the generic backend
11
+ // save, so a human's manual node positions (persisted by the admin-ui autosave,
12
+ // Task W) are never clobbered — only the AI tidies.
13
+ //
14
+ // Layout: topological layers become columns (left→right); nodes within a layer
15
+ // stack vertically. Orphan / cycle members (never reached) get their own
16
+ // trailing column so they stay visible and non-overlapping — the exact same
17
+ // "unreachable as a trailing layer" treatment the flow-diagram renderer uses.
18
+ import { topoLayers } from "./render/dag.js";
19
+ // Pitch must exceed the admin-ui BaseNode card box (min-w-[220px]
20
+ // max-w-[300px]) so programmatically-placed nodes never crowd — identical to
21
+ // the graph-builder constants (300 max card + 100 gutter; stacked-card height +
22
+ // gutter).
23
+ const BASE_X = 100;
24
+ const BASE_Y = 100;
25
+ const COL_WIDTH = 400;
26
+ const ROW_HEIGHT = 240;
27
+ /**
28
+ * Re-position every node into a clean layered grid derived from the edges.
29
+ * Returns a NEW array; each node keeps its id/type/data and gets a fresh
30
+ * `position`. Pure + deterministic (same graph → same positions). An empty
31
+ * `nodes` array is returned untouched.
32
+ */
33
+ export function autoLayoutNodes(nodes, edges) {
34
+ if (nodes.length === 0)
35
+ return nodes;
36
+ const { layers, unreachable } = topoLayers(nodes.map((n) => ({ id: n.id, type: n.type })), edges.map((e) => ({ source: e.source, target: e.target })));
37
+ // Orphans + cycle members trail in their own column so they remain visible
38
+ // (this is exactly the node the AI must be able to see to tidy — Task W).
39
+ const columns = unreachable.length > 0 ? [...layers, unreachable] : layers;
40
+ const positionById = new Map();
41
+ columns.forEach((column, colIndex) => {
42
+ column.forEach((id, rowIndex) => {
43
+ positionById.set(id, {
44
+ x: BASE_X + colIndex * COL_WIDTH,
45
+ y: BASE_Y + rowIndex * ROW_HEIGHT,
46
+ });
47
+ });
48
+ });
49
+ return nodes.map((node) => {
50
+ const position = positionById.get(node.id);
51
+ return position ? { ...node, position } : node;
52
+ });
53
+ }
54
+ //# sourceMappingURL=auto-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-layout.js","sourceRoot":"","sources":["../../../src/modules/apimapper/auto-layout.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wBAAwB;AACxB,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,2EAA2E;AAC3E,kDAAkD;AAClD,EAAE;AACF,kEAAkE;AAClE,6EAA6E;AAC7E,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,+EAA+E;AAC/E,yEAAyE;AACzE,4EAA4E;AAC5E,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAc7C,kEAAkE;AAClE,6EAA6E;AAC7E,gFAAgF;AAChF,WAAW;AACX,MAAM,MAAM,GAAG,GAAG,CAAC;AACnB,MAAM,MAAM,GAAG,GAAG,CAAC;AACnB,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAU,EACV,KAAgC;IAEhC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,CACxC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAC9C,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAC3D,CAAC;IAEF,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE3E,MAAM,YAAY,GAAG,IAAI,GAAG,EAAoC,CAAC;IACjE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;QACnC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;YAC9B,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE;gBACnB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;gBAChC,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU;aAClC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -46,7 +46,7 @@ export declare function sanitizeErrorString(s: string): string;
46
46
  * The underlying toolkit `ApiResponse` only carries `{success, data?, error?}`.
47
47
  * We wrap each call so we capture the HTTP code via `fetch` and merge.
48
48
  */
49
- export type ApiErrorCode = "auth" | "not_found" | "conflict" | "rate_limit" | "server" | "network" | "unknown";
49
+ export type ApiErrorCode = "auth" | "not_found" | "conflict" | "rate_limit" | "server" | "network" | "credential_expired" | "tier_limit_reached" | "unknown";
50
50
  export interface ExtApiResponse<T = unknown> extends ApiResponse<T> {
51
51
  status?: number;
52
52
  errorCode?: ApiErrorCode;
@@ -181,11 +181,61 @@ export declare function __resetPlatformResolutionForTests(): void;
181
181
  */
182
182
  export declare function request<T = unknown>(path: string, init?: RequestInit, opts?: RequestOpts): Promise<ExtApiResponse<T>>;
183
183
  /**
184
- * Map an `errorCode` to a focused hint string for the caller.
185
- * Falls back to the generic health-tool hint.
184
+ * Optional second argument to {@link hintFor}, used to route a hint more
185
+ * precisely than the coarse `ApiErrorCode` alone allows. Both fields are
186
+ * optional and every legacy `hintFor(code)` call keeps its exact prior
187
+ * output (back-compat), so the ~12 call sites need not change.
188
+ *
189
+ * Welle 2 (F112 + F113, 2026-06-11):
190
+ * - `message`: the upstream error string. Lets the `unknown` branch route
191
+ * a config/validation/argument error to a "fix the field / fix the flow
192
+ * shape / detect schema" hint instead of the catch-all HEALTH_HINT
193
+ * (which sends the agent on a connectivity probe that always passes).
194
+ * It is also the channel for the F83 JMESPath depth-limit detection
195
+ * (see {@link DEPTH_SPLIT_HINT}).
196
+ * - `origin`: WHERE a 401/403 came from. `classify()` maps every 401/403
197
+ * to `'auth'`, but a 401/403 raised by a *connection* / *credential*
198
+ * fetch is an EXPIRED UPSTREAM token, not a broken MCP key. With
199
+ * `origin: 'connection' | 'credential'` the auth branch steers to
200
+ * re-authorising the upstream credential (`oauth_authorize_begin`)
201
+ * rather than rotating the still-valid MCP bearer key.
186
202
  */
187
- export declare function hintFor(code?: ApiErrorCode): string;
203
+ export interface HintContext {
204
+ /** The upstream error message, used for message-pattern routing of `unknown`. */
205
+ message?: string;
206
+ /**
207
+ * The origin of an auth (401/403) failure. `connection` / `credential`
208
+ * mean an expired upstream token; `mcp_transport` (or omitted) means the
209
+ * MCP bearer key itself.
210
+ */
211
+ origin?: "connection" | "credential" | "mcp_transport";
212
+ }
213
+ export declare const DEPTH_SPLIT_HINT: string;
214
+ /**
215
+ * Map an `errorCode` (and optional {@link HintContext}) to a focused hint
216
+ * string for the caller. Falls back to the generic health-tool hint only for
217
+ * genuinely connectivity-shaped failures.
218
+ *
219
+ * The second argument is a UNION: a bare `string` is treated as
220
+ * `{ message }` so the ~12 legacy call sites that pass the upstream error
221
+ * string verbatim (`hintFor(code, r.error)`) keep working unchanged, while
222
+ * the richer `{ message, origin }` form drives F112/F113 routing. Omit it to
223
+ * keep the legacy code-only behaviour byte-for-byte.
224
+ */
225
+ export declare function hintFor(code?: ApiErrorCode, context?: string | HintContext): string;
188
226
  export declare const HEALTH_HINT = "Use apimapper_health to check connectivity and auth.";
227
+ /**
228
+ * Recovery hint for an auth failure on the MCP transport itself (the bearer
229
+ * key is wrong/revoked/expired). Kept verbatim for the legacy `hintFor('auth')`
230
+ * contract.
231
+ */
232
+ export declare const MCP_KEY_AUTH_HINT: string;
233
+ /**
234
+ * F113 — recovery hint for an EXPIRED UPSTREAM credential surfaced as a
235
+ * connection/credential 401/403. The fix is to re-authorise the credential in
236
+ * place (preserving the refresh_token), NOT to rotate the MCP key.
237
+ */
238
+ export declare const CREDENTIAL_EXPIRED_HINT: string;
189
239
  export declare function authConfigured(): boolean;
190
240
  export declare const api: {
191
241
  request: <T>(path: string, init?: RequestInit, _retryCount?: number, responseSchema?: import("zod").ZodType<T>) => Promise<ApiResponse<T>>;
@@ -25,6 +25,7 @@
25
25
  import { createHttpClient } from "@getimo/mcp-toolkit";
26
26
  import { Agent, setGlobalDispatcher } from "undici";
27
27
  import { sanitizeSecrets } from "./credential-sanitizer.js";
28
+ import { getMcpClient } from "./mcp-client-identity.js";
28
29
  import { getCached, setCached, isCacheableRequest, invalidateByPath, clearCache, } from "./read-cache.js";
29
30
  import { WordPressPlatform, JoomlaPlatform, isPlatformResponseError, isJoomlaUnsupportedPathError } from "../../platform/index.js";
30
31
  import { loadSitesRegistry } from "../../sites/loader.js";
@@ -207,10 +208,19 @@ async function performFetch(cfg) {
207
208
  const { url, headers, init, opts, parseResponse, preferMessageKey = true, attachErrorBody = false, textSuccessFalseGuard = false, } = cfg;
208
209
  let status;
209
210
  const timeoutMs = resolveTimeout(opts);
211
+ // Q1 (2026-06-14): performFetch is the ONE outbound chokepoint shared by the
212
+ // WP, Joomla, and absolute request paths. Attaching X-MCP-Client here means
213
+ // every REST call carries the connected AI client's identity (set once
214
+ // post-handshake in index.ts) without touching three caller header builders.
215
+ // Null when no client info → header omitted entirely.
216
+ const mcpClient = getMcpClient();
210
217
  try {
211
218
  const res = await fetch(url, {
212
219
  ...init,
213
- headers,
220
+ headers: {
221
+ ...headers,
222
+ ...(mcpClient ? { "X-MCP-Client": mcpClient } : {}),
223
+ },
214
224
  signal: AbortSignal.timeout(timeoutMs),
215
225
  });
216
226
  status = res.status;
@@ -855,33 +865,154 @@ async function rawAbsoluteRequest(url, init, opts) {
855
865
  });
856
866
  }
857
867
  /**
858
- * Map an `errorCode` to a focused hint string for the caller.
859
- * Falls back to the generic health-tool hint.
868
+ * F83 (2026-06-10, C3 cold-agent): the JMESPath depth-limit failure surfaced
869
+ * on the flow-write path. The PHP backend emits it as a 422 with one of two
870
+ * frozen wordings:
871
+ * - FlowHandler::validateJmesPathDepth → "N JMESPath expression(s) exceeded
872
+ * the depth limit of M"
873
+ * - TransformException → "JMESPath expression too deeply nested (N levels).
874
+ * Maximum: M"
875
+ * Neither carries a body-level `error_code`/`suggestion`, so `classify(422)`
876
+ * lands on "unknown" and the bare-code hint is HEALTH_HINT — the WRONG remedy
877
+ * (a cold agent literally got "Use apimapper_health to check connectivity").
878
+ * The actual cure is the two-transform split: a pipe `|` resets the depth
879
+ * counter. We detect the depth-limit message text (not the coarse code) so the
880
+ * remedy fires regardless of how the wire status classifies. This is the
881
+ * canonical depth remedy — the PHP `TransformException::expressionTooDeepWithRemedy`
882
+ * superset emits the same intent; the MCP-side detection here covers the
883
+ * write-path 422s that arrive without a body-level error_code.
860
884
  */
861
- export function hintFor(code) {
885
+ const DEPTH_LIMIT_MESSAGE_RE = /depth limit|too deeply nested/i;
886
+ export const DEPTH_SPLIT_HINT = "JMESPath depth limit hit. This is NOT a connectivity problem — do not run " +
887
+ "apimapper_health. Multi-stage reshape? Pass `transform` as an ARRAY of stages " +
888
+ "— each stage gets its own depth budget. SPLIT the over-nested expression into " +
889
+ "TWO Transform nodes piped together: a pipe `|` resets the depth counter, so " +
890
+ "each half stays under the cap of 10. Move the inner projection/merge into a " +
891
+ "first Transform, then do the per-row shaping in a second Transform reading its " +
892
+ "output. Iterate each half risk-free with apimapper_jmespath_test before " +
893
+ "wiring, and read the copy-paste recipes via " +
894
+ "apimapper_get_skill({ topic: 'jmespath-cookbook' }) → \"Two-Transform split\".";
895
+ /**
896
+ * Map an `errorCode` (and optional {@link HintContext}) to a focused hint
897
+ * string for the caller. Falls back to the generic health-tool hint only for
898
+ * genuinely connectivity-shaped failures.
899
+ *
900
+ * The second argument is a UNION: a bare `string` is treated as
901
+ * `{ message }` so the ~12 legacy call sites that pass the upstream error
902
+ * string verbatim (`hintFor(code, r.error)`) keep working unchanged, while
903
+ * the richer `{ message, origin }` form drives F112/F113 routing. Omit it to
904
+ * keep the legacy code-only behaviour byte-for-byte.
905
+ */
906
+ export function hintFor(code, context) {
907
+ // Normalise the union: a bare string IS the upstream message.
908
+ const ctx = typeof context === "string" ? { message: context } : context;
909
+ // F83: message-driven depth-limit detection wins over the coarse code, so a
910
+ // 422 that classify()s to "unknown" still gets the split remedy.
911
+ if (ctx?.message && DEPTH_LIMIT_MESSAGE_RE.test(ctx.message)) {
912
+ return DEPTH_SPLIT_HINT;
913
+ }
862
914
  switch (code) {
863
915
  case "auth":
864
- return ("Auth failed (HTTP 401/403). Your MCP key (APIMAPPER_TOKEN) is " +
865
- "invalid, revoked, or expired. Recovery steps: " +
866
- "(1) Open API Mapper menu Settings MCP Access. " +
867
- "(2) Revoke the old key if you suspect it was leaked. " +
868
- "(3) Click 'New API key' and copy the value. " +
869
- "(4) Re-run `npx -y @wootsup/mcp setup` and paste the new key — " +
870
- "the wizard rewrites your AI client config in place. " +
871
- "(5) Restart your AI client (Claude Desktop / Cursor / etc.).");
916
+ // F113: separate upstream-credential auth from MCP-transport auth.
917
+ // A 401/403 carried back from a connection/credential fetch is an
918
+ // EXPIRED UPSTREAM token re-authorise it in place; do NOT send the
919
+ // agent to rotate the (valid) MCP key + re-run the setup wizard.
920
+ if (ctx?.origin === "connection" || ctx?.origin === "credential") {
921
+ return CREDENTIAL_EXPIRED_HINT;
922
+ }
923
+ return MCP_KEY_AUTH_HINT;
872
924
  case "not_found":
873
925
  return "Resource not found. Use the matching `*_list` tool to find a valid id.";
874
926
  case "rate_limit":
875
- return "Rate-limited. Retry after a few seconds; consider apimapper_cache_invalidate to reduce churn.";
927
+ // F59 (2026-06-10): a 429 is often recoverable WITHOUT waiting many
928
+ // providers have a same-schema MIRROR connection (same template, a
929
+ // different upstream serving identical data). Point the agent there.
930
+ return ("Rate-limited (HTTP 429). Retry after a few seconds, and raise " +
931
+ "cache_ttl / use apimapper_cache_invalidate to reduce churn. If the " +
932
+ "throttle persists, run apimapper_connection_list and look for a " +
933
+ "same-schema / mirror connection (same library template or a " +
934
+ "duplicate pointing at an alternative upstream) that serves the same " +
935
+ "data — bind the flow to that mirror instead of the throttled source.");
936
+ case "credential_expired":
937
+ // A11: re-authorize the EXISTING credential in place; never delete +
938
+ // recreate (that drops the OAuth refresh token).
939
+ return ("An OAuth credential expired. Re-authorize it IN PLACE with " +
940
+ "apimapper_oauth_authorize_begin({ credential_id }), open the returned " +
941
+ "authorize_url, complete consent, then retry. Keep the same credential " +
942
+ "— recreating it from scratch drops the refresh token. Use " +
943
+ "apimapper_credential_list to find the credential_id.");
944
+ case "tier_limit_reached":
945
+ // A12: the plan's connection / auth-method limit is hit.
946
+ return ("Your plan's limit was reached (connections or auth methods). " +
947
+ "Upgrade the license to raise the limit, or free a slot by deleting an " +
948
+ "unused connection (apimapper_connection_list to review). Check the " +
949
+ "current tier + limits with apimapper_license_status.");
876
950
  case "server":
877
951
  return "Upstream server error. Try again, then run apimapper_health and check WP error logs.";
878
952
  case "network":
879
953
  return "Network/timeout error. Verify APIMAPPER_WP_BASE is reachable from this host.";
880
954
  default:
881
- return HEALTH_HINT;
955
+ // F112: an `unknown`/config error must NOT blanket-route to the
956
+ // connectivity probe. Route on the message shape when we have one.
957
+ return routeUnknownHint(ctx?.message);
958
+ }
959
+ }
960
+ /**
961
+ * F112 — message-pattern router for the `unknown` (config/validation) branch.
962
+ * Returns a hint that points at the ACTUAL fix (fill a field, repair the flow
963
+ * shape, detect a schema) instead of the catch-all HEALTH_HINT. Only a
964
+ * genuinely connectivity-shaped message (or no message at all) keeps the
965
+ * health hint.
966
+ */
967
+ function routeUnknownHint(message) {
968
+ if (!message)
969
+ return HEALTH_HINT;
970
+ const m = message.toLowerCase();
971
+ // Connectivity-shaped failures keep pointing at apimapper_health.
972
+ if (/econnrefused|enotfound|etimedout|fetch failed|network|timeout|unreachable|connection refused/.test(m)) {
973
+ return HEALTH_HINT;
974
+ }
975
+ // Empty/stale schema → detect the schema.
976
+ if (/schema (is )?empty|no schema|empty schema|run detect|detect[- ]schema/.test(m)) {
977
+ return "The source schema is empty — run apimapper_flow_detect_schema (or apimapper_flow_full_recompile_publish) to populate it before binding fields.";
978
+ }
979
+ // Flow-SHAPE errors (wiring / nodes / edges) → inspect the flow graph.
980
+ if (/no (target|source|output) node|target node|source node|\bedges?\b|\bnode\b|connect|wiring|no nodes/.test(m)) {
981
+ return "The flow shape is incomplete (missing node, edge, or target). Run apimapper_flow_get to inspect the graph, then fix the node/edge wiring with apimapper_flow_update.";
982
+ }
983
+ // Missing-field / configure errors → supply the field.
984
+ if (/missing required field|missing field|please configure|required field|is required|required:/.test(m)) {
985
+ return "A required argument is missing — supply the named field(s) and call the tool again. Check the tool's input schema for the exact key(s).";
882
986
  }
987
+ // Default: still a config error, not a connectivity one — keep the agent
988
+ // out of the health probe and tell it to recheck its arguments.
989
+ return "Check the tool arguments against its input schema and retry; this is a request/config error, not a connectivity problem.";
883
990
  }
884
991
  export const HEALTH_HINT = "Use apimapper_health to check connectivity and auth.";
992
+ /**
993
+ * Recovery hint for an auth failure on the MCP transport itself (the bearer
994
+ * key is wrong/revoked/expired). Kept verbatim for the legacy `hintFor('auth')`
995
+ * contract.
996
+ */
997
+ export const MCP_KEY_AUTH_HINT = "Auth failed (HTTP 401/403). Your MCP key (APIMAPPER_TOKEN) is " +
998
+ "invalid, revoked, or expired. Recovery steps: " +
999
+ "(1) Open API Mapper → ⋮ menu → Settings → MCP Access. " +
1000
+ "(2) Revoke the old key if you suspect it was leaked. " +
1001
+ "(3) Click 'New API key' and copy the value. " +
1002
+ "(4) Re-run `npx -y @wootsup/mcp setup` and paste the new key — " +
1003
+ "the wizard rewrites your AI client config in place. " +
1004
+ "(5) Restart your AI client (Claude Desktop / Cursor / etc.).";
1005
+ /**
1006
+ * F113 — recovery hint for an EXPIRED UPSTREAM credential surfaced as a
1007
+ * connection/credential 401/403. The fix is to re-authorise the credential in
1008
+ * place (preserving the refresh_token), NOT to rotate the MCP key.
1009
+ */
1010
+ export const CREDENTIAL_EXPIRED_HINT = "The upstream API rejected the request (HTTP 401/403) because the " +
1011
+ "connection's credential has expired or was revoked — this is the " +
1012
+ "external service's token, NOT your MCP key. Re-authorise it: call " +
1013
+ "apimapper_oauth_authorize_begin with the connection's credential_id to " +
1014
+ "get a fresh consent URL (this preserves the refresh_token). Do NOT " +
1015
+ "rotate your MCP key for this error.";
885
1016
  export function authConfigured() {
886
1017
  // Bearer token (amk_live_…) is sufficient on its own; legacy App-Password
887
1018
  // auth still requires both user + password.