sandbox-seed

sandbox-seed

Salesforce sandbox seeding, built for AI agents. SOQL-driven org-to-org record copy with automatic dependency-graph walking, cross-org FK remapping, and a hard AI-never-sees-your-data boundary.

Category
访问服务器

README

sandbox-seed

Salesforce sandbox seeding, built for AI agents. SOQL-driven org-to-org record copy with automatic dependency-graph walking, cross-org FK remapping, and a hard AI-never-sees-your-data boundary.

npm license node


Why this exists

If you've ever tried to seed a Salesforce sandbox from production through an AI agent, you already know the two problems:

  1. Record IDs don't match across orgs. Any "just query source, bulk insert target" recipe — whether you wrote it yourself or you're driving SFDMU or sf data import tree through tool calls — breaks on FK remapping, circular references like Account↔Contact, and master-detail parent ordering.
  2. Agents see everything they touch. Running SOQL through a generic MCP or a shell wrapper streams rows straight into your prompt context. Real customer data, real account balances, real PII, all getting embedded into an LLM.

sandbox-seed is designed around both:

  • A proper dependency-graph walker with two-phase inserts for every strongly-connected component, cross-org ID remapping, and a mandatory dry-run gate before any write.
  • A hard boundary in the tool surface itself: record data never leaves disk. The AI sees counts, schemas, file paths, and plan hashes. It does not see the rows.

If you're building AI workflows that touch Salesforce, the AI-boundary contract is the property you actually care about, and it's non-negotiable in this tool.


30-second setup (MCP, the primary surface)

