Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Sfgraph

БесплатноНе проверен

A local, privacy-first knowledge graph for Salesforce orgs. It live-syncs your org to a SQLite + vector index on your machine and exposes 26 MCP tools to Cursor

GitHubEmbed

Описание

A local, privacy-first knowledge graph for Salesforce orgs. It live-syncs your org to a SQLite + vector index on your machine and exposes 26 MCP tools to Cursor, Claude Code/Desktop, and VS Code, so the AI you already use can reason about Apex, LWC, Flow, Vlocity, OmniStudio, security, and integrations without your code or schema ever leaving your laptop.

README

npm license node

A local, privacy-first knowledge graph for Salesforce orgs. sfgraph live-syncs your org to a SQLite + vector index on your machine and exposes 28 MCP tools to Cursor, Claude Code/Desktop, and VS Code, so the AI you already use can reason about Apex, LWC, Flow, Vlocity, OmniStudio, security, and integrations without your code or schema ever leaving your laptop.

┌──────────────────────────────────────────────────────────────────────┐
│  Cursor / Claude / VS Code   ←──── MCP stdio ────→   sfgraph         │
│                                                                      │
│              read-only Salesforce APIs    ──→    your org            │
│              local SQLite + sqlite-vec    ←──    OS data dir         │
└──────────────────────────────────────────────────────────────────────┘

Privacy in one line. Nothing leaves your machine — graph, vectors, logs all live under the platform's user-data directory (~/Library/Application Support/sfgraph/ on macOS, ~/.local/share/sfgraph/ on Linux, %APPDATA%\sfgraph\ on Windows; see docs/DATA_LOCATIONS.md). Salesforce auth is delegated to the sf CLI (token stays in ~/.sfdx/). Every connection is wrapped in a read-only Proxy. Full threat model: docs/PRIVACY.md.


Install

1. Prerequisites

How
Node.js ≥ 20 nodejs.org or brew install node
sf CLI npm install -g @salesforce/cli
At least one sf login sf org login web --alias my-org && sf config set target-org=my-org

Verify:

node --version          # v20+ (v22 LTS recommended)
sf org list             # at least one org marked as default

2. Install sfgraph

npm install -g @ryanstark24/sfgraph

Or run on-demand via npx @ryanstark24/sfgraph <command> without installing.

After install, sfgraph is on your PATH.

3. Wire it into your editor

sfgraph install

Idempotent. Copies 20 skill playbooks into ~/.claude/skills/ + ~/.cursor/rules/ and adds a sfgraph entry to your editor's MCP config. Existing MCP entries are preserved. Use --target=claude|cursor|vscode to wire only one, or --dry-run to preview. Start with sf-graph-router — it routes intent to the right skill and enforces grounding answers in the org graph before generating Salesforce code.

Using a different IDE or LLM client?

sfgraph install writes config for Claude / Cursor / VS Code automatically. For any other MCP-compatible client (Windsurf, Zed, Continue, Cline, an OpenAI- or Gemini-based agent with MCP support, your own custom host, etc.), add this entry to the client's MCP config file manually:

{
  "mcpServers": {
    "sfgraph": {
      "command": "npx",
      "args": ["-y", "@ryanstark24/sfgraph", "mcp"]
    }
  }
}

On Windows, use "npx.cmd" instead of "npx".

Pinning the Node binary. Some hosts (sandboxed Electron apps, IDE extensions) ship with a bundled Node whose ABI differs from your shell's. If that bundled Node lacks a matching better-sqlite3 prebuilt, the MCP child fails to load. Pin to your shell's Node:

{
  "mcpServers": {
    "sfgraph": {
      "command": "/Users/you/.nvm/versions/node/v22.21.1/bin/node",
      "args": ["/usr/local/bin/sfgraph", "mcp"]
    }
  }
}

Use which node and which sfgraph to fill in the paths. Same effect as sfgraph install --local --pin-node "$(which node)" but written by hand into a client we don't have a built-in target for.

