sf-intelligence
MCP serverDocs & knowledgeYour AI can answer questions about one Salesforce org's metadata, how its pieces depend on each other, and what a change might affect. It draws on an offline, read-only knowledge base, so it works without a live connection and cannot modify the org. It covers a single org at a time.
Unavailable. This server has no hosted endpoint yet, so Ahel can't serve it.
Add to setup to save this item as a reference. Ahel cannot run it, and signing in will not install it.
What your AI can do with it
- Look up metadata from a single Salesforce org
- Trace dependencies between components in that org
- Assess the impact of a change before it is made
- Answer questions about the org while offline
- Keep the org untouched with read-only access
Getting started
- Save this item in Your setup as a reference.
- Read the source or reference documentation for its setup requirements. Saving it here does not connect it to your AI.
- Check this page for availability before trying to install it through Ahel.
From the project's README
As published by pranavnagrecha/salesforce-intelligence in README.md.
sf-intelligence
A grounded, fail-closed backend for AI assistants working in one Salesforce org. Your AI host (Claude, or any MCP client) asks it questions in plain language; it answers from the org's real metadata — never a guess — and labels every claim with how much to lean on it.
sf-intelligence is an offline, read-only, MCP-first knowledge base for a
single Salesforce org. You run one retrieve (sf project retrieve); it builds a
local Markdown vault and a DuckDB dependency graph. From then on every answer is
served locally by default — offline-first, no network egress for vault
answers. An opt-in live read-only plane (sfi.live_*) can answer record
counts and samples when enabled. Private by design. MIT + Commons Clause.
It is not a standalone chatbot — it has no chat surface. It is the evidence layer an AI host consumes: a router that advises (ranked tool candidates plus explicit disclosures), a host LLM that decides (picks and runs the tools), and an engine that grounds every answer in the vault and fails closed — refusing, disclosing a gap, or asking a clarifying question — when it cannot.
Ask it like a person
You don't need to know the exact API name of anything. The front door is a typo-tolerant resolver that turns messy phrasing into the right component — and when it isn't sure, it asks you a clarifying question instead of guessing:
You: where's the emale field?
It: I found several matches for "email" — which did you mean? ·
Email__conAccount·Email__conContact·Alternate_Email__conLead
You: what about the paymnet object?
It:
Payment__c— one confident match.
You: is there a "warranty fee" field?
It: Nothing matched that confidently. Your vault was last refreshed on 2026-05-20 — want to pull fresh metadata from the org (
/sfi-refresh) in case it's new, or rephrase?
That is the headline behavior for resolution and routing: they never
silently commit to a guess. Resolution is always heuristic and labeled as
such. When several components are plausible it hands you a clarifying question;
when nothing matches it offers to refresh from the org or stop. A high match
score is string similarity, not proof. Source grep tools (sfi.search_apex_source,
sfi.search_flow_metadata) walk the vaulted source/ tree from your last
refresh — run /sfi-refresh before trusting an empty grep result.
Advisory routing — the funnel advises, the host decides
Under the hood a semantic router (sfi.route_question) reads each question
and returns a meaning-ranked shortlist (toolCandidates) of the sfi.*
tools that can answer it — so your AI host picks and runs them without you ever
typing a tool name. It runs fully offline (a small TF-IDF model over the
tool catalog — no network, no embeddings service) and it advises rather than
dictates: the candidates are the primary output; the deterministic route
that rides along is a non-authoritative hint. The host LLM decides which tools
to run, in what order.
Confidence semantics are explicit. When no deterministic intent matches but the
semantic funnel's top candidate scores above a fixed floor, the router returns a
funnel-advisory route — the top funnel tools, confidence low by
construction, reason flagged FUNNEL-DERIVED — an advisory pick for the host
to verify (resolve the named component, then ground), never a command. Each
candidate row also carries cosine, its raw semantic score, so a host can tell
real semantic support from a regex-rule assertion.
The router also tags each question with the plane that answers it —
the offline vault (metadata, dependencies, permissions), the live org
(counts, samples, limits, inactive users — read-only, opt-in), or a hybrid of
both (e.g. "is this field actually populated?"). Every answer is stamped with
its provenance (offline_snapshot, live_org, or hybrid) and freshness.
Clarifying questions are a last resort: a qualifier already in the question
("the X object", an object word next to a same-named field, a literal API
name) auto-resolves instead of blocking, and offered options are hygienic —
fuzzy lookalike junk never appears as a choice. But when two genuinely competing
components remain, or the best-fitting tools diverge on something consequential
(one destructive-simulation, one read-only), the router stops and asks which
you meant instead of letting the host silently commit. When nothing fits, it
says so rather than guessing (and can log the gap locally — opt-in via
logGap: true). (A deterministic, no-LLM routing mode is available via
SFI_ROUTER_MODE=offline for CI / air-gapped hosts.)
An experimental, opt-in RRF hybrid embeddings layer is available for early
adopters (SFI_EMBEDDINGS=1 + npm i @huggingface/transformers). It fuses the
TF-IDF candidates with a locally cached neural model (~23 MB) via Reciprocal
Rank Fusion. The model is not bundled with the npm package and isn't
fetched automatically — it requires the separate peer-dependency install
above, and the download-on-first-use path is still being hardened, so treat it
as a manual opt-in step, not something that happens for you. Off by
default either way — the lexical path is byte-identical when unset, and if
the model isn't installed or cached the funnel silently falls back to
lexical-only. The honesty/refusal decision and the deterministic route.tools
plan are not affected. See
docs/configuration.md for details.
Refusal behavior — fail closed, offer the read
Some questions should never route to an executable tool, no matter how well
they score. Score-independent refusal gates run on the raw question before
any intent matching, and a refusal is non-executable by shape (tools: []
plus a structured route.refusal disclosure):
- Write imperatives ("delete the X field for me", "go ahead and merge these
profiles") →
refused-write, with a read-only alternative offered instead (safe_to_delete_field,what_if_merge_profiles,get_impact, … by verb family) — the product has no write path; the refusal names the simulation that answers the underlying question safely. - Prompt injection / record-value exfiltration ("ignore your previous
instructions…", "dump all SSN values") →
refused-injection, with candidates and guidance suppressed entirely. - Runtime telemetry no tool models →
honest-gap-runtime, naming the nearest real reads. Non-Salesforce asks →out-of-scope.
Legitimate reads are explicit excluders — "am I allowed to edit…", "who can delete…", "is it safe to…" are permission questions and route normally. On a 2,000-question real-org evaluation, the gates cut genuine over-confident routes from 69 to 11 with zero answerable questions falsely refused.
Conversation context — follow-ups without server-side memory
The product stores no conversation state. Instead, the host may pass an
optional context.previous on each route_question call describing what the
prior turn was about, and terse follow-ups ("does it fire on delete too?",
"what about on Contact?", "the second one") resolve against it — pronoun
substitution is an exact-id lookup (never fuzzy), an inherited tool is an
advisory continuation capped at medium confidence, and a clarification
pick re-dispatches through the normal clarification contract (out-of-range
ordinals re-ask, stale ids are rejected). A self-contained question ignores
context entirely, and refusal gates run before any context logic — context
never bypasses them. Host-side, after routing "who can edit the SSN field?"
and running the tools:
// next turn: "can Support Agents specifically edit it?"
{
"question": "can Support Agents specifically edit it?",
"context": {
"previous": {
"question": "who can edit the SSN field?",
"tool": "sfi.field_access_audit",
"componentId": "CustomField:Contact.SSN__c"
}
}
}
When (and only when) context changes the route, the response discloses it in
route.contextApplied. See docs/routing.md for the full
host contract.
Honesty guarantees
The design rule across the surface is fail closed, disclose first:
- Grounded or refused. Every answer path ends in real tool output against the vault (or the consented live org); when no tool covers the ask, the router returns an honest gap — never a lookalike tool, never general Salesforce knowledge dressed up as org fact.
- Premise checks. A question naming a component the resolver cannot find
still routes (the tools fail closed on the unknown id), but confidence is
downgraded and a
PREMISE CHECKdisclosure warns that no such component exists in the vault — and a funnel-advisory route is never granted on a failed premise. - Disclosure-first. Coverage caveats, staleness warnings, live-consent notices, refusals, and context application are structured fields the host renders before the answer — not fine print after it.
How it works
One read-only refresh turns your org into a local vault; from then on every question is answered offline — your AI host asks the router for a shortlist, picks the tools, runs them against the vault, and grounds the answer. The host decides; the router only advises.
flowchart TB
subgraph REFRESH["Refresh — once, and whenever the org changes"]
direction LR
ORG[("Salesforce org")] -->|"sf project retrieve (read-only)"| SRC["source/ raw metadata"]
SRC -->|"extract + parse Apex / Flow / XML"| VAULT[("Graph A · Local vault<br/>your org, grounded<br/>Markdown + DuckDB graph")]
end
subgraph CONCEPT["Concept Model — ships with the package · no org data, ever"]
CM[["Graph B · Concept Model<br/>143 org-independent concepts / 195 rules<br/>save-order · relationships · sharing · code-shape"]]
end
subgraph ASK["Ask — every question, offline on your machine"]
direction TB
Q["Your question<br/>(plain language)"] --> HOST["Host LLM<br/>(Claude, etc.)"]
HOST -->|"1 · route_question"| FUNNEL["Semantic funnel<br/>offline TF-IDF — no network"]
FUNNEL -->|"toolCandidates + guidance<br/>(ranked shortlist — advises)"| HOST
HOST -->|"2a · retrieve: picks and runs"| TOOLS["sfi.* retrieval tools"]
TOOLS -->|"read"| VAULT
TOOLS -.->|"opt-in, read-only, capped"| LIVE[("Live org")]
HOST -->|"2b · reason: resolve"| RESOLVE["sfi.resolve<br/>fix the component"]
RESOLVE -->|"interpret"| INTERPRET["sfi.interpret · deterministic OFFLINE JOIN<br/>Concept Model × grounded vault slice<br/>no LLM · no live org read"]
INTERPRET -->|"cited, confidence-tiered<br/>structural-implication claims"| SYNTH["3 · synthesize_answer"]
TOOLS --> SYNTH
SYNTH --> ANS["Grounded answer<br/>+ provenance + freshness<br/>+ cited canonical ids"]
end
VAULT ==>|"grounded slice · Graph A"| INTERPRET
CM ==>|"concept rules · Graph B"| INTERPRET
Every box on the Ask path runs on your machine; the dotted edge to the live
org is the only one that can touch Salesforce, and only after you opt in.
Retrieval (route_question → sfi.* → synthesize_answer) reports what's in the
org; the reasoning path (resolve → interpret → synthesize_answer) reports
what its shape implies. sfi.interpret is a deterministic, offline join of
the org-independent Concept Model (Graph B — 143 concepts / 195 rules, which
never touches your org) against a grounded slice of the vault (Graph A); it runs
with no LLM and no live read, and every claim it feeds synthesize_answer is
cited and confidence-tiered. The deterministic SFI_ROUTER_MODE=offline mode
collapses step 1 to a single routed plan for hosts with no LLM in the loop.
Reasoning, not just retrieval
Retrieval tells you what's in the org. It doesn't tell you what a structure
implies — that a master-detail parent delete cascade-deletes its children,
that two active before-save flows on one object run in an undefined order, or
that an @AuraEnabled method is an entry point where Apex does not auto-enforce
field-level security. SfIntelligence answers those with a small second graph.
Alongside the org's grounded vault, the product ships a Concept Model: 143
org-independent, curated concepts and 195 rules that encode general Salesforce
truth — save-order phases, relationship semantics, sharing posture, code-shape
signals. No org data lives in it; the org enters reasoning only through the
grounded slice at query time. The sfi.interpret tool joins the two: it
assembles a minimal graph slice around one component and fires the applicable
rules to produce cited, confidence-tiered structural-implication claims. It
is deterministic and offline — no LLM, no live org read — and its claims are
also folded into sfi.synthesize_answer so they reach a normal answer, hedged
and attributed, on any MCP host.
The concept families are curated structural patterns, not vulnerability detection. A sample of what fires today:
- Relationships — master-detail cascade-delete + read-only roll-up summary; junction (two-master) many-to-many; formula/roll-up fields are read-only, so a write to one is write-hostile.
- Automation — multiple active record-triggered flows in one trigger context (undefined execution order); a firing condition that tests a field another automation writes in the same save (cross-phase coupling); before/after trigger phases; a flow fault-path rollback gap.
- Sharing & security surface — organization-wide default (OWD) posture;
without sharingsystem-context Apex; an external API surface (@RestResource/@AuraEnabled/@InvocableMethod) where FLS/CRUD are not auto-enforced; async boundaries; connected-app OAuth scope. - Code shape — Apex SOQL-injection / bulkification / CRUD-FLS / swallowed- exception / hardcoded-id gaps; a test with no assertions.
Every claim is grounded or it does not exist. Each interpretation carries a
groundedIn list of the exact component ids it matched — no citation ⇒ no
claim — and its confidence is computed, never asserted: the weakest of
the rule's ceiling and the grounding edges it matched (see the two-axis note
below). An empty result means "no concept rule fired," never "nothing depends
on it." And the governor/security concepts reason about static code shape —
they name a surface or a coupling, not a live limit breach or a proven runtime
vulnerability. For a worked resolve → interpret → synthesize example, see
docs/guides/asking-questions.md §2b; for
the design rationale, ADR-008.
What you can ask
Eight capability areas, each answerable in natural language (ask
sfi.capabilities, or just "what can you do?", for the live map):
| Area | Example questions |
|---|---|
| Find & identify | "where is the email field?" · "what's the payment object called?" |
| Understand | "what does this validation rule do?" · "what happens when an Account is saved?" (automation on standard objects works even when the object file was not retrieved; objectModeled: false is surfaced) |
| Impact & dependencies | "what breaks if I delete this field?" · "is it safe to deactivate this flow?" |
| Permissions & sharing | "why can't this user see this record?" · "who can edit the Salary field?" · "who holds the Sales Manager permission set?" (live) · "what does user Jane hold?" (live) · "who's in the Support queue?" (live) · "which active users have zero permission-set assignments?" (live) |
| Automation & code | "what runs on Case create?" · "which Apex methods have no real test coverage?" · "decode this Apex debug log / governor-limit exception to the class that ran" |
| Decision-support (before you build/change) | "before I add automation to this object, what already runs there?" · "building Apex here — what should I watch out for?" · "before I change/require this field, what breaks?" |
| Architect & developer | "are there circular Apex dependencies?" · "which classes have no test reference?" · "does the vault still match the live org?" |
| Integrations | "what external systems does this org talk to?" · "list every outbound endpoint" |
| Documentation | "give me a tour of this org" · "generate a data dictionary" · "which reports / objects / permission sets have no description?" (list_components with missingDescription: true) |
| Health & audit | "is my vault fresh?" · "where is PII stored?" · "how has the org changed across refreshes?" |
These are advisory, read-only briefings — e.g. automation_build_advisor,
apex_build_advisor, field_change_advisor synthesize what the org already
shows so you make a better build decision; find_dependency_cycles,
apex_test_coverage, live_drift_check, and org_history serve architects and
developers. None of them write to the org.
Every org artifact the product names is backed by a tool call and cited with its
canonical ID (CustomObject:Account, CustomField:Account.Industry__c), and
every relationship is cited with its confidence (declared, parsed, or
heuristic).
Trust & confidence glossary
Every answer is tagged so you know how much to lean on it. These tags match the
runtime values verbatim (the trust block on analysis tools, the per-edge
confidence, and synthesize_answer's provenance.stamp).
Edge confidence — how a relationship was derived. This is the per-edge tier you see on dependency answers:
declared— Salesforce metadata states it directly (a layout assignment, a field'sreferenceTo, a permission grant). Highest trust.parsed— produced by AST/XML parsing of source (the parser-grade Apex pass that runs on every refresh by default — resolved field reads/writes, cross-class calls, field-level SOQL — plus the formula tokenizer, Flow elements, a profile's<layoutAssignments>). High trust.heuristic— produced by regex / token / dynamic-string analysis (the Apex recall scanner that supplements the parsed pass, name-pattern detection). May have false positives — spot-check before acting.
Claim confidence — a different axis: how well a reasoning claim from
sfi.interpret is grounded. It uses the same declared | parsed | heuristic
words, but it is computed, not read off one edge: a claim's confidence is the
weakest of the concept rule's ceiling and the grounding edges the claim matched.
An absence-shaped claim under non-complete coverage reads unknown. Do not
conflate the two — edge confidence describes a single relationship; claim
confidence describes an interpretation that rests on one or more such edges and
can never exceed the weakest of them.
Provenance — where the answer came from:
offline_snapshot— the last/sfi-refreshvault. The default for every vault tool.live_org— an opt-in, capped, read-onlysfi.live_*SOQL read.hybrid— fuses vault + live and discloses both provenances.
Completeness — how much of what the answer depends on was actually retrieved:
complete— the refresh modeled every metadata family the answer needs.partial— a family the answer depends on was not retrieved; absence means "not checked", never "none" (acoverageCaveatnames the gap).unknown— coverage could not be determined.
Two tools make this concrete. sfi.coverage_report lists what the retrieve
manifest requested and returned; sfi.retrieve_blindspot_report lists what the
graph references but never retrieved — automation/code/config that depends on a
component the vault never pulled — so an "X is unused / nothing references X"
answer carries a known-coverage caveat instead of a silent blind spot.
How much it models
| MCP roster | Every sfi.* tool is registered in code; run sfi.capabilities (see productManifest) for the live registered/advertised counts — never a handwritten number |
| Graph model | A broad ComponentType union across 103 component types (objects, fields, Flows, Apex, layouts, permissions, sharing, UI, legacy automation, integrations, CPQ, OmniStudio, reports, FlexiPages, and more) connected by 23 typed edge types — see sfi.capabilities for how tools group those families. Counts are pinned by eval/product-manifest.json. |
| Concept Model | Concept Model (143 concepts / 195 rules) — org-independent, curated — JOIN against the grounded vault to produce cited structural-implication claims via sfi.interpret. No org data lives in the model. Same figures in eval/product-manifest.json. |
| 26 | skills + 5 slash commands + 4 subagents (Claude Code plugin layer) that auto-activate in a session |
What it does NOT do
Boundaries are explicit, and the product tells you plainly when it hits one rather than papering over the gap with general Salesforce knowledge:
Shortened here. Read the whole README on GitHub.
Signals
- GitHub stars
- 2
- Last commit
- Oct 2026
- Weekly downloads
- 363
- Weekly_downloads
- 112 weekly_downloads
Advanced
- Delivery
- sf-intelligence MCP server → your Ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
io-github-pranavnagrecha-sf-intelligence- Source
- github.com/pranavnagrecha/salesforce-intelligence
github.com/pranavnagrecha/salesforce-intelligence
More in Docs & knowledge
MCP server · dat999zx
More in Docs & knowledgeagent-native-slides
MCP server · builderio
More in Docs & knowledgemcp-memory-server
MCP server · mnemoverse
More in Docs & knowledgedatasinking
MCP server · heubme2020
More in Docs & knowledgespoken
MCP server · spokenmd
More in Docs & knowledgeemailmd
MCP server · anypost
More in Docs & knowledge