salesforce-mcp v7.1.0 ships R48 zero-limitation operator-intent surface (P1-P6) but two defects make
What
salesforce-mcp v7.1.0 ships R48 zero-limitation operator-intent surface (P1-P6) but two defects make the Profile/PermissionSet WRITE path non-functional. EA session resuming the System Administrator Clone profile tightening (production Id 00efu00000D6zHSAAZ, 19-permission disable) hit both defects in one session and halted per tool-ambiguity protocol — both orgs untouched, no metadata changes deployed.
Defect 1 (UX gap, breaks R48) — sf_disable_profile_permissions (P5) fail-closes the entire batch when ANY name is bucketed retired by P2 pre-flight. Should auto-skip retired names and proceed with valid subset. Operator hits 2 round-trips minimum.
Defect 2 (HARD bug, blocks all writes) — sf_get_profile_full_metadata (P1, called internally by P5) looks for retrieved Profile at zip path unpackaged/profiles/{name}.profile but modern simple-salesforce mdapi.retrieve() returns it at profiles/{name}.profile (no unpackaged/ prefix). Same response’s zip_namelist proves the profile WAS retrieved successfully — parser just looks at wrong path. Misleading “check fullname spelling” insight makes it harder to spot. P6 readers (sf_get_permission_set_full_metadata, sf_get_muting_permission_set_full_metadata) almost certainly carry the same bug — added together in Bible v19.1.10 Check 15.
Suspected root cause for Defect 2: Modern simple-salesforce mdapi.retrieve() (Tooling/REST path) returns zip entries WITHOUT unpackaged/ prefix; legacy SOAP MDAPI returned WITH prefix. P1/P6 readers likely tested against SOAP-shape fixtures or coded against SOAP-era documentation.
Single-line candidate fix (tools/profile_complete/operations.py):
candidates = [f"profiles/{name}.profile", f"unpackaged/profiles/{name}.profile"]
matched = next((c for c in candidates if c in zip_namelist), None)Apply to all three readers (P1 + both P6).
Why Phase 9 census missed it: Cutover census validated symmetric-reader PRESENCE (method exists + returns structured response) but NOT real-zip-roundtrip CORRECTNESS. Add a real-zip-roundtrip check to Phase 9: assert P1 returns parsed Profile shape (not error) for at least one known-existing profile per env.
What v7.1.0 got right (don’t regress these): health_check reports v7.1.0/Bible-v19.1.10/684 tools/both orgs healthy; ToolSearch resolves all four P1-P6 tools cleanly; P2 correctly buckets retired names with retired_in_api + retirement_reason metadata; mdapi.retrieve() upstream itself succeeds.
Repro fixture: sf_get_profile_full_metadata(profile_name="System Administrator Clone", org_alias="fullcopy") — expect status=success with full Profile shape; current actual is status=error with insights “Expected entry ‘unpackaged/profiles/…’ not found in zip” while data.zip_namelist=[“profiles/System Administrator Clone.profile”,“package.xml”].
Reference docs:
- Full bug post-mortem:
/root/aj-ea/outputs/documents/mcp-tool-limitation-salesforce-v7.1.0-p1-zip-prefix-bug-06-may-2026.md - Vault note:
knowledge/critical/salesforce-mcp-v710-p1p6-zip-prefix-bug-blocks-operator-inte.md - Decisions log entry:
/root/aj-ea/decisions/log.md(2026-05-06 entry)
Pattern context: This is the same workflow that resolved the v7.0.2 production-deploy testLevel bug — EA flags a hard bug discovered in operator session, dev patches, EA resumes on the next cutover. v7.0.2 → v7.1.0 cycle worked clean; expect v7.1.1 to follow the same path.
Why
Blocks AJ’s complete-capability invariant (Bible R26 / R48). Profile/PermissionSet WRITES via the operator-intent surface are non-functional in v7.1.0 — every Profile-tightening, every Profile-loosening, every PermissionSet-permission-toggle operation is dead in the cutover build. The 19-permission System Administrator Clone tightening is the canonical test case, but the bug affects every future Profile/PermissionSet write workflow on this MCP. EA cannot proceed without v7.1.1.
Action Required
- Patch P1 + both P6 readers in
tools/profile_complete/operations.pyto try both zip-path candidates (no-prefix first since modern API path is dominant; preserve unpackaged/ fallback for backward compat). - Add Defect 1 policy decision — RECOMMENDED Option C: opt-in
skip_retired_names: bool = Falseparam on P5 enable/disable variants. Default preserves current strict fail-closed behavior; opt-in honors R48 single-round-trip promise and gives operators a choice. - Add real-zip-roundtrip regression test — fixture zip with
profiles/X.profile(no prefix), assert P1 parses; second fixture withunpackaged/profiles/X.profile, assert P1 still parses (backward compat). - Update Phase 9 census check to include real-zip-roundtrip (not just presence-of-method).
- Cutover v7.1.1 with both fixes via the same 7-surface cascade discipline used for v7.1.0.
- Notify aj-ea — EA resumes System Administrator Clone tightening with same call shape (drop ManageMobileConfigurations OR pass skip_retired_names=True if Option C ships).
Estimated effort: <2h (single-line zip-path fix + opt-in param + regression test + cutover). Cleaner than v7.0.2 → v7.1.0 cycle since both defects are tightly localized.