Where each known client keeps its MCP config:

Client Config path
Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) · %APPDATA%\Claude\claude_desktop_config.json (Win)
Claude Code (CLI) ~/.claude.json (user) or .mcp.json (project)
Cursor ~/.cursor/mcp.json
VS Code ~/Library/Application Support/Code/User/mcp.json (macOS) · %APPDATA%\Code\User\mcp.json (Win)
Windsurf ~/.codeium/windsurf/mcp_config.json
Zed ~/.config/zed/settings.json (under context_servers)
Continue (VS Code) ~/.continue/config.json (under mcpServers)
Cline (VS Code) ~/.cline/cline_mcp_settings.json

After editing the file, fully restart the client so it re-reads the MCP server list. Then ask the agent something like "list orgs from sfgraph" to confirm the tools are visible.

The skill playbooks (sf-impact-from-diff, sf-security-audit, etc.) are Claude/Cursor-specific. On other clients, the agent still has direct access to all 28 MCP tools — it just routes by tool name instead of by skill trigger.

4. Verify the install

sfgraph doctor

End-to-end self-check: Node ABI, native bindings, code-signing (macOS), data dir, org DBs, sf CLI, IDE MCP configs. Each failed check prints a copy-paste fix.

If you see a bindings file not found / ABI mismatch (common after a Node upgrade or on a brand-new Node release with no prebuilts yet):

sfgraph rebuild-bindings

First ingest

The first sync of an org takes 2–6 minutes on a typical 50K-node sandbox. Subsequent syncs on Source-Tracking-enabled orgs are incremental (<30 s).

# Default org from `sf config target-org`
sfgraph ingest

# Or pick an org explicitly
sfgraph ingest --org my-prod

The graph lands in <data-dir>/<orgId>.sqlite (macOS: ~/Library/Application Support/sfgraph/, Linux: ~/.local/share/sfgraph/, Windows: %APPDATA%\sfgraph\). From this point every MCP tool reads only from that file — no network calls.

Keep it fresh. Re-run sfgraph ingest whenever you want current data. Skills warn the agent when the graph is older than 7 days.

For tuning, large-org options, multi-org ingest, and rebuild flags, see docs/CLI.md.


Use it from your editor

Restart your IDE so it picks up the new MCP entry. Then in any project ask the agent:

  • "What does this PR break?"
  • "Who reads Account.Status__c?"
  • "What changed in prod since last week?"
  • "Show me how accountTile flows from UI to DB."

The agent routes to the right tool automatically via the installed skill playbooks. A short worked example:

User: I'm about to merge this PR. Anything I should worry about?

Agent: *invokes sf-impact-from-diff*
       → impact_from_git_diff(diff="…", depth=3)
       → test_gap_intelligence_from_git_diff(diff="…")

       Your diff touches 3 nodes. 9 dependents at 3 hops:
         • 4 covered by tests (green)
         • 5 at-risk (no IS_TEST_FOR):
             - LWC:opportunityTile
             - ApexMethod:BillingSvc.run(2)
             - ApexMethod:BillingSvc.dryRun(0)
             - Flow:Order_Status_Update
             - LWC:invoiceTile

       Recommend adding test coverage for BillingSvc.run(2) before merging.

More worked examples: docs/SAMPLES.md.


Optional: web visualiser

sfgraph serve          # http://localhost:7777

A 3D force-graph explorer for the ingested org. Loopback-only by default. See docs/WEB.md.


Reliability

Wedge isolation (Phase 1.5)

A slow or hung source no longer blocks neighbors. When the per-source watchdog (90s first-yield, 5min inactivity) fires, the source's slot is released and the next queued source runs. The wedge runs to completion in the background; late records are drained with attributes.lateYield: true.

You will see warnings of the form wedge:<source>:<reason>:... in the ingest run summary — these are now informational (the run continues), not fatal.