Add this to your MCP host config (~/.cursor/mcp.json, ~/Library/Application Support/Claude/claude_desktop_config.json, or your project's .mcp.json):

{
  "mcpServers": {
    "sandbox-seed": {
      "command": "npx",
      "args": ["-y", "-p", "sandbox-seed", "sandbox-seed-mcp"]
    }
  }
}

Restart your host. Then try:

"Seed my dev-full sandbox with Opportunities that closed this quarter over $50k, from the prod org."

The model will call the seed tool and walk you through the five-step flow (analyze → select → dry-run → confirm → run). No record data ever appears in chat.

What to expect on first run:

  • analyze on a standard object (Case, Opportunity) against a managed-package-heavy org: ~5–20 seconds cold, ~1–3 seconds warm. Describes fan out in parallel (6 at a time, with backoff on throttling) across the dependency graph (~20–40 describes for Case), and cache at .sandbox-seeding/cache/ with a 24h TTL.
  • extract rate depends on record count × relationship breadth; small seeds (<500 rows) finish in seconds.
  • Sessions live at ~/.sandbox-seed/sessions/ and are garbage-collected after 7 days. The cross-run project id-map at ~/.sandbox-seed/id-maps/ is persistent.

For deeper MCP config, tool reference, and host-specific tips, see docs/MCP.md.


Install (CLI)

npm i -g sandbox-seed

Requires Node.js ≥ 20.

The CLI ships inspect (read-only schema/dependency-graph exploration) and a first-class seed command — the same engine and safety gates as the MCP tool, usable from a terminal or CI:

sandbox-seed inspect --object Case
sandbox-seed inspect --object Opportunity --include-counts --format mermaid

# Full seed flow: dry run → interactive confirm → run
sandbox-seed seed --source-org prod --target-org dev-full \
  --object Case --where "IsClosed = false AND CreatedDate = THIS_YEAR" --sample-size 100

# Stop at the dry-run report; execute later after review
sandbox-seed seed ... --mask --dry-run-only
sandbox-seed seed resume <sessionId>

Full CLI reference: docs/CLI.md.


The AI-boundary contract

The single most important property of this tool.

  1. SOQL results are written to an on-disk session store the tool owns. They do not flow back through the MCP response envelope. No tool call ever returns a row.
  2. Every tool response is metadata only: object names, row counts, relationship graphs, file paths, plan hashes.
  3. WHERE clauses must be SOQL typed by a human. The tool refuses to invent predicates from natural language ("the biggest", "recent ones"). Ambiguity surfaces a prompt asking for a real SOQL predicate.
  4. Targets must be sandboxes (Organization.IsSandbox = true). Writes to production orgs are rejected at the tool layer.

The tests under tests/mcp/ encode these rules — start there if you're auditing the boundary. Full writeup in docs/AI_BOUNDARY.md.


Walkthrough — copy the prompts from a real session

The fastest way to learn this tool is to read a real chat transcript and copy the prompts into your own agent. docs/WALKTHROUGH.md contains four full verbatim sessions covering:

  • A happy-path Case seed (306/308 inserts, 2 target-validation-rule failures)
  • A clean 1,271-row run with zero errors
  • Three common first-time mistakes the tool catches (full SELECT strings, limit too low, WHERE matches zero)
  • How to ask the agent to describe the tool before you call it

One prompt shape you can paste straight into Cursor, Claude Desktop, or any MCP-aware host:

action: "start"
sourceOrg: "<your source alias>"
targetOrg: "<your target sandbox alias>"
object: "Case"
whereClause: "IsClosed = false AND CreatedDate = THIS_YEAR"
sampleSize: 100
disableValidationRulesOnRun: true

USE MCP: sandbox-seed

Then for each subsequent step, paste back the JSON the agent suggests:

{ "action": "analyze", "sessionId": "<session-id-from-start>" }
{
  "action": "select",
  "sessionId": "<session-id>",
  "includeOptionalParents": ["Account", "Contact"],
  "includeOptionalChildren": ["CaseComment", "Task"]
}
{ "action": "dry_run", "sessionId": "<session-id>" }
{ "action": "run", "sessionId": "<session-id>", "confirm": true }

Prerequisites:

  1. Salesforce CLI installed (brew install sfdx-cli or npm i -g @salesforce/cli) and both orgs logged in with sf org login web --alias <name>.
  2. sandbox-seed registered in your MCP host config (see the 30-second setup block above).

Troubleshooting (from real sessions)

  • "WHERE clause matched 0 records on <object>" — your SOQL matches nothing. Test it in Workbench or sf data query first, or relax the filter.
  • "WHERE clause matched N records, exceeding limit M"limit is a safety cap, not a SOQL LIMIT. Either raise limit, tighten the predicate, or use sampleSize: N (deterministic "first N by ORDER BY Id").
  • "sandbox_seed_seed does not take a full SELECT string"whereClause is the predicate only. Drop the SELECT … FROM … LIMIT … parts.
  • FIELD_CUSTOM_VALIDATION_EXCEPTION in execute.log — target-org validation rules rejected some rows. Pass disableValidationRulesOnRun: true to start to snapshot + deactivate them around the insert, then restore.
  • DUPLICATE_VALUE on re-run — you've already seeded those rows. Objects with an external-id field auto-route through UPSERT on re-runs; otherwise run against a clean sandbox.

What's shipped in 0.2.x

  • First-class CLI seed command (new in 0.2.8) — sandbox-seed seed / seed resume / seed recover drive the same engine and safety gates as the MCP tool from a terminal or CI (--dry-run-only, --yes, --json).
  • Parallel describe walk (new in 0.2.8) — cold-cache analyze/inspect fan describes out 6 at a time; full-graph analyze on managed-package-heavy orgs dropped from 30–90s to ~5–20s.
  • Masking production-blessed (0.2.8) — the real-org acceptance gate passed G1–G6 on three consecutive runs; adds a digit-shaped postal-code preset, masked values cap to the shorter of source/target field length, and the dry-run report warns when a masked field is shorter on the target.
  • Sticky upsert keys (new in 0.2.8) — the external-id each object UPSERTs on persists per (source, target) pair and is reused (re-validated) by later sessions, so re-seeds keep matching the rows earlier runs created.
  • MCP seed tool — five-step SF → SF copy flow (analyze → select → dry-run → confirm → run) with cross-org FK remapping, two-phase cycle inserts, validation-rule snapshot/restore, and the AI-boundary contract.
  • Child + 1 user-selected lookups (new in 0.2.0) — at start, name specific reference fields on direct children of the root; the walker follows each exactly one hop to pull that target object into scope. Multi-path objects (reachable via direct FK and child-lookup) union their ID sets rather than picking one path.
  • Semi-joins in whereClause now supported (fixed in 0.2.0) — root predicates like Id IN (SELECT … FROM …) work end-to-end. Root IDs are materialized once and spliced into downstream scopes as literal Id IN ('…','…'), sidestepping SOQL's one-level semi-join limit.
  • CLI inspect command — read-only schema and dependency-graph exploration (tree / mermaid / dot / json).
  • Salesforce CLI auth integration (reads ~/.sf/).
  • Deterministic field masking (opt-in) — pass mask: true (and/or maskFields) at start to replace PII with deterministic, format-preserving fakes before insert (emails stay email-shaped, phones phone-shaped, …). Keyed by a per-(source, target) salt, so the same value masks identically everywhere and across re-runs — value joins and external-id UPSERT survive. Detected sensitive fields mask by default; the dry-run report lists exactly what will mask so you can add anything auto-detection missed. Reference fields are never masked (the id-map owns FKs). See docs/AI_BOUNDARY.md.

Not yet shipped: synthetic data generation, CSV import, multi-target fan-out. These are roadmap.

Scope & limitations to know about in 0.2.x

  • One session = one id-map. The source→target ID map is session-scoped (written to the session dir). Seeds cannot yet be composed across runs — if you seed Accounts in one session and then seed Applications in a second session, the second session does not recognize the Accounts from the first. Required lookups are skipped; nillable lookups are inserted as null. Workaround: seed everything you need in a single session by rooting the seed on the highest shared object (e.g. Account), so the id-map is populated in dependency order within one run. A project-level id-map that composes across runs is on the roadmap.
  • Child-lookup walking is one hop only, user-selected. 0.2.0 walks user-named reference fields on direct children exactly one hop further. No transitive expansion, no auto-discovery. If you need a two-hop chain (child → parent → grandparent), root the seed on the child instead so its parents are walked transitively.
  • Ownership and queue/group lookups default to the target user. References to User, Group, or Queue (most commonly OwnerId, but also fields like AssignedToId or QueueId) are not walked into the dependency graph, because those records are org-global, often privileged, and rarely safe to materialize cross-org. At run time these fields are left null on insert, which causes Salesforce to default them to the target-org user performing the seed. The dry-run report surfaces a "Defaulted owner/user/group references" count per object so you can see how many rows this affects before running. If you need to preserve specific owners, set them manually in the target after seeding, or pre-populate the id-map with explicit User mappings.

Authentication

  • Reads ~/.sf/ auth files if you already use the Salesforce CLI (sf). Zero config.
  • Falls back to an OAuth device flow if you don't have sf installed.
  • Target org must be a sandbox. Production targets are refused.

More: docs/AUTH.md.


Status

Pre-release (0.2.8). APIs and flags may change before 1.0. Use in sandboxes only — never point this at a production org as the target (the tool refuses, but don't test the refusal with real money).

Roadmap: [BACKLOG in project notes, soon to be moved into GitHub Issues].


Documentation


Contributing

Issues and PRs welcome. See CONTRIBUTING.md for dev setup.

Security issues: please do not file public issues. Email pranav.nagrecha11@gmail.com.


License

Apache-2.0. © 2026 Pranav Nagrecha.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选