@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.
Files changed (131) hide show
  1. package/CHANGELOG.md +148 -83
  2. package/README.md +31 -27
  3. package/SECURITY.md +15 -6
  4. package/dist/auth/keychain.d.ts +27 -1
  5. package/dist/auth/keychain.js +48 -2
  6. package/dist/auth/keychain.js.map +1 -1
  7. package/dist/cli-hint.d.ts +22 -0
  8. package/dist/cli-hint.js +55 -0
  9. package/dist/cli-hint.js.map +1 -0
  10. package/dist/index.js +97 -22
  11. package/dist/index.js.map +1 -1
  12. package/dist/install-skill.js +1 -1
  13. package/dist/modules/apimapper/cache.js +25 -17
  14. package/dist/modules/apimapper/cache.js.map +1 -1
  15. package/dist/modules/apimapper/client.d.ts +62 -1
  16. package/dist/modules/apimapper/client.js +555 -291
  17. package/dist/modules/apimapper/client.js.map +1 -1
  18. package/dist/modules/apimapper/connections.js +230 -75
  19. package/dist/modules/apimapper/connections.js.map +1 -1
  20. package/dist/modules/apimapper/credential-sanitizer.d.ts +5 -0
  21. package/dist/modules/apimapper/credential-sanitizer.js +60 -1
  22. package/dist/modules/apimapper/credential-sanitizer.js.map +1 -1
  23. package/dist/modules/apimapper/credentials.js +19 -47
  24. package/dist/modules/apimapper/credentials.js.map +1 -1
  25. package/dist/modules/apimapper/diagnose.js +21 -2
  26. package/dist/modules/apimapper/diagnose.js.map +1 -1
  27. package/dist/modules/apimapper/flows.js +60 -77
  28. package/dist/modules/apimapper/flows.js.map +1 -1
  29. package/dist/modules/apimapper/gateway/advanced-tool.js +56 -5
  30. package/dist/modules/apimapper/gateway/advanced-tool.js.map +1 -1
  31. package/dist/modules/apimapper/gateway/essentials.d.ts +1 -1
  32. package/dist/modules/apimapper/gateway/essentials.js +8 -1
  33. package/dist/modules/apimapper/gateway/essentials.js.map +1 -1
  34. package/dist/modules/apimapper/get-skill.d.ts +1 -1
  35. package/dist/modules/apimapper/get-skill.js +44 -6
  36. package/dist/modules/apimapper/get-skill.js.map +1 -1
  37. package/dist/modules/apimapper/graph.js +40 -36
  38. package/dist/modules/apimapper/graph.js.map +1 -1
  39. package/dist/modules/apimapper/index.js +2 -0
  40. package/dist/modules/apimapper/index.js.map +1 -1
  41. package/dist/modules/apimapper/library.js +425 -83
  42. package/dist/modules/apimapper/library.js.map +1 -1
  43. package/dist/modules/apimapper/license.js +12 -36
  44. package/dist/modules/apimapper/license.js.map +1 -1
  45. package/dist/modules/apimapper/local-sources.js +20 -34
  46. package/dist/modules/apimapper/local-sources.js.map +1 -1
  47. package/dist/modules/apimapper/misc.js +13 -27
  48. package/dist/modules/apimapper/misc.js.map +1 -1
  49. package/dist/modules/apimapper/onboarding.d.ts +30 -1
  50. package/dist/modules/apimapper/onboarding.js +114 -19
  51. package/dist/modules/apimapper/onboarding.js.map +1 -1
  52. package/dist/modules/apimapper/schema.js +9 -18
  53. package/dist/modules/apimapper/schema.js.map +1 -1
  54. package/dist/modules/apimapper/settings.js +49 -52
  55. package/dist/modules/apimapper/settings.js.map +1 -1
  56. package/dist/modules/apimapper/sites-tools.d.ts +29 -0
  57. package/dist/modules/apimapper/sites-tools.js +165 -0
  58. package/dist/modules/apimapper/sites-tools.js.map +1 -0
  59. package/dist/modules/apimapper/tool-result.d.ts +46 -0
  60. package/dist/modules/apimapper/tool-result.js +63 -0
  61. package/dist/modules/apimapper/tool-result.js.map +1 -0
  62. package/dist/modules/apimapper/toolslist-size.d.ts +11 -10
  63. package/dist/modules/apimapper/toolslist-size.js +16 -14
  64. package/dist/modules/apimapper/toolslist-size.js.map +1 -1
  65. package/dist/modules/apimapper/types.d.ts +21 -0
  66. package/dist/modules/apimapper/types.js.map +1 -1
  67. package/dist/modules/apimapper/whitelist-drift.d.ts +85 -0
  68. package/dist/modules/apimapper/whitelist-drift.js +360 -0
  69. package/dist/modules/apimapper/whitelist-drift.js.map +1 -0
  70. package/dist/modules/apimapper/workflows.js +82 -27
  71. package/dist/modules/apimapper/workflows.js.map +1 -1
  72. package/dist/modules/apimapper/yootheme-binding.d.ts +35 -0
  73. package/dist/modules/apimapper/yootheme-binding.js +186 -0
  74. package/dist/modules/apimapper/yootheme-binding.js.map +1 -0
  75. package/dist/platform/index.d.ts +56 -0
  76. package/dist/platform/index.js +151 -2
  77. package/dist/platform/index.js.map +1 -1
  78. package/dist/setup/detect-clients.d.ts +40 -1
  79. package/dist/setup/detect-clients.js +148 -1
  80. package/dist/setup/detect-clients.js.map +1 -1
  81. package/dist/setup/probe-handshake.js +40 -7
  82. package/dist/setup/probe-handshake.js.map +1 -1
  83. package/dist/setup/remove-config.d.ts +8 -0
  84. package/dist/setup/remove-config.js +145 -0
  85. package/dist/setup/remove-config.js.map +1 -0
  86. package/dist/setup/uninstall.d.ts +34 -0
  87. package/dist/setup/uninstall.js +147 -0
  88. package/dist/setup/uninstall.js.map +1 -0
  89. package/dist/setup-cli.d.ts +7 -0
  90. package/dist/setup-cli.js +29 -1
  91. package/dist/setup-cli.js.map +1 -1
  92. package/dist/sites/loader.d.ts +41 -0
  93. package/dist/sites/loader.js +119 -0
  94. package/dist/sites/loader.js.map +1 -0
  95. package/dist/sites/schema.d.ts +69 -0
  96. package/dist/sites/schema.js +71 -0
  97. package/dist/sites/schema.js.map +1 -0
  98. package/dist/sites/secret-resolver.d.ts +47 -0
  99. package/dist/sites/secret-resolver.js +150 -0
  100. package/dist/sites/secret-resolver.js.map +1 -0
  101. package/dist/skill-instructions.d.ts +1 -1
  102. package/dist/skill-instructions.js +5 -0
  103. package/dist/skill-instructions.js.map +1 -1
  104. package/dist/transports/stdio.js +4 -4
  105. package/dist/transports/stdio.js.map +1 -1
  106. package/dist/uninstall-skill.d.ts +27 -0
  107. package/dist/uninstall-skill.js +89 -0
  108. package/dist/uninstall-skill.js.map +1 -0
  109. package/docs/architecture.md +21 -21
  110. package/docs/customgraph-internal-migration.md +4 -4
  111. package/docs/security.md +2 -21
  112. package/docs/tools.md +40 -12
  113. package/manifest.json +77 -79
  114. package/package.json +68 -65
  115. package/skills/apimapper/SKILL.md +53 -7
  116. package/skills/apimapper/reference/conditional-style-multi-items.md +114 -0
  117. package/skills/apimapper/reference/jmespath-pitfalls.md +108 -0
  118. package/skills/apimapper/reference/joomla.md +1 -1
  119. package/skills/apimapper/reference/library-template-discovery.md +65 -0
  120. package/skills/apimapper/reference/merge-two-sources-on-key.md +99 -0
  121. package/skills/apimapper/reference/troubleshooting.md +20 -0
  122. package/skills/apimapper/reference/yootheme.md +1 -1
  123. package/dist/auth/oauth-provider.d.ts +0 -68
  124. package/dist/auth/oauth-provider.js +0 -232
  125. package/dist/auth/oauth-provider.js.map +0 -1
  126. package/dist/server-http.d.ts +0 -22
  127. package/dist/server-http.js +0 -159
  128. package/dist/server-http.js.map +0 -1
  129. package/dist/transports/http.d.ts +0 -29
  130. package/dist/transports/http.js +0 -267
  131. package/dist/transports/http.js.map +0 -1