Socket-leak caveat (honest disclosure). The underlying HTTP request to Salesforce is NOT cancelled (jsforce 3.10.15 does not expose AbortController). Wedged sockets are reaped by Node's idle-timeout (~10min). Worst-case memory: 4 wedges × ~1MB ≈ 4MB per ingest, garbage-collected at process exit. The cap is SFGRAPH_MAX_BACKGROUND_WEDGES (default 4).

Detect-deletions drop-ratio guard (Phase 1.5)

When run with --detect-deletions --rebuild, sfgraph refuses to wipe a label whose drop ratio exceeds SFGRAPH_DETECT_DELETIONS_MAX_DROP_RATIO (default 0.30). A wedge-induced empty stream emits a wedge:detect-deletions:refuse:label=<L>:reason=empty-stream warning instead of silently destroying the label. Refused labels keep their previous last_seen_at so the staleness clock keeps ticking — staleness reports will still surface them.


Diagnostics

When ingest reports skips you don't understand, use the diagnose subcommand:

sfgraph diagnose <orgId>

diagnose forces source / Tooling / Metadata / Data pool concurrency to 1 and writes a structured JSON report capturing per-source timing, wedge events, capability probes, and detect-deletions refusals. By default it writes to a temporary graph DB so your main org graph is untouched.

Note: wall-clock is NOT comparable to a production run — diagnose names wedges, it does not predict prod throughput.

Default report path (platform-aware, under the same data dir as the graph):

Platform Path
macOS ~/Library/Application Support/sfgraph/diagnostics/<orgId>-<ISO-timestamp>.json
Linux ~/.local/share/sfgraph/diagnostics/<orgId>-<ISO-timestamp>.json
Windows %APPDATA%\sfgraph\diagnostics\<orgId>-<ISO-timestamp>.json

Flags:

Flag Default Effect
--output <path> (auto) Override the default report path.
--max-duration <seconds> 600 Overall diagnose timeout (10 min).
--verbose false Stream per-source timing to stdout in addition to the JSON report.
--keep-graph false Write to the real org graph DB instead of a temp DB.

MCP staleness signal

Every MCP tool response carries a _meta.staleness block:

{
  generation: number,            // monotonic per-org sync counter
  in_progress: boolean,          // true if an ingest is currently rewriting the graph
  started_at: string | null,     // ISO timestamp of the in-progress ingest
  last_sync_at: string | null    // ISO timestamp of the most recent completed sync
}

Reader-side contract. MCP clients should check staleness.in_progress === true to warn users that the graph is being rewritten and results may reflect partial state. Tools that don't carry an orgId argument (e.g. ping, list_orgs) omit the block instead of guessing.


Environment variables

Authoritative inventory — every SFGRAPH_* env var read at runtime, sorted alphabetically. Verified via grep -rn "process.env.SFGRAPH_" packages/ --include="*.ts".

