salesforce-metadata-mcp 2.8.7 → 2.11.2

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 CHANGED
@@ -1,5 +1,469 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.11.2] - 2026-08-06
4
+
5
+ ### Security — resolved all 5 production-dependency advisories (2 high, 3 moderate)
6
+
7
+ `@modelcontextprotocol/sdk` bumped `1.29.0` → `1.30.0` (minor, non-breaking). Every advisory traced
8
+ back to that one dependency:
9
+
10
+ | Package | Advisory | Severity |
11
+ |---|---|---|
12
+ | `@modelcontextprotocol/sdk` | vulnerable range 1.25.0–1.29.0 | moderate |
13
+ | `@hono/node-server` | path traversal in `serve-static` on Windows via encoded backslash (`%5C`) | moderate |
14
+ | `hono` | ReDoS in CORS middleware via `Access-Control-Request-Headers` | moderate |
15
+ | `ip-address` | leading-zero octet / CIDR-suffix / IPv4-mapped-IPv6 parsing bugs enabling SSRF and trust-boundary bypass (3 advisories) | high |
16
+ | `fast-uri` | host confusion via backslash authority introducer | high |
17
+
18
+ Only two of these actually required a change here. `hono`, `fast-uri`, and `ip-address` sit under
19
+ parent ranges (`^4.11.4`, `^3.0.1`, `^10.2.0`) that already admit their patched versions, so any fresh
20
+ install resolves them safely regardless of what this repo's lockfile happens to pin. `@hono/node-server`
21
+ did not: SDK 1.29.0 constrained it to `^1.19.9`, which cannot reach the patched 2.0.5. SDK 1.30.0
22
+ widens that to `^1.19.9 || ^2.0.5`. The SDK's own advisory needed the bump too.
23
+
24
+ **Note on why the lockfile is not the fix.** This package is a library — consumers resolve from the
25
+ `dependencies` ranges in `package.json` at install time and never see `package-lock.json`. Running
26
+ `npm audit fix` alone would have cleaned the local `npm audit` output while changing nothing for
27
+ anyone installing from npm. The dependency bump is what actually reaches users, and only once
28
+ published.
29
+
30
+ Resolved after the bump: `@modelcontextprotocol/sdk` 1.30.0, `@hono/node-server` 2.1.0, `hono` 4.13.0,
31
+ `fast-uri` 3.1.5, `ip-address` 10.4.0. `npm audit` reports 0 vulnerabilities for both production and
32
+ full trees.
33
+
34
+ Verified beyond the audit output, since the SDK is the protocol layer and a clean `tsc` proves nothing
35
+ about runtime: **stdio** transport handshakes and lists 223 tools; **HTTP** transport (`TRANSPORT=http`)
36
+ serves `/health`, completes an `initialize` over `/mcp`, 404s unknown paths, and still binds
37
+ `127.0.0.1` by default (the v2.8.8 hardening is intact — this mattered to check, as the changed
38
+ packages are exactly the ones behind that transport); and a real `tools/call` round-trip dispatches
39
+ through zod validation into the handler, failing only at the expected credentials boundary.
40
+
41
+ ### Fixed — server advertised a stale hardcoded version to MCP clients
42
+
43
+ `src/index.ts` hardcoded the version in four places (`McpServer` init, both startup banners, the
44
+ `/health` payload) and was never bumped for v2.11.0 or v2.11.1, so the server reported **2.10.0** in
45
+ its `initialize` response while `package.json` said 2.11.1. Now read from `package.json` at runtime via
46
+ `createRequire(import.meta.url)`, so it cannot drift again. A direct JSON import is not viable here:
47
+ `package.json` sits outside `tsconfig`'s `rootDir` (`./src`), so importing it would restructure `dist/`.
48
+
49
+ ### Docs
50
+
51
+ Corrected the tool count in `QUICKSTART.md` (212 → 223) and in the GitHub repository description
52
+ (212 → 223). Both had drifted for the same reason: neither ships in the npm tarball, so publishing
53
+ never surfaces them the way it does `README.md`/`TOOLS.md`/`package.json`.
54
+
55
+ ## [2.11.1] - 2026-08-03
56
+
57
+ ### Fixed — `sf_retrieve_metadata` reported success on zero-result retrieves, plus two dead parameters found while investigating
58
+
59
+ Ajay's follow-up report confirmed v2.11.0's `sf_create_agent_action`/`sf_describe_object` fixes were
60
+ correct — his contradicting evidence turned out to be tested against a stale Claude Desktop MCP
61
+ subprocess predating the rebuild (a recurring gotcha this project has hit before: a rebuilt `dist/`
62
+ only takes effect after a full restart). His genuinely new finding, independent of that mix-up, was
63
+ real: `sf_retrieve_metadata` returned `success: true` and `"Retrieved 1 file(s)."` for a retrieve that
64
+ found **zero** of the requested components — because Salesforce's retrieve zip always includes
65
+ `package.xml` as its own manifest even when every requested member comes back empty, and the file count
66
+ included it. Verified with his exact repro (4 nonexistent `GenAiFunction` names) against a control
67
+ retrieve of a real component.
68
+
69
+ Fixed in `retrieveMetadataAndWait`: the reported count now excludes `package.xml`, and when components
70
+ were requested by name but none came back, the result is `success: false` with an explicit message
71
+ listing what was requested — instead of a misleadingly cheerful count of a manifest nobody asked for.
72
+
73
+ **Investigating this surfaced two more, more severe versions of the same underlying problem**, both
74
+ previously untested: the tool's schema has advertised `metadataType`+`componentName` (single-component
75
+ shortcut) and `packageXml` (raw manifest) as alternatives to `components` since this tool existed, but
76
+ the handler only ever read `params.components` — the other two were silently no-ops. A call using
77
+ either form retrieved **nothing at all** (an empty `<unpackaged>` body) while still reporting a
78
+ "successful" retrieve of the manifest-only zip, even when the requested component genuinely existed.
79
+ Wired up both: `metadataType`/`componentName` now builds a single-item `components` array, and
80
+ `packageXml` now extracts the `<types>`/`<version>` content from the supplied document and uses it
81
+ directly as the retrieve request body (needs the `met:` namespace prefix added to every element, since
82
+ the SOAP body has no default namespace, unlike a standalone package.xml). Verified live for all three
83
+ paths: the shortcut form now retrieves a real flow's XML, the zero-match array form now fails honestly,
84
+ and a hand-written raw `packageXml` retrieve returns real content.
85
+
86
+ No regressions: `test-suite.mjs` 209/212 (2 pre-existing unrelated failures, same as before).
87
+
88
+ ## [2.11.0] - 2026-08-03
89
+
90
+ ### Fixed — `sf_create_agent_action` was fundamentally broken for Flow/ApexClass-backed actions; the misdiagnosis pointed users at their org's licensing instead of the real bug
91
+
92
+ Ajay reported that `sf_create_agent_action` failed for `type=Flow` even against a confirmed-Active
93
+ flow, and that the failure message wrongly concluded custom agent actions were unsupported in the org
94
+ ("check your Agentforce/Einstein licensing") — disprovable because he had just created five
95
+ Flow-backed actions successfully through Salesforce's own Agentforce Builder UI, in the same org, same
96
+ user, same flows.
97
+
98
+ **Root cause, found by following Ajay's own recommended debugging path (diff a UI-created action's
99
+ real XML against what the tool generates) and going further once retrieval came back empty:**
100
+ `sf_create_agent_action` built a classic Metadata API `.genAiFunction` deploy with
101
+ `<invocationTarget>` set to the flow/class **API name** — but UI-created actions, read back via the
102
+ Tooling API's `GenAiFunctionDefinition` object (the classic Metadata API's `GenAiFunction` type turned
103
+ out not to expose these records at all — confirmed by a wildcard retrieve finding zero results even
104
+ for the five UI-created ones), showed `InvocationTarget` holding an 18-character **record ID**
105
+ (`FlowDefinition.Id` / `ApexClass.Id`), not a name. The generic "Specify a valid invocationTarget and
106
+ invocationTargetType" error — previously treated as a reliable org-capability signal after testing in
107
+ an unrelated org — turned out to be Salesforce's error for *this exact payload bug* in an org that
108
+ supports the feature just fine.
109
+
110
+ Fixed by switching `sf_create_agent_action` from the classic Metadata API deploy to a Tooling API
111
+ `GenAiFunctionDefinition` upsert — the same mechanism Agentforce Builder itself uses — resolving
112
+ `reference` to the right record ID first (`FlowDefinition.DeveloperName` → `Id` for Flow,
113
+ `ApexClass.Name` → `Id` for ApexClass). Verified live end-to-end, not just unit-tested: created a real
114
+ action against Ajay's own reported flow through the actual registered tool handler (reproducing his
115
+ repro exactly), confirmed the fix also works for ApexClass, and confirmed a Tooling-API-created action
116
+ is correctly picked up by a topic (`GenAiPlugin`) deployed the normal Metadata-API way — the two APIs
117
+ share the same underlying records, so mixing them across the 5-step agent sequence is safe.
118
+ `PromptTemplate`/`DataCategoryGroup`/`ExternalService` are now honestly refused (clear "not yet
119
+ verified" message) rather than silently deploying an unverified, likely-broken payload — matching this
120
+ project's standing rule not to ship unverified metadata behavior.
121
+
122
+ **`sf_create_agent`'s pre-flight capability probe (added in v2.10.0)** used the same broken deploy
123
+ path internally, so it always failed and hard-blocked agent creation even in orgs — like this one —
124
+ where it works fine. Rewritten to match: it now attempts a real Tooling API insert with a
125
+ syntactically-valid-but-nonexistent target ID. This fails fast on a specific field-validation error in
126
+ any org where the object exists (verified live: `INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST`), and since
127
+ nothing is ever actually written, there's no cleanup step either — simpler than the old probe, which
128
+ had to deploy-then-delete a throwaway. Verified live: `sf_create_agent` now succeeds normally in this
129
+ org, both with and without `skipActionCapabilityCheck`.
130
+
131
+ Also fixed: `sf_describe_object` returned a bare `NOT_FOUND` 404 for standard objects whose *feature*
132
+ is disabled (Ajay's repro: `Quote`, when the Quotes feature is off in Setup) — indistinguishable from a
133
+ typo'd or nonexistent object name. Added a hint for a hardcoded list of commonly feature-gated standard
134
+ objects (Quote, Contract, Order, Campaign, Territory2, WorkOrder, ServiceAppointment, etc.) pointing at
135
+ Setup instead of sending the user hunting for a naming mistake that isn't there.
136
+
137
+ **`qa-agentforce.mjs` needed a substantial rewrite, not just the tool code.** The suite's own
138
+ assertions were written under the same now-disproven assumption ("demo-org cannot create GenAiFunction
139
+ actions") baked into skip logic throughout — so the action/topic verification paths had never actually
140
+ executed in any prior session, and once they finally ran (because the underlying bug they were gated
141
+ behind is now fixed), they surfaced a second, independent, pre-existing gap: `existsInOrg`'s plain REST
142
+ `queryRecords` can't see `GenAiFunction`/`GenAiFunctionDefinition` (Tooling-API-only, confirmed) or
143
+ `GenAiPlugin` (no SOQL interface at all, confirmed both plain REST and Tooling — only readable via
144
+ classic Metadata API `readMetadata`) — it happened to work before only because those checks were never
145
+ reached. Rewrote `existsInOrg` to dispatch to the right API per type, and rewrote the action-type
146
+ matrix check to read `GenAiFunctionDefinition.InvocationTargetType` back via Tooling API instead of a
147
+ `retrieveMetadata` call that (per the finding above) was always going to come back empty. Suite went
148
+ from 33 passed/15 failed (pre-fix) to 35 passed/2 failed against a live org.
149
+
150
+ **Known open item, not a code defect:** after extensive live testing today (mine plus Ajay's own
151
+ UI-based testing), further `GenAiFunctionDefinition` inserts in `demo-org` started failing with
152
+ `DUPLICATE_DEVELOPER_NAME` ("...already exists or has been previously used") even against
153
+ brand-new, never-used developer names and master labels — isolated by testing fresh-name/reused-label
154
+ and fresh-everything/reused-target combinations independently; neither explains it, and the condition
155
+ persisted for several minutes and across unrelated work. Most likely an org-side rate limit or cooldown
156
+ on this object triggered by the volume of creates/deletes during today's testing, not a regression in
157
+ this fix — the two remaining `qa-agentforce.mjs` failures are this condition surfacing honestly through
158
+ the tool's real error message, not a masked defect. Re-run the suite after some time has passed to
159
+ confirm it clears; if it doesn't, this needs further investigation as a genuine platform limit.
160
+
161
+ ## [2.10.0] - 2026-08-01
162
+
163
+ ### Fixed/Added — 4 more findings from an extended manual test session (Bugs 6-8, and a sharper Bug 3), plus 2 new tools
164
+
165
+ Ajay's follow-up report superseded the previous one. Bugs 1, 2, 4, 5 from that report were already
166
+ fixed in v2.9.0 (confirmed still present in this session, not re-fixed) — the report describing them
167
+ as unfixed was written from a Claude Desktop session whose MCP server subprocess had been running
168
+ since before v2.9.0 landed; restarting Claude Desktop picks up a rebuilt `dist/`, an already-spawned
169
+ subprocess does not. New findings below.
170
+
171
+ **Bug 3, revisited with much stronger evidence.** The previous release's conclusion (org-side schema
172
+ propagation lag) held, but Ajay's new evidence sharpened *what kind* of lag it is: persisted 2+ hours
173
+ in his session (ruling out ordinary propagation delay), and — critically — REST describe worked fine
174
+ on **pre-existing** custom fields on standard objects (Opportunity's own custom fields) while failing
175
+ on everything newly created, which looked like it might be specific to brand-new custom *objects*
176
+ rather than fields in general. Tested that distinction directly and decisively: created a field on the
177
+ standard `Account` object and a field on a brand-new custom object side by side, then polled both for
178
+ 2 full minutes. **Both were equally stuck** — this rules out "new object vs. existing object" as the
179
+ differentiator. The real explanation: Ajay's "working" standard-object fields were older, already-
180
+ propagated fields from earlier sessions, not freshly created ones — not evidence that new fields on
181
+ standard objects propagate faster. Also directly tested Ajay's identity-mismatch hypothesis (REST and
182
+ Metadata clients authenticating as different users): confirmed live that both use the exact same
183
+ `auth.accessToken`, resolving to the same user (`semwalajaydevorg@agentforce.com`) and same org ID —
184
+ ruled out. Revised, more precise conclusion: this org has a severe (multi-hour-observed), general
185
+ schema-cache propagation lag affecting all newly created fields, regardless of parent object type —
186
+ still not something any client-side code change can fix.
187
+
188
+ **Bug 6: `sf_create_agent` now probes GenAiFunction (custom action) support before creating a Bot
189
+ shell.** Reproduced Ajay's exact finding: active Agentforce permission set licenses are not sufficient
190
+ evidence that custom actions work — confirmed by deploying a `GenAiFunction` aimed at a deliberately
191
+ nonexistent target and getting the identical generic error a real target would get, meaning the org
192
+ never even attempts target resolution. Added a pre-flight probe (a real, throwaway `GenAiFunction`
193
+ deploy, cleaned up automatically) that runs before the Bot shell is created on the first call in the
194
+ 5-step sequence: if actions aren't supported, the call fails immediately with no shell created, instead
195
+ of leaving an orphaned Bot with no planner/topic/action once step 2 turns out to be unreachable. Added
196
+ `skipActionCapabilityCheck` for topics-only agents that don't need custom actions. Verified live both
197
+ ways: the probe correctly blocks with no shell created, and the skip flag correctly bypasses it.
198
+
199
+ **Bug 7: `sf_create_agent_topic` now validates that every referenced action exists before deploying.**
200
+ Previously, a topic referencing a missing action deployed and failed with an opaque Salesforce support
201
+ ErrorId naming nothing. `GenAiFunction` isn't SOQL/Tooling-queryable in every org (confirmed: it isn't
202
+ in `demo-org`), so existence is checked via Metadata API `readMetadata` instead, which works regardless
203
+ of SOQL support for the type. Verified live: a topic referencing a nonexistent action is now rejected
204
+ before ever reaching Salesforce, naming the specific missing action.
205
+
206
+ **Bug 8: added `sf_delete_metadata`.** There was previously no way to remove anything deployed by this
207
+ MCP server — `sf_deploy_metadata` has no `destructiveChanges` support, and diagnostic/orphaned metadata
208
+ had nowhere to go (confirmed: Ajay's stranded `AccountOpportunityAgent` Bot shell was still in the org,
209
+ alongside 13 similar leftovers from earlier sessions). Wraps the `deleteMetadata` SOAP call, which
210
+ already existed as an internal service function but was never exposed as a tool. Verified live with a
211
+ real round-trip (create → delete → confirm gone) and by actually attempting cleanup of the accumulated
212
+ org backlog: correctly surfaced Salesforce's own 10-record-per-call limit (batched around it), and
213
+ correctly surfaced a real dependency-order error when a `GenAiPlannerBundle` was still referenced by a
214
+ Bot. The specific stuck Bot records from earlier sessions remain undeletable — a pre-existing, already-
215
+ documented Salesforce-side "unexpected error" on those particular records, not something this tool or
216
+ any client-side retry can work around.
217
+
218
+ **Documented, not a bug**: Flow `textTemplates` strip leading/trailing whitespace on deploy while
219
+ preserving internal newlines — concatenating per-iteration templates in a loop without an internal
220
+ separator runs lines together. Added to the `sf_create_flow` schema description.
221
+
222
+ **Confirmed already fixed, not re-touched**: Bugs 1 (duplicate Decision rule names), 2 (filter value
223
+ typing), 4 (FLS warning), 5 (raw-XML pre-validation) — all still present and correct in this codebase,
224
+ verified by direct inspection before assuming anything needed re-fixing.
225
+
226
+ Tool count 222→223 (`sf_delete_metadata`). Regression: `qa-agentforce.mjs` gained 5 new checks for
227
+ Bugs 6/7 (all existing `sf_create_agent` calls updated with `skipActionCapabilityCheck` so the new
228
+ probe doesn't change what those pre-existing tests were actually testing); `test-suite.mjs` gained a
229
+ real create→delete→confirm-gone round-trip test for `sf_delete_metadata`.
230
+
231
+ ## [2.9.0] - 2026-08-01
232
+
233
+ ### Fixed — 5 real bugs from a genuine manual test session in Claude Desktop, all reproduced and re-verified live
234
+
235
+ Ajay tested v2.8.9 by hand in Claude Desktop against a real Developer Edition org — created a custom
236
+ object, six custom fields, and two Flows built against them — and reported five specific issues found
237
+ along the way. Every one below was reproduced first (not assumed from the report), root-caused in the
238
+ source, fixed, and re-verified against `demo-org` before being called done.
239
+
240
+ **`sf_create_flow` emits duplicate rule developer names for 2+ Decision elements (blocking).**
241
+ Reproduced exactly: `Deployment failed: Duplicate developer name: Rule_1`. Root cause: each Decision's
242
+ rule `<name>` was `Rule_1`, `Rule_2`, ... scoped per-decision, but Salesforce requires uniqueness across
243
+ the whole Flow. Fixed in both XML generators by namespacing with the parent Decision's own name
244
+ (`Decision_One_Rule_1`), verified unique in the deployed XML afterward. Fixing this surfaced a second,
245
+ related bug in the same code path: `<defaultConnectorLabel>` was only emitted when `defaultConnector`
246
+ was set, but Salesforce requires it unconditionally (it labels the implicit "no rule matched" branch,
247
+ which exists whether or not it connects anywhere) — every existing Decision test in this repo's own
248
+ suite happened to set `defaultConnector` explicitly, which is exactly why this had never been caught.
249
+ Fixed in both generators; added a permanent regression test with two Decisions, the second deliberately
250
+ relying on implicit fall-through. Flow suite: 142→144 checks, 144/144 passing.
251
+
252
+ **`sf_create_flow`'s filter/assignment values only accepted strings, and GetRecords filters silently
253
+ mistyped numbers.** The schema rejected a native boolean (`value: true`) with a bare zod error; the
254
+ reported workaround (`value: "true"`) did work correctly (booleans were already string-sniffed
255
+ correctly), but investigating this surfaced a real, more serious, previously-unreported bug in the same
256
+ code: GetRecords filter values had NO numeric detection at all — unlike Decision/CreateRecords/
257
+ UpdateRecords, which all correctly detect numeric-looking values, GetRecords filters emitted
258
+ `<stringValue>100</stringValue>` for every non-boolean value including numbers, which risks incorrect
259
+ or no matches when filtering Number/Currency/Percent fields with comparison operators. Fixed the missing
260
+ numeric detection in both generators, and widened `rightValue`/`filterValue`/`filters[].value`/
261
+ `inputAssignments[].value`/`assignments[].value` to accept string, number, or boolean directly (coerced
262
+ to string before the existing, now-correct typed-XML logic) so the natural call shape works without a
263
+ string-coercion workaround. Verified live: a native boolean and a native number filter both produce the
264
+ correct typed XML element in the deployed flow.
265
+
266
+ **REST describe / SOQL not seeing custom fields that the Metadata API and Tooling API confirm exist.**
267
+ Reproduced exactly — `describe field count: 10` (only standard fields), matching the report precisely,
268
+ persisting well past 60 seconds and after granting FLS (also reproduced: 0 grants by default). Ruled
269
+ out an in-process cache (there isn't one — `sf_describe_object` makes a fresh HTTP call every time,
270
+ confirmed by reading the code) and ruled out XML element ordering in the picklist-value generator via a
271
+ controlled live A/B test (an initial hypothesis that looked promising but didn't hold up once tested
272
+ head-to-head). What's actually happening: Salesforce's own REST describe/SOQL schema cache lagged
273
+ behind the Metadata API and (intermittently, itself) the Tooling API by 10+ minutes on this org during
274
+ testing — a genuine platform-side propagation characteristic, not something any client-side code
275
+ change can fix. Implemented the mitigation Ajay suggested regardless: `sf_describe_object` gained
276
+ `waitForFields`/`timeoutSeconds` to poll until named fields appear (or say clearly that they still
277
+ haven't, with a pointer to the Tooling API to confirm the field truly exists), so callers don't have to
278
+ hand-roll retry loops. Documented plainly in both the tool description and the CHANGELOG that this is
279
+ an org-side lag, not a bug in this server — don't re-diagnose it as one without new evidence.
280
+
281
+ **`sf_create_custom_field` leaves every new field with zero FLS grants and no indication a follow-up
282
+ call is needed.** Reproduced: `sf_get_field_permissions` returns 0 grants immediately after a
283
+ `success: true` field creation, for every profile including System Administrator. Fixed by checking FLS
284
+ right after creation and appending an explicit warning to the response when none exist, naming the
285
+ exact fix (`sf_create_field_level_security`) — chose this over auto-granting FLS by default since that
286
+ would silently change existing behavior; surfacing the truth is a strictly additive fix.
287
+
288
+ **`sf_create_flow_from_xml` surfaced raw, unhelpful Salesforce schema errors for 3 common mistakes.**
289
+ Added `validateAndNormalizeFlowXml()`: a bounded, depth-tracking tokenizer (not a full XML parser —
290
+ sufficient for direct children of the root `<Flow>` element) that catches, before ever deploying: (1)
291
+ non-contiguous top-level elements of the same type (interleaved `<assignments>`/`<decisions>` etc.,
292
+ which Salesforce reports as a baffling "Element X is duplicated at this location in type Flow" instead
293
+ of naming the real issue — grouping), (2) missing `<start>` `locationX`/`locationY`, auto-defaulted
294
+ rather than just flagged since there's no ambiguity about a safe default, (3) an SObject-typed
295
+ `<variables>` entry missing `<objectType>`, naming the specific variable (Salesforce's own error for
296
+ this one was already good — replicated its style for consistency, and to catch it pre-deploy instead of
297
+ after). Verified live: interleaved elements and a missing objectType are both now rejected pre-deploy
298
+ with a specific, actionable message and never reach Salesforce at all; missing start coordinates are
299
+ silently defaulted and the flow deploys successfully.
300
+
301
+ **Full regression, both before committing and after every individual fix**: `qa-flow-comprehensive.mjs`
302
+ 142→144/144 (2 new checks from the Bug 1 regression test, all passing). `test-suite.mjs` and the
303
+ Agentforce suites held their existing pass rates — none of these five fixes touch Agentforce code paths.
304
+
305
+ ## [2.8.9] - 2026-07-31
306
+
307
+ ### Fixed — the v2.8.8 command-injection guard was over-broad; narrowed after a second round of live testing
308
+
309
+ Asked for a second round of testing before publishing v2.8.8, rather than treating the first pass as
310
+ done. Good call: it surfaced a real false-positive regression in the fix itself. The original guard
311
+ rejected any `sf` CLI argument containing `` " ` $ & | ; < > ^ `` — but a systematic, one-character-
312
+ at-a-time live test (each character alone, then each paired with a quote) showed every one of those
313
+ metacharacters is completely inert on its own through cross-spawn; **only a literal `"` combined with
314
+ a following metacharacter reaches a live shell.** A quote alone never did either. That means the
315
+ original guard would have rejected entirely legitimate values this codebase's own tools pass
316
+ routinely — a package description like `"Sales & Service Tools"`, a company name like
317
+ `"O'Brien Industries"` — with zero actual security benefit, since none of those ever reach a shell
318
+ regardless. Narrowed to reject only `"` (plus raw newlines, never legitimate in a single CLI arg
319
+ either). Re-verified live, both directions: the original exploit payload (`"x & echo ... & echo x"`)
320
+ is still rejected; a package description containing `&` and `'` now reaches the real `sf` CLI instead
321
+ of being rejected by the guard.
322
+
323
+ ### Reviewed in depth on request — Flow builder and Agentforce agent/topic/action/planner creation
324
+
325
+ Ajay asked specifically for closer attention here. Read both Flow XML generators
326
+ (`buildFlowXml`/SOAP and `buildFlowDeployXml`/ZIP, ~800 lines combined) end to end and all four
327
+ Agentforce tools (`sf_create_agent`, `sf_create_agent_topic`, `sf_create_agent_action`,
328
+ `sf_create_agent_planner`) line by line, not just grep-sampled. Result: both Flow builders escape
329
+ every free-text value correctly and consistently (verified their `buildFilterValue`/
330
+ `typedResourceValue` helpers apply `x()` at every actual string-literal insertion point); the
331
+ remaining raw interpolations are all zod-enum-constrained `dataType` fields or booleans, not user
332
+ text, so no injection surface. Agentforce's XML construction is equally clean throughout.
333
+
334
+ **Did find one real, separate bug while reading this closely, unrelated to injection**:
335
+ `sf_create_agent_action`'s `inputs` parameter (input parameter mappings — `[{name, value}]`) is
336
+ accepted by the schema and documented, but was never wired into the generated `GenAiFunction` XML at
337
+ all — confirmed by grep, not a one-off oversight in this pass. Any caller who passed `inputs` had them
338
+ silently discarded, with no error and no indication in the response. This went uncaught because
339
+ `demo-org` cannot create `GenAiFunction` actions at all (a pre-existing, documented org-licensing
340
+ limit), so this parameter has never been exercised against a live org — and this project's own rule is
341
+ not to ship metadata XML shapes that haven't been verified that way. Rather than guess at the correct
342
+ XML (a real risk of shipping a second, differently-wrong bug), the tool's success message now says
343
+ explicitly when `inputs` was provided but not applied, so callers aren't silently misled. Implementing
344
+ it for real is still blocked on the same thing blocking the rest of GenAiFunction action testing: an
345
+ org where custom agent actions are actually licensed.
346
+
347
+ **Full regression**, both directions of this round: `test-suite.mjs` 207/211 passed — the one new
348
+ "failure" beyond the existing 2 pre-existing ones (`sf_share_report_folder`) is test-state
349
+ accumulation (it selects an existing report folder from the org, and today's own repeated
350
+ `test-suite.mjs` runs have created enough of them that one now has a too-long derived name), not a
351
+ code regression — unrelated to any change in this release. `qa-agentforce.mjs`,
352
+ `qa-agentforce-adjacent.mjs`, and `qa-flow-comprehensive.mjs` (142/142) all held their existing rates.
353
+
354
+ ## [2.8.8] - 2026-07-31
355
+
356
+ ### Security audit — one confirmed, exploitable command-injection vulnerability fixed, plus 13 more real findings across SOQL, generated-code, and credential-handling surfaces
357
+
358
+ Ajay asked for a standing security review of this project, not tied to any specific bug report. Went
359
+ through the codebase systematically rather than waiting for a report, and proved every finding below
360
+ by actually attempting the attack through the real, compiled MCP tool handler — not just reading code
361
+ and guessing. Everything here was found live against `demo-org`, the same standard this project holds
362
+ itself to for functional bugs.
363
+
364
+ **Command injection — CRITICAL, confirmed live-exploitable, now fixed.** Every `sf` CLI invocation in
365
+ this codebase built a shell command by joining an args array with spaces and running it through
366
+ `execSync`. Six tools passed unvalidated string parameters straight into that array:
367
+ `sf_create_scratch_org`, `sf_delete_scratch_org`, `sf_create_package`, `sf_create_package_version`,
368
+ `sf_install_package`, `sf_uninstall_package`, `sf_run_code_scanner`, `sf_scan_apex_antipatterns`.
369
+ Proof of concept: a `devHubAlias` of `DevHub & echo INJECTED > marker.txt & echo x` actually created
370
+ the marker file when run through `sf_create_scratch_org`'s real handler. Fixed by replacing every
371
+ `execSync`/`exec` call with `cross-spawn`, which passes each argument as a genuine argv entry instead
372
+ of shell text — re-verified the same payload no longer executes. **cross-spawn alone was not enough**:
373
+ an argument combining a literal `"` with a shell metacharacter (e.g. `"x & ... & echo x"`) still
374
+ reached a live shell even through cross-spawn 7.0.6's own escaping, because `sf` is a `.cmd` batch
375
+ shim on Windows and its internal `%*` argument-forwarding to node.exe is a second, uncontrolled
376
+ re-parsing step outside cross-spawn's reach — also proven live before being closed with an explicit
377
+ character allowlist (`runSfCli` now rejects any argument containing `"`, `` ` ``, `$`, `&`, `|`, `;`,
378
+ `<`, `>`, `^`, or a newline before it ever reaches cross-spawn; none of this codebase's CLI arguments —
379
+ aliases, IDs, paths, keys, rule selectors — ever legitimately need one). Also deleted `createScratchOrg`,
380
+ a second, entirely dead implementation of scratch-org creation with the same injection flaw plus
381
+ broken shell quoting that would have failed on both POSIX and Windows — confirmed zero references
382
+ anywhere before removing it.
383
+
384
+ **SOQL injection — real, live, found across 9 call sites.** `sf_get_field_history` (`recordId` and
385
+ `objectApiName`, the latter landing unquoted in a FROM-clause identifier position — no amount of
386
+ quote-escaping fixes that, only an identifier allowlist does), `sf_get_setup_audit_trail` /
387
+ `sf_get_login_history` / `sf_get_event_logs` (`startDate`/`endDate`, interpolated unquoted with zero
388
+ format validation), `sf_get_apex_test_results` (`testRunId`), `sf_detect_devops_merge_conflict` /
389
+ `sf_check_devops_commit_status` / `sf_list_devops_work_items` (`workItemId`/`projectId`/`stageId`),
390
+ and `sf_create_field_dependency` (`objectName`/`dependentField` in a Tooling API query). Fixed with a
391
+ new `soqlEscape()` helper (formalizing the backslash-quote pattern already used correctly at ~15 other
392
+ call sites in this file) and a new `assertSoqlDateLiteral()` validator for the unquoted date-literal
393
+ positions. `sf_query_records`'s raw `soql`/`whereClause`/`orderBy` and `sf_create_apex_batch`'s
394
+ `queryFilter` were deliberately left alone — both are documented, intentional raw-SOQL-fragment
395
+ parameters, the entire point of those tools, not an oversight.
396
+
397
+ **Code injection into generated, later-executed source — found in both Apex and TypeScript
398
+ generation.** `sf_create_invocable_action`'s `label`/`description` and its input/output variable
399
+ labels landed unescaped inside `@InvocableMethod`/`@InvocableVariable` annotation string literals in
400
+ generated Apex — an unescaped `'` breaks out of the literal and injects arbitrary class members into
401
+ a class that gets deployed and can execute. Same pattern in the (dead, unwired — see below)
402
+ `createApexScheduler`'s doc comment (a literal `*/` closes the comment early, turning the rest of the
403
+ generated file back into live code) and `createRestResource`'s `urlMapping`. Fixed with the same
404
+ `soqlEscape()` helper (Apex and SOQL use identical backslash-quote string-literal escaping) plus a
405
+ comment-safe `*/`-stripping helper for the comment-only cases. **More seriously, this same class of
406
+ bug was live and reachable** in `sf_create_mcp_server` and `sf_create_mcp_tool` (the tools that
407
+ scaffold a brand-new MCP server project on disk): `serverName` and `toolName` were spliced unescaped
408
+ into generated `.ts` source as string literals, and `sf_create_mcp_tool`'s `inputSchema` keys —
409
+ `z.record(z.unknown())`, so literally any string — were spliced in as raw, unquoted object-property
410
+ names with zero validation. Proof of concept: an `inputSchema` key of
411
+ `x(){require("fs").writeFileSync("pwn2","x");return z.string()` was accepted by the old code and would
412
+ have become live, executable code in the generated project the moment it was built and run. Fixed:
413
+ `serverName`/`toolName` now go through `JSON.stringify()` (matching how `toolDescription` was already
414
+ correctly handled in the same function — this was an inconsistency, not a from-scratch gap), and
415
+ `inputSchema` keys are now validated against a strict identifier regex before generation, with a clear
416
+ rejection instead of silent code smuggling.
417
+
418
+ **Credential leak in the codebase's own default error-sanitization path — real, high-impact, silently
419
+ broken since introduction.** `sanitizeError()` is called in essentially every one of this codebase's
420
+ ~100 catch blocks — it's what stands between an internal error and what gets returned to the calling
421
+ LLM/user. Its only token-redaction rule was `[A-Fa-f0-9]{40,}` (pure hex, 40+ chars). Real Salesforce
422
+ access tokens/session IDs look like `00Dxxxxxxxxxxxx!AQEAQ...` — base64url-ish with a literal `!`
423
+ separator, never pure hex — so a real token embedded in any error message (a network client echoing a
424
+ request URL, an API error quoting back session context) would have passed straight through
425
+ completely unredacted. Proved this live with a realistic fake token before and after the fix. There
426
+ was a second function, `redactSensitive()`, that had the right idea (a `Bearer` pattern, a `00D...`
427
+ pattern) but its own character classes stopped at the first `!` or `.`, so it only partially redacted
428
+ even the cases it targeted, and — separately — it was only ever called from 2 of the ~100 relevant
429
+ sites, so almost nothing benefited from it regardless. Fixed by broadening the character classes to
430
+ cover the actual token shape and having `sanitizeError()` call `redactSensitive()` internally, so
431
+ every existing caller gets the protection retroactively with no call-site changes needed.
432
+
433
+ **HTTP transport mode has no authentication and bound to all network interfaces by default.** This
434
+ project supports `TRANSPORT=http` as an alternative to the default stdio transport. Its `/mcp` endpoint
435
+ has no auth of its own — any request that reaches it executes MCP tools using whatever Salesforce
436
+ credentials the server process is configured with — and `http.Server.listen(port)` with no explicit
437
+ host binds to every interface, not just localhost, by Node's own default. Fixed: defaults to
438
+ `127.0.0.1` now; set `HOST` explicitly (e.g. behind a reverse proxy that adds real auth) to opt into
439
+ broader exposure instead of getting it by accident. This mode is opt-in and off by default (stdio is
440
+ the default transport), so this was a foot-gun for anyone who did enable it, not an always-on gap.
441
+
442
+ **Audited and confirmed clean, no action needed:** XML metadata builders (spot-checked ~60 candidate
443
+ interpolation sites; every one was already either correctly wrapped in the existing `x()` escaper or a
444
+ boolean/number field with no injection surface at all — the real gaps here were already closed in
445
+ v2.8.2). `npm audit`: still exactly the 2 moderate findings already documented and deliberately left
446
+ (a path-traversal bug in `@hono/node-server`'s `serve-static`, a transitive dependency of the MCP SDK
447
+ that this project's own HTTP transport — a from-scratch, two-route implementation — never calls into
448
+ regardless of transport mode; confirmed again this session, not just carried forward from memory).
449
+ Secrets/credential files: confirmed `.gitignore` still covers `.env`, `.env.local`, `*.key`, and
450
+ `CLAUDE.local.md`, and confirmed via `git log --all` that nothing secret-shaped has ever been committed.
451
+
452
+ **Also found, not fixed (dead code, zero live exposure, hardened anyway for defense-in-depth):**
453
+ `createInvocableAction`, `createApexScheduler`, and `createRestResource` are all exported from
454
+ `services/salesforce.ts` but never imported by any tool file — confirmed via full-codebase grep before
455
+ and after — so their injection fixes above protect nothing reachable today. Left in place rather than
456
+ deleted (unlike `createScratchOrg`, which was both dead *and* had no legitimate salvage value) since
457
+ these look like intended-but-never-wired functionality; flagging here so a future session that wires
458
+ them up inherits the fix rather than reintroducing the bug.
459
+
460
+ **Full regression confirmation:** `test-suite.mjs` (211 tests) — 208 passed, 2 failed (both pre-existing,
461
+ unrelated, intentional negative-test probes), 1 skipped — no change from the pre-audit baseline.
462
+ `qa-agentforce.mjs`, `qa-agentforce-adjacent.mjs`, and `qa-flow-comprehensive.mjs` all held their
463
+ existing pass rates. Every fix above was also independently proven by re-attempting its specific
464
+ exploit through the real, compiled tool handler and confirming it now fails cleanly instead of
465
+ executing.
466
+
3
467
  ## [2.8.7] - 2026-07-31
4
468
 
5
469
  ### Added — `sf_create_external_client_app`, and it closes a gap `sf_create_connected_app` structurally cannot
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
6
  [![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-green.svg)](https://modelcontextprotocol.io)
7
7
 
8
- **The only Salesforce MCP server that builds Agentforce agents, OmniStudio components, and DevOps Center pipelines** — alongside a complete daily developer loop (schema describe, Apex read, debug logs) and 222 tools total for building, configuring, and automating Salesforce orgs directly from Claude or any MCP client.
8
+ **The only Salesforce MCP server that builds Agentforce agents, OmniStudio components, and DevOps Center pipelines** — alongside a complete daily developer loop (schema describe, Apex read, debug logs) and 223 tools total for building, configuring, and automating Salesforce orgs directly from Claude or any MCP client.
9
9
 
10
10
  ---
11
11
 
@@ -47,7 +47,7 @@ See [SETUP.md](SETUP.md) for all authentication methods and detailed setup instr
47
47
 
48
48
  ---
49
49
 
50
- ## Tools — 222 total
50
+ ## Tools — 223 total
51
51
 
52
52
  Highlights below; see [TOOLS.md](TOOLS.md) for the complete reference with parameters and example prompts.
53
53
 
@@ -163,6 +163,7 @@ Highlights below; see [TOOLS.md](TOOLS.md) for the complete reference with param
163
163
  | `sf_deploy_metadata` | Deploy metadata via Metadata API (supports `testLevel`, inline XML) |
164
164
  | `sf_check_deploy_status` | Check deployment job status |
165
165
  | `sf_retrieve_metadata` | Retrieve metadata from the org |
166
+ | `sf_delete_metadata` | Permanently delete metadata components (CustomObject, CustomField, Flow, GenAiFunction, Bot, etc.) |
166
167
 
167
168
  ### MCP Server Management
168
169
  | Tool | Description |
@@ -210,7 +211,7 @@ Highlights below; see [TOOLS.md](TOOLS.md) for the complete reference with param
210
211
  ## Documentation
211
212
 
212
213
  - [SETUP.md](SETUP.md) — Prerequisites, authentication, Claude configuration
213
- - [TOOLS.md](TOOLS.md) — All 222 tools with full parameter documentation
214
+ - [TOOLS.md](TOOLS.md) — All 223 tools with full parameter documentation
214
215
  - [AGENTFORCE.md](AGENTFORCE.md) — Agentforce agent creation guide
215
216
  - [APEX_LWC.md](APEX_LWC.md) — Apex and LWC development guide
216
217
  - [CHANGELOG.md](CHANGELOG.md) — Version history
package/TOOLS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Tools Reference
2
2
 
3
- Complete documentation for all 222 tools in `salesforce-metadata-mcp`. (Highlights below cover the most commonly used tools in depth; see the README's full 222-tool table for every tool name.)
3
+ Complete documentation for all 223 tools in `salesforce-metadata-mcp`. (Highlights below cover the most commonly used tools in depth; see the README's full 223-tool table for every tool name.)
4
4
 
5
5
  ---
6
6
 
@@ -323,4 +323,4 @@ Reads the current field-level security grants for a field across all Profiles an
323
323
 
324
324
  ---
325
325
 
326
- *For the complete list of all 222 tools, see [README.md](README.md).*
326
+ *For the complete list of all 223 tools, see [README.md](README.md).*
package/dist/index.js CHANGED
@@ -3,17 +3,24 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
5
  import { createServer } from "http";
6
+ import { createRequire } from "module";
6
7
  import { registerTools } from "./tools/index.js";
8
+ // Single source of truth for the version. Hardcoding it here drifted from package.json across
9
+ // v2.11.0/v2.11.1 (the server advertised 2.10.0 to clients while the package said 2.11.1), so read
10
+ // it at runtime instead. dist/index.js → ../package.json resolves correctly both in the repo and
11
+ // when installed as node_modules/salesforce-metadata-mcp/dist/index.js.
12
+ const require = createRequire(import.meta.url);
13
+ const { version: VERSION } = require("../package.json");
7
14
  const server = new McpServer({
8
15
  name: "salesforce-metadata-mcp",
9
- version: "2.5.8",
16
+ version: VERSION,
10
17
  });
11
18
  registerTools(server);
12
19
  // ─── Transport: stdio ─────────────────────────────────────────────────────────
13
20
  async function runStdio() {
14
21
  const transport = new StdioServerTransport();
15
22
  await server.connect(transport);
16
- console.error("Salesforce Metadata MCP server v2.5.8 running on stdio");
23
+ console.error(`Salesforce Metadata MCP server v${VERSION} running on stdio`);
17
24
  }
18
25
  // ─── Transport: HTTP ──────────────────────────────────────────────────────────
19
26
  function readBody(req) {
@@ -34,11 +41,18 @@ function readBody(req) {
34
41
  }
35
42
  async function runHTTP() {
36
43
  const port = parseInt(process.env["PORT"] ?? "3000", 10);
44
+ // Defaults to localhost-only: this endpoint has no authentication of its own (any request that
45
+ // reaches /mcp executes tools using whatever Salesforce credentials this process is configured
46
+ // with), and Node's http.Server.listen(port) with no host binds to ALL interfaces by default —
47
+ // found during the 2026-07-31 security audit. Set HOST explicitly (e.g. "0.0.0.0") to opt into
48
+ // wider exposure — e.g. behind a reverse proxy that adds its own auth — rather than exposing this
49
+ // unauthenticated by accident.
50
+ const host = process.env["HOST"] ?? "127.0.0.1";
37
51
  const httpServer = createServer(async (req, res) => {
38
52
  const url = req.url ?? "/";
39
53
  if (url === "/health" && req.method === "GET") {
40
54
  res.writeHead(200, { "Content-Type": "application/json" });
41
- res.end(JSON.stringify({ status: "ok", server: "salesforce-metadata-mcp", version: "2.5.8" }));
55
+ res.end(JSON.stringify({ status: "ok", server: "salesforce-metadata-mcp", version: VERSION }));
42
56
  return;
43
57
  }
44
58
  if (url === "/mcp" && req.method === "POST") {
@@ -63,8 +77,8 @@ async function runHTTP() {
63
77
  res.writeHead(404, { "Content-Type": "application/json" });
64
78
  res.end(JSON.stringify({ error: "Not found" }));
65
79
  });
66
- httpServer.listen(port, () => {
67
- console.error(`Salesforce Metadata MCP server v2.5.8 running on http://localhost:${port}/mcp`);
80
+ httpServer.listen(port, host, () => {
81
+ console.error(`Salesforce Metadata MCP server v${VERSION} running on http://${host}:${port}/mcp`);
68
82
  });
69
83
  }
70
84
  // ─── Entry point ──────────────────────────────────────────────────────────────
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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"}