@@ -0,0 +1,165 @@
1
+ // src/modules/apimapper/sites-tools.ts — Phase 3.
2
+ //
3
+ // Sites-file-backed implementations of the profile tools. When a sites-file is
4
+ // active (APIMAPPER_SITES_FILE set + non-empty), index.ts wires THESE registrars
5
+ // under the canonical tool names (apimapper_list_profiles / apimapper_use_profile)
6
+ // instead of the keychain ProfileStore versions in use-profile.ts. The tool
7
+ // names + response shapes stay identical so the agent surface is unchanged —
8
+ // only the backing store differs (sites-file entries vs keychain profiles).
9
+ //
10
+ // `apimapper_use_profile(name)` calls `setActiveSite(name)` on the client, which
11
+ // resets the resolution memo so the NEXT request() retargets the chosen site.
12
+ // `setActiveSite` runs BEFORE the optional identity probe so the probe hits the
13
+ // newly-activated site.
14
+ import { z } from "zod";
15
+ import { formatResult, mutating, readOnly } from "@getimo/mcp-toolkit";
16
+ import { request } from "./client.js";
17
+ export function registerSitesListProfilesTool(server, deps) {
18
+ const registrar = server;
19
+ registrar.registerTool("apimapper_list_profiles", {
20
+ title: "List Configured Profiles",
21
+ description: "List all configured site profiles (name, siteUrl, platform) with an " +
22
+ "is_active flag indicating which one is currently active. " +
23
+ "Backed by your sites-file (APIMAPPER_SITES_FILE). " +
24
+ "Use this to discover available profile names before calling " +
25
+ "apimapper_use_profile to switch the active site. " +
26
+ "Read-only — does not contact any site." +
27
+ "\n\nResponse shape:\n" +
28
+ " { profile_count, active_profile, profiles: [{ name, siteUrl, platform, is_active }] }",
29
+ inputSchema: {},
30
+ annotations: readOnly({ title: "List Configured Profiles", openWorld: false }),
31
+ }, async () => {
32
+ const reg = deps.getRegistry();
33
+ const active = deps.getActiveSiteId();
34
+ // When no explicit pointer is set, the default entry is the active one.
35
+ const activeName = active ?? reg.getDefault().site_id;
36
+ const profiles = reg.list().map((entry) => ({
37
+ name: entry.site_id,
38
+ siteUrl: entry.url,
39
+ platform: entry.platform,
40
+ is_active: entry.site_id === activeName,
41
+ }));
42
+ return formatResult({
43
+ profile_count: profiles.length,
44
+ active_profile: activeName,
45
+ source: "sites-file",
46
+ profiles,
47
+ }, false, { maxChars: 3000 });
48
+ });
49
+ }
50
+ /**
51
+ * Default probe: switch already happened (setActiveSite ran first), so the
52
+ * legacy `request("identity")` now resolves to the freshly-activated site.
53
+ */
54
+ async function defaultSitesProbeIdentity(_entry) {
55
+ const r = await request("/identity");
56
+ if (!r.success) {
57
+ throw new Error(r.error ?? "identity probe failed");
58
+ }
59
+ return normaliseIdentity(r.data);
60
+ }
61
+ function normaliseIdentity(data) {
62
+ if (!data || typeof data !== "object") {
63
+ throw new Error("identity response missing object body");
64
+ }
65
+ const o = data;
66
+ const plugin_version = typeof o.plugin_version === "string" ? o.plugin_version : "";
67
+ const plugin_hash = typeof o.plugin_hash === "string" ? o.plugin_hash : "";
68
+ const site_url = (typeof o.site_url === "string" && o.site_url) ||
69
+ (typeof o.siteurl === "string" && o.siteurl) ||
70
+ "";
71
+ const caps = Array.isArray(o.capabilities)
72
+ ? o.capabilities.filter((c) => typeof c === "string")
73
+ : [];
74
+ if (!plugin_version || !plugin_hash) {
75
+ throw new Error("identity response missing required fields");
76
+ }
77
+ return { plugin_version, plugin_hash, site_url, capabilities: caps };
78
+ }
79
+ export function registerSitesUseProfileTool(server, deps) {
80
+ const probe = deps.probeIdentity ?? defaultSitesProbeIdentity;
81
+ const registrar = server;
82
+ registrar.registerTool("apimapper_use_profile", {
83
+ title: "Switch Active Profile",
84
+ description: "Activate a configured site (from your sites-file) and probe its identity " +
85
+ "endpoint to confirm the site is reachable and the plugin is installed. " +
86
+ "Switching retargets every subsequent tool call at the chosen site. " +
87
+ "Use `noProbe: true` to skip the network probe for offline activation." +
88
+ "\n\nExample:\n apimapper_use_profile({ name: 'prod', noProbe: false })",
89
+ inputSchema: {
90
+ name: z
91
+ .string()
92
+ .min(1)
93
+ .describe('Site_id to activate (e.g., "dev", "client-x-prod"). Use apimapper_list_profiles to discover.'),
94
+ noProbe: z
95
+ .boolean()
96
+ .default(false)
97
+ .describe("Skip the live /identity probe. Use for offline activation when the site is unreachable."),
98
+ },
99
+ // Mutating: flips the active-site pointer (changes which backend every
100
+ // subsequent request targets). Closed-world — bounded to the local
101
+ // sites-file selection + an internal /identity call.
102
+ annotations: mutating({ title: "Switch Active Profile", openWorld: false }),
103
+ }, async (args) => {
104
+ const { name, noProbe = false } = args;
105
+ const reg = deps.getRegistry();
106
+ const entry = reg.get(name);
107
+ if (!entry) {
108
+ return formatResult({
109
+ error: `Site "${name}" not found in sites-file`,
110
+ context: { name, known: reg.listIds() },
111
+ hint: "Use apimapper_list_profiles to see configured sites.",
112
+ }, true);
113
+ }
114
+ // Switch FIRST so the (default) identity probe targets the new site.
115
+ try {
116
+ deps.setActiveSite(name);
117
+ }
118
+ catch (e) {
119
+ const msg = e instanceof Error ? e.message : String(e);
120
+ return formatResult({
121
+ error: `Failed to activate site "${name}": ${msg}`,
122
+ context: { name },
123
+ hint: "Verify APIMAPPER_SITES_FILE is set and the site_id exists.",
124
+ }, true);
125
+ }
126
+ if (noProbe) {
127
+ return formatResult({
128
+ activated: true,
129
+ profile: { name: entry.site_id, siteUrl: entry.url, platform: entry.platform },
130
+ noProbe: true,
131
+ source: "sites-file",
132
+ warnings: [
133
+ "Identity probe skipped (noProbe=true). Plugin reachability not verified.",
134
+ ],
135
+ }, false, { maxChars: 2500 });
136
+ }
137
+ let identity;
138
+ try {
139
+ identity = await probe(entry);
140
+ }
141
+ catch (e) {
142
+ const msg = e instanceof Error ? e.message : String(e);
143
+ return formatResult({
144
+ // The switch already happened; surface that the probe (not the
145
+ // switch) failed so the agent knows the active site DID change.
146
+ error: `Site "${name}" activated, but identity probe failed: ${msg}`,
147
+ context: { name, siteUrl: entry.url, platform: entry.platform },
148
+ hint: "Verify the site is reachable and the plugin is installed/active. " +
149
+ "Re-run with `noProbe: true` to activate without probing.",
150
+ }, true);
151
+ }
152
+ return formatResult({
153
+ activated: true,
154
+ profile: { name: entry.site_id, siteUrl: entry.url, platform: entry.platform },
155
+ source: "sites-file",
156
+ identity: {
157
+ plugin_version: identity.plugin_version,
158
+ plugin_hash: identity.plugin_hash,
159
+ capabilities: identity.capabilities,
160
+ site_url: identity.site_url,
161
+ },
162
+ }, false, { maxChars: 3000 });
163
+ });
164
+ }
165
+ //# sourceMappingURL=sites-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sites-tools.js","sourceRoot":"","sources":["../../../src/modules/apimapper/sites-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { StructuredCallToolResult } from "@getimo/mcp-toolkit";
2
+ import { type ApiErrorCode } from "./client.js";
3
+ /**
4
+ * The minimal slice of a response this helper reads. `ExtApiResponse` (the
5
+ * shared client return type) is a structural superset, and the graph
6
+ * hydration object `{ error, status?, errorCode? }` also satisfies it, so
7
+ * both can flow through `restErrorResult` without a cast.
8
+ */
9
+ export interface RestErrorLike {
10
+ /** Human-readable error from the upstream response, if any. */
11
+ error?: string;
12
+ /** Coarse error classification used for the recovery hint + code fallback. */
13
+ errorCode?: ApiErrorCode | string;
14
+ /** HTTP status, used as the `code` fallback when `errorCode` is absent. */
15
+ status?: number;
16
+ }
17
+ /** Per-site overrides for the canonical REST-error mapping. */
18
+ export interface RestErrorOpts {
19
+ /**
20
+ * Fallback message when `response.error` is absent. Mirrors the per-tool
21
+ * `r.error ?? "<fallback>"` string each site used inline.
22
+ */
23
+ message?: string;
24
+ /**
25
+ * Bespoke suggestion that overrides the default `hintFor(response.errorCode)`.
26
+ * Use only where a site intentionally pinned a tool-specific recovery hint.
27
+ */
28
+ suggestion?: string;
29
+ /**
30
+ * Bespoke `code` fallback that overrides the default `String(status)` when
31
+ * `response.errorCode` is absent. Use only where a site pinned a domain code.
32
+ */
33
+ code?: string;
34
+ }
35
+ /**
36
+ * Build the canonical structured error result for a failed REST request.
37
+ *
38
+ * Behaviour-preserving replacement for the 67× inline
39
+ * `errorResult({ message: r.error ?? …, code: …, suggestion: hintFor(…), details })`
40
+ * block. See the file header for the exact mapping and the opts contract.
41
+ *
42
+ * @param response the failed response (`!response.success` already checked by the caller)
43
+ * @param details the structured `details` payload (typically the echoed input params)
44
+ * @param opts per-site overrides — see {@link RestErrorOpts}
45
+ */
46
+ export declare function restErrorResult(response: RestErrorLike, details?: Record<string, unknown>, opts?: RestErrorOpts): StructuredCallToolResult;
@@ -0,0 +1,63 @@
1
+ // src/modules/apimapper/tool-result.ts — shared REST-error result builder.
2
+ //
3
+ // A1 (Wave-B audit, 2026-06-03): ~67 tool handlers across the apimapper
4
+ // modules hand-wrote the IDENTICAL post-request error block:
5
+ //
6
+ // if (!r.success) {
7
+ // return errorResult({
8
+ // message: r.error ?? "<per-tool fallback>",
9
+ // code: r.errorCode ?? (r.status ? String(r.status) : undefined),
10
+ // suggestion: hintFor(r.errorCode),
11
+ // details: { ...inputParams },
12
+ // });
13
+ // }
14
+ //
15
+ // `restErrorResult(r, details?, opts?)` collapses that block to a single
16
+ // call while preserving the output BYTE-FOR-BYTE. The mapping is:
17
+ //
18
+ // message → r.error ?? opts.message ?? "request failed"
19
+ // code → r.errorCode ?? (r.status ? String(r.status) : undefined)
20
+ // suggestion → opts.suggestion ?? hintFor(r.errorCode)
21
+ // details → details (passed through verbatim; computed by the caller)
22
+ //
23
+ // Per-site nuance is preserved through `opts`:
24
+ // - opts.message : the per-tool fallback string when `r.error` is absent.
25
+ // - opts.suggestion : a bespoke suggestion that overrides hintFor() (used by
26
+ // the few sites that want a tool-specific recovery hint
27
+ // regardless of the error code).
28
+ // - opts.code : a bespoke `code` fallback that overrides the
29
+ // `r.status`-derived default when `r.errorCode` is absent
30
+ // (used by sites that pin a domain code like
31
+ // "credential_lookup_failed").
32
+ //
33
+ // Sites whose error is NOT a `!response.success` REST failure (e.g. a
34
+ // post-success "entity not found" semantic check, or a `bad_request`
35
+ // validation guard with a hardcoded message/code/suggestion) deliberately
36
+ // stay on the raw `errorResult({...})` form — they are documented per-site
37
+ // and must NOT be funnelled through this helper, because their message/code
38
+ // do not derive from the response shape.
39
+ import { errorResult } from "@getimo/mcp-toolkit";
40
+ import { hintFor } from "./client.js";
41
+ /**
42
+ * Build the canonical structured error result for a failed REST request.
43
+ *
44
+ * Behaviour-preserving replacement for the 67× inline
45
+ * `errorResult({ message: r.error ?? …, code: …, suggestion: hintFor(…), details })`
46
+ * block. See the file header for the exact mapping and the opts contract.
47
+ *
48
+ * @param response the failed response (`!response.success` already checked by the caller)
49
+ * @param details the structured `details` payload (typically the echoed input params)
50
+ * @param opts per-site overrides — see {@link RestErrorOpts}
51
+ */
52
+ export function restErrorResult(response, details, opts = {}) {
53
+ const errorCode = response.errorCode;
54
+ return errorResult({
55
+ message: response.error ?? opts.message ?? "request failed",
56
+ code: errorCode !== undefined && errorCode !== ""
57
+ ? String(errorCode)
58
+ : opts.code ?? (response.status ? String(response.status) : undefined),
59
+ suggestion: opts.suggestion ?? hintFor(errorCode),
60
+ ...(details !== undefined ? { details } : {}),
61
+ });
62
+ }
63
+ //# sourceMappingURL=tool-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-result.js","sourceRoot":"","sources":["../../../src/modules/apimapper/tool-result.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,wEAAwE;AACxE,6DAA6D;AAC7D,EAAE;AACF,sBAAsB;AACtB,2BAA2B;AAC3B,mDAAmD;AACnD,wEAAwE;AACxE,0CAA0C;AAC1C,qCAAqC;AACrC,UAAU;AACV,MAAM;AACN,EAAE;AACF,yEAAyE;AACzE,kEAAkE;AAClE,EAAE;AACF,6DAA6D;AAC7D,0EAA0E;AAC1E,yDAAyD;AACzD,2EAA2E;AAC3E,EAAE;AACF,+CAA+C;AAC/C,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,uDAAuD;AACvD,qEAAqE;AACrE,gFAAgF;AAChF,mEAAmE;AACnE,qDAAqD;AACrD,EAAE;AACF,sEAAsE;AACtE,qEAAqE;AACrE,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,yCAAyC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,OAAO,EAAqB,MAAM,aAAa,CAAC;AAoCzD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAuB,EACvB,OAAiC,EACjC,OAAsB,EAAE;IAExB,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;IACrC,OAAO,WAAW,CAAC;QACjB,OAAO,EAAE,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,gBAAgB;QAC3D,IAAI,EACF,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;YACzC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;YACnB,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1E,UAAU,EACR,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,SAAqC,CAAC;QACnE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC"}
@@ -23,9 +23,9 @@ export interface ToolsListMeasurement {
23
23
  }
24
24
  /** The full Task-B result: the post-W3 and pre-W3-equivalent surfaces. */
25
25
  export interface ToolsListComparison {
26
- /** Post-W3 `tools/list` — the 17 surface tools the server exposes today. */
26
+ /** Post-W3 `tools/list` — the 19 surface tools the server exposes today. */
27
27
  postW3: ToolsListMeasurement;
28
- /** Pre-W3-equivalent `tools/list` — all 76 tools exposed flat (no gateway). */
28
+ /** Pre-W3-equivalent `tools/list` — all 78 tools exposed flat (no gateway). */
29
29
  preW3Flat: ToolsListMeasurement;
30
30
  /** Absolute byte reduction (preW3Flat.totalBytes − postW3.totalBytes). */
31
31
  bytesSaved: number;
@@ -39,17 +39,18 @@ export interface ToolsListComparison {
39
39
  */
40
40
  export declare function toCatalogEntry(name: string, tool: Pick<CollectedTool, "description" | "inputSchema" | "annotations">): ToolCatalogEntry;
41
41
  /**
42
- * Builds the full 77-tool catalog from the current build and measures the
42
+ * Builds the full 79-tool catalog from the current build and measures the
43
43
  * post-W3 vs pre-W3-equivalent `tools/list` payload sizes.
44
44
  *
45
- * Surface composition (verified against `gateway/essentials.ts` + `src/index.ts`):
46
- * - module tools : 13 essentials + `apimapper_advanced` = 14 (on the real
47
- * McpServer) + 60 advanced (gateway registry) = 74
45
+ * Surface composition (verified against `gateway/essentials.ts` + `src/index.ts`,
46
+ * pinned live in `gateway/gateway.test.ts` A2):
47
+ * - module tools : 15 essentials + `apimapper_advanced` = 16 (on the real
48
+ * McpServer) + 60 advanced (gateway registry) = 76
48
49
  * - top-level tools: rest_modules_status + use_profile + list_profiles = 3
49
- * total = 77
50
+ * total = 79
50
51
  *
51
- * POST-W3 `tools/list` = the 14 module-real tools + the 3 top-level tools = 17.
52
- * PRE-W3 flat `tools/list` = the 16 non-gateway surface tools + the 60 advanced
53
- * tools = 76 (the `apimapper_advanced` gateway did not exist pre-W3).
52
+ * POST-W3 `tools/list` = the 16 module-real tools + the 3 top-level tools = 19.
53
+ * PRE-W3 flat `tools/list` = the 18 non-gateway surface tools + the 60 advanced
54
+ * tools = 78 (the `apimapper_advanced` gateway did not exist pre-W3).
54
55
  */
55
56
  export declare function measureToolsList(): Promise<ToolsListComparison>;
@@ -4,16 +4,17 @@
4
4
  // JSON schemas an MCP client receives once per session, before any tool is
5
5
  // called. This is the DOMINANT token cost center of an API Mapper session.
6
6
  //
7
- // Two figures, both derived from the CURRENT build:
7
+ // Two figures, both derived from the CURRENT build (canonical counts asserted
8
+ // live in gateway/gateway.test.ts — A2, 2026-06-03):
8
9
  //
9
- // - POST-W3 `tools/list` — the 17 surface tools the server now exposes
10
- // (13 module essentials + `apimapper_advanced`
10
+ // - POST-W3 `tools/list` — the 19 surface tools the server now exposes
11
+ // (15 module essentials + `apimapper_advanced`
11
12
  // + the 3 src/index.ts top-level tools).
12
- // - PRE-W3-equivalent `tools/list` — what `tools/list` WOULD be if all 77
13
+ // - PRE-W3-equivalent `tools/list` — what `tools/list` WOULD be if all 79
13
14
  // tools were exposed flat (the pre-Gateway
14
- // state): the 17 surface tools minus the
15
+ // state): the 19 surface tools minus the
15
16
  // gateway tool, plus the 60 advanced-registry
16
- // tool configs — 76 flat tools. (Pre-W3 the
17
+ // tool configs — 78 flat tools. (Pre-W3 the
17
18
  // `apimapper_advanced` gateway did not exist.)
18
19
  //
19
20
  // Per-tool serialization mirrors what the MCP SDK puts on the wire for one
@@ -136,18 +137,19 @@ function captureTopLevelTools() {
136
137
  return captured;
137
138
  }
138
139
  /**
139
- * Builds the full 77-tool catalog from the current build and measures the
140
+ * Builds the full 79-tool catalog from the current build and measures the
140
141
  * post-W3 vs pre-W3-equivalent `tools/list` payload sizes.
141
142
  *
142
- * Surface composition (verified against `gateway/essentials.ts` + `src/index.ts`):
143
- * - module tools : 13 essentials + `apimapper_advanced` = 14 (on the real
144
- * McpServer) + 60 advanced (gateway registry) = 74
143
+ * Surface composition (verified against `gateway/essentials.ts` + `src/index.ts`,
144
+ * pinned live in `gateway/gateway.test.ts` A2):
145
+ * - module tools : 15 essentials + `apimapper_advanced` = 16 (on the real
146
+ * McpServer) + 60 advanced (gateway registry) = 76
145
147
  * - top-level tools: rest_modules_status + use_profile + list_profiles = 3
146
- * total = 77
148
+ * total = 79
147
149
  *
148
- * POST-W3 `tools/list` = the 14 module-real tools + the 3 top-level tools = 17.
149
- * PRE-W3 flat `tools/list` = the 16 non-gateway surface tools + the 60 advanced
150
- * tools = 76 (the `apimapper_advanced` gateway did not exist pre-W3).
150
+ * POST-W3 `tools/list` = the 16 module-real tools + the 3 top-level tools = 19.
151
+ * PRE-W3 flat `tools/list` = the 18 non-gateway surface tools + the 60 advanced
152
+ * tools = 78 (the `apimapper_advanced` gateway did not exist pre-W3).
151
153
  */
152
154
  export async function measureToolsList() {
153
155
  const server = new McpServer({
@@ -1 +1 @@
1
- {"version":3,"file":"toolslist-size.js","sourceRoot":"","sources":["../../../src/modules/apimapper/toolslist-size.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toolslist-size.js","sourceRoot":"","sources":["../../../src/modules/apimapper/toolslist-size.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,27 @@ export interface Credential {
39
39
  auth_type: string;
40
40
  oauth_provider?: string | null;
41
41
  oauth_token_expires_at?: string | null;
42
+ /**
43
+ * Wave-12 F1 (Cold-AI #6) — canonical token-validity surface emitted by the
44
+ * PHP `/credentials` endpoint (`CredentialRepository::calculateStatus`).
45
+ * Values: 'active' | 'expiring' | 'expired' | 'broken'.
46
+ *
47
+ * - 'active' covers credentials with a refresh-token even if their
48
+ * short-lived access token's `oauth_token_expires_at` is in the past —
49
+ * they auto-renew on next use.
50
+ * - 'expired' is the only state where the customer truly needs to reconnect.
51
+ *
52
+ * The onboarding suggestion engine MUST prefer this field over the raw
53
+ * `oauth_token_expires_at` heuristic to avoid false-positive reconnect
54
+ * prompts for refreshable tokens (Google, GitHub, etc.).
55
+ */
56
+ status?: "active" | "expiring" | "expired" | "broken" | string | null;
57
+ /**
58
+ * Hard-expiry timestamp emitted ONLY for credentials WITHOUT a refresh-token
59
+ * (e.g. Meta/Instagram 60-day expiry). When this field is null/absent on an
60
+ * OAuth credential, the token is auto-refreshable and not user-visibly expirable.
61
+ */
62
+ token_hard_expires_at?: string | null;
42
63
  provider?: string | null;
43
64
  created_at?: string;
44
65
  updated_at?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/modules/apimapper/types.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,EAAE;AACF,yEAAyE;AACzE,iGAAiG;AACjG,oFAAoF;AACpF,wEAAwE;AACxE,iFAAiF;AACjF,sEAAsE;AACtE,6EAA6E;AAC7E,mGAAmG;AACnG,EAAE;AACF,qFAAqF;AA8HrF,gFAAgF;AAChF,iEAAiE;AACjE,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,MAAM,CAAmB,KAAmB;IAC1D,OAAO,KAAwD,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/modules/apimapper/types.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,EAAE;AACF,yEAAyE;AACzE,iGAAiG;AACjG,oFAAoF;AACpF,wEAAwE;AACxE,iFAAiF;AACjF,sEAAsE;AACtE,6EAA6E;AAC7E,mGAAmG;AACnG,EAAE;AACF,qFAAqF;AAmJrF,gFAAgF;AAChF,iEAAiE;AACjE,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,MAAM,CAAmB,KAAmB;IAC1D,OAAO,KAAwD,CAAC;AAClE,CAAC"}
@@ -0,0 +1,85 @@
1
+ /** How a tool's request body relates to the PHP route. */
2
+ export type ToolBodyKind = "structured" | "envelope";
3
+ /** One body-sending tool's route binding. */
4
+ export interface ToolWireBinding {
5
+ /** HTTP method + normalised path, e.g. "POST /connections". Joins the manifest. */
6
+ route: string;
7
+ /** The literal wire body keys the tool sends (envelope tools list their wrapper key). */
8
+ bodyKeys: readonly string[];
9
+ kind: ToolBodyKind;
10
+ }
11
+ /**
12
+ * Curated bridge: body-sending tool → route + wire body keys.
13
+ *
14
+ * ONLY tools that send a request body appear here. Read-only (GET) tools and
15
+ * path/query-only tools carry no body-drift surface and are listed in the
16
+ * manifest's `_local_tools` (when they hit no route at all) or are simply
17
+ * absent (when they hit a GET route — GET routes never drift on body keys).
18
+ *
19
+ * `envelope` tools forward a free-form record (`patch` / `pipeline` / a settings
20
+ * map) whose individual keys are validated on the PHP side (e.g.
21
+ * ConnectionAdminController::ALLOWED_PATCH_KEYS). Their wrapper key is recorded
22
+ * so the test confirms the tool is accounted for; per-key validation lives in
23
+ * the PHP layer and is covered by PHP-side tests.
24
+ */
25
+ export declare const TOOL_WIRE_MAP: Readonly<Record<string, ToolWireBinding>>;
26
+ /** The PHP-accepted-params manifest fixture shape. */
27
+ export interface PhpAcceptedManifest {
28
+ /** "<METHOD> <path>" → accepted request-body keys. */
29
+ routes: Record<string, string[]>;
30
+ /** tool → { wire-key → justification } for keys the PHP route does not read. */
31
+ _allowed_drift: Record<string, Record<string, string>>;
32
+ /** tool → reason: tools with no REST route (purely client-side / aggregate). */
33
+ _local_tools: Record<string, string>;
34
+ /** route → { php-key → reason } for keys PHP accepts that no tool sends. */
35
+ _inverse_ignore?: Record<string, Record<string, string>>;
36
+ _meta?: Record<string, unknown>;
37
+ }
38
+ /** A single forward-direction drift: a wire key the PHP route does not accept. */
39
+ export interface DriftFinding {
40
+ tool: string;
41
+ route: string;
42
+ key: string;
43
+ }
44
+ /** A single inverse-direction advisory: a PHP-accepted key no tool sends. */
45
+ export interface InverseFinding {
46
+ route: string;
47
+ key: string;
48
+ }
49
+ export interface DriftReport {
50
+ /** Dangerous direction: tool sends a key PHP neither accepts nor allow-lists. */
51
+ drift: DriftFinding[];
52
+ /** Advisory: PHP accepts a key no tool sends (minus `_inverse_ignore`). */
53
+ inverse: InverseFinding[];
54
+ /** Live tools missing from BOTH TOOL_WIRE_MAP and `_local_tools` (coverage gap). */
55
+ uncovered: string[];
56
+ /** Entries in TOOL_WIRE_MAP / `_local_tools` no longer present in the live surface. */
57
+ stale: string[];
58
+ }
59
+ /**
60
+ * Resolve the committed fixture path. From this module
61
+ * (`<pkg>/{src,dist}/modules/apimapper/whitelist-drift.{ts,js}`) the package
62
+ * root is three directories up; the fixture is `tests/fixtures/...` under it.
63
+ * The depth is identical for the source layout (vitest/tsx) and the built
64
+ * `dist/` layout, so the same relative offset works in both.
65
+ */
66
+ export declare function manifestPath(): string;
67
+ /** Load + validate the committed PHP-accepted-params manifest. */
68
+ export declare function loadManifest(path?: string): PhpAcceptedManifest;
69
+ /**
70
+ * Enumerate every registered MCP tool name. Mirrors the runtime tool surface:
71
+ * - module essentials forwarded to a real McpServer,
72
+ * - the gateway-captured advanced tools,
73
+ * - the profile / status tools registered in src/index.ts AFTER module load.
74
+ *
75
+ * The src/index.ts trio is appended explicitly: they are registered on the real
76
+ * server outside the module's register(), so a module-only enumeration would
77
+ * miss them. They are pure local/profile tools (no REST body) and live in
78
+ * `_local_tools`; listing them here keeps the coverage check honest.
79
+ */
80
+ export declare function collectLiveTools(): string[];
81
+ /**
82
+ * Compute the drift report from the live tool surface + the curated wire map +
83
+ * the PHP-accepted manifest. Pure — no I/O.
84
+ */
85
+ export declare function computeDrift(liveTools: readonly string[], manifest: PhpAcceptedManifest): DriftReport;