Name Type Default Purpose Since
SFGRAPH_ALLOW_ANY_DB bool (1) unset Bypass the "graph DB must live under data dir" safety check. 1.0
SFGRAPH_APEX_PARSER string regex Apex class parser strategy (regex is the default; other values reserved). 1.0
SFGRAPH_AUTO_RETRY_THRESHOLD int 10 Skip-count threshold above which ingest auto-retries the wedged sources. 1.0
SFGRAPH_BISECT_MAX_DEPTH int 6 Tooling SOQL adaptive bisection depth cap. 1.0
SFGRAPH_CACHE_DIR path platform default Override OS cache directory. 1.0
SFGRAPH_CONFIG_DIR path platform default Override OS config directory. 1.0
SFGRAPH_DATA_DIR path platform default Override OS data directory (where <orgId>.sqlite lives). 1.0
SFGRAPH_DATA_POOL int varies Data API pool concurrency. 1.0
SFGRAPH_DEBUG_INGEST bool (1) unset Verbose ingest logging (per-source counters, dispatch table, etc.). 1.0
SFGRAPH_DEBUG_POOLS bool (1) unset Print pool-counter snapshots during ingest. 1.0
SFGRAPH_DETECT_DELETIONS_MAX_DROP_RATIO float 0.30 Per-label drop-ratio threshold above which --detect-deletions sweep refuses to act. 1.5
SFGRAPH_EMBED_MODEL_DIM int model default Embedding model dimensionality override. 1.0
SFGRAPH_EMBED_MODEL_ID string model default Embedding model identifier override. 1.0
SFGRAPH_EMBED_MODEL_PATH path (auto) Local path to a custom embedding model file. 1.0
SFGRAPH_INCLUDE_ALL_GENERIC bool (1) unset Disable GENERIC_TYPE_WHITELIST filter — route every discovered metadata type through the generic extractor. 1.0
SFGRAPH_INCLUDE_ALL_SOBJECTS bool (1) unset Skip the EntityDefinition.IsCustomizable filter and include every queryable SObject. 1.0
SFGRAPH_INCLUDE_MANAGED bool (1) unset Include managed-namespace components globally (Apex body, generic metadata, LWC source). 1.0
SFGRAPH_INCLUDE_MANAGED_LWC bool (1) unset LWC-only override for managed-namespace inclusion (independent of the global flag). 1.0
SFGRAPH_INCLUDE_SYSTEM_SOBJECTS bool (1) unset Include platform telemetry SObjects (ApexLog, EventLogFile, etc.). 1.0
SFGRAPH_LATE_DRAIN_BUDGET_MS int (ms) (impl default) Per-wedge late-yield drain budget — how long the background runner gets to drain late records before being abandoned. 1.5
SFGRAPH_LOG_DIR path platform default Override OS log directory. 1.0
SFGRAPH_MAX_BACKGROUND_WEDGES int 4 Cap on simultaneous background wedges per ingest. 1.5
SFGRAPH_METADATA_POOL int varies Metadata API pool concurrency. 1.0
SFGRAPH_METADATA_READ_CHUNK_SIZE int 10 metadata.read composite batch size. 1.0
SFGRAPH_NO_AUTO_RETRY bool (1) unset Disable automatic retry on watchdog wedge / skip cascade. 1.0
SFGRAPH_NO_LIVENESS_PROBE bool (1) unset Skip the pre-ingest liveness probe. 1.0
SFGRAPH_SEQUENTIAL_SOURCES bool (1) unset Force serial source execution (debug aid; bypasses the sliding-window merger). 1.0
SFGRAPH_SKIP_LWC csv unset Skip specific LWC bundle DeveloperNames (also accepts 1 to skip the source entirely). 1.0
SFGRAPH_SKIP_SOBJECT csv unset Skip specific SObjects by QualifiedApiName (escape hatch for describe()-crashing tables). 1.0
SFGRAPH_SKIP_THRESHOLD int (impl default) Skip-count threshold for ingest-level retry/abort behavior. 1.0
SFGRAPH_SOURCE_CONCURRENCY int 12 Concurrency of the sliding-window source merger in bulk-retrieve.ts. 1.0
SFGRAPH_TEMP_DIR path platform default Override OS temp directory. 1.0
SFGRAPH_TOOLING_POOL int 5 Tooling API pool concurrency. 1.0
SFGRAPH_TRAVERSAL_NODE_CAP int (impl default) Cap on nodes visited by dependents / dependencies traversal in the analysis layer. 1.0
SFGRAPH_WATCHDOG_FIRST_YIELD_MS int (ms) 90000 Per-source first-yield watchdog timeout. 1.5
SFGRAPH_WATCHDOG_INACTIVITY_MS int (ms) 300000 Per-source inactivity watchdog timeout (5 min). 1.5

Honest disclosures — known limitations

sfgraph aims to be honest about gaps. Read this section before relying on it for security or compliance audits.

  • Security model gaps. Profile / PermissionSet / SharingRules are ingested as first-class nodes with GRANTS_* edges. However, PermissionSetGroup, MutingPermissionSet, ProfileSessionSetting, ProfilePasswordPolicy are ingested as opaque generic nodes WITHOUT GRANTS_* or DENIES_* edges — they exist as nodes but their security semantics are not modeled. Audits that rely on these edges will not surface findings for those types until a future Security phase.
  • Security analysis caps. The analysis layer caps results at 5000 per label (SECURITY_PER_LABEL_CAP). On orgs with more than 5k Profiles or PermissionSets, analysis is truncated with a truncated: true flag — but graph storage is complete.
  • Generic-type whitelist. sfgraph dispatches ~80 of the ~327 metadata types Salesforce returns from describeMetadata() to the parsed extractor path. The rest are recorded only as opaque generic nodes when matched by the whitelist; everything else is filtered out. Set SFGRAPH_INCLUDE_ALL_GENERIC=1 to override (every discovered type runs through the generic extractor — longer ingest, more opaque nodes). The full type list is documented in docs/COVERAGE.md.
  • LWC empty-bundle behavior change (Phase 1.5). Prior versions yielded a stub RawMember with files: {} on per-bundle resource-fetch failure, creating empty bundle nodes in the graph. Phase 1.5 emits a wedge:lwc:bundleFetchFailed:... warning and no record. Users who upgrade may see previously-recorded empty LWC bundles disappear from their graph on the next re-ingest. This is correct.
  • Socket leak on wedged HTTP requests. When the per-source watchdog fires, sfgraph releases the slot but the underlying jsforce HTTP request is NOT cancelled (no AbortController exposed by jsforce 3.10.15). The socket is reaped by Node's idle-timeout (~10min). Worst case: SFGRAPH_MAX_BACKGROUND_WEDGES (default 4) × ~1MB ≈ 4MB transient memory per ingest, GC'd at process exit. Tracked as future hardening; an upstream jsforce PR or fork is needed for true in-flight HTTP cancellation.

Coverage

sfgraph mixes deep parsing (Apex, LWC, Flow, Object, Profile/PermissionSet, NamedCredential, Vlocity, OmniStudio) with opaque-node fallback for the long tail of metadata types. Coverage is dynamic, not hardcoded — at ingest start, conn.metadata.describe(apiVersion) asks the org for its full supported type list, which automatically includes types added by managed packages or future Salesforce releases. Each type is routed to a named extractor, the generic opaque-node path, or filtered out.

See docs/COVERAGE.md for the full status matrix: every type, the edges it emits, known limitations, and the source file that implements it.


Documentation

docs/CLI.md Full CLI reference — every command, every flag
docs/TOOLS.md The 28 MCP tools — schemas, examples, algorithms
docs/SKILLS.md The 20 skill playbooks installed into your editor
docs/SAMPLES.md Worked agent-conversation examples
docs/COVERAGE.md Metadata coverage matrix and SObject classification logic
docs/WEB.md Local web visualiser
docs/TROUBLESHOOTING.md Diagnose and fix common install / ingest issues
docs/DESIGN.md Architecture decisions, analysis pipeline, TS rewrite rationale
docs/ARCHITECTURE.md Storage model + ingestion pipeline deep-dive
docs/PRIVACY.md Read-only enforcement, sanitizer, telemetry threat model
docs/DATA_LOCATIONS.md What lives where on your machine
docs/DEVELOPMENT.md Build, test, contribute
CHANGELOG.md Per-release notes

License

MIT

from github.com/ryanStark24/sfgraph

Установка Sfgraph

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/ryanStark24/sfgraph

FAQ

Sfgraph MCP бесплатный?

Да, Sfgraph MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Sfgraph?

Нет, Sfgraph работает без API-ключей и переменных окружения.

Sfgraph — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Sfgraph в Claude Desktop, Claude Code или Cursor?

Открой Sfgraph на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Sfgraph with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории data