MCP Trust Tiers
When the FrootAI kernel attaches an external MCP server, it consults a trust manifest to decide how much to do on your behalf without asking. Every publisher in that manifest sits in one of four trust tiers, and every elevated tier is backed by a reviewable evidence file — not an opinion.
This page explains, for users and CIOs:
- what the four tiers mean for you when you attach a server,
- how to read the evidence behind any
verified-publisherbadge, - how to request a promotion for a publisher you maintain,
- the 90-day quarterly re-review cadence that keeps trust honest,
- how to override trust on your own machine and share it with your team.
The authority for these rules is the open, CC0-licensed trust manifest. The manifest is the single source of truth — the kernel never carries an inline, hard-coded publisher list.
Why trust tiers exist
An MCP server is code that runs tools on your behalf. Some of those tools are destructive — deleting a cloud resource, dropping a database table, issuing a refund, force-pushing a branch. The question the kernel must answer at attach time is: how much should I do silently, and how much should I confirm with the user first?
The answer depends on who published the server and how confident we are in that identity. That confidence is exactly what the four tiers encode. The escalating axis is how much the kernel does without asking you:
- A server you implicitly trust (because it’s from Microsoft, or a vendor we’ve verified) can attach without a prompt.
- A server we know nothing about should always ask before it attaches.
- A server that looks like an impersonation of a trusted one should be refused outright.
Trust is never based on popularity. A server with a million installs and no
verifiable identity is still community. Install count is a ranking signal for
the marketplace UI — it is never a trust signal.
The four tiers at a glance
Each tier maps to a policy block the kernel enforces at attach time:
| Tier | Attaches without prompt? | Destructive tools without per-call confirm? | Metered as |
|---|---|---|---|
| first-party-ms | ✅ Yes | ✅ Yes | Azure AOAI |
| verified-publisher | ✅ Yes | ❌ No (always confirm) | per-publisher |
| community | ❌ No (always prompt) | ❌ No (always confirm) | per-publisher |
| untrusted | ❌ Refused at attach | — | — |
Read each row as a sentence:
- first-party-ms — “Attach silently; destructive tools may run without a per-call prompt; usage rolls up to the Azure AOAI meter.”
- verified-publisher — “Attach silently, but any destructive tool still asks before it runs; usage meters per publisher.”
- community — “Always prompt the user before attaching; destructive tools always confirm; usage meters per publisher.”
- untrusted — “Refuse the attach before the transport is even spawned.”
first-party-ms is the only tier permitted to run a destructive tool
without a per-call confirmation, because it is the only tier under FrootAI /
Microsoft operational control.
Tier 1 — first-party-ms
Servers owned and operated by Microsoft or by FrootAI itself, published from a Microsoft-verified GitHub org under a Microsoft-controlled package namespace. These are treated as inside the FrootAI / Microsoft trust boundary.
What it means for you: the server attaches without a prompt, and its destructive tools may run without a per-call confirmation — because by attaching a first-party server you’ve already consented to its operations.
Examples: Azure MCP, Playwright, Markitdown, MS Learn, Foundry, Fabric, GitHub.
What it requires: a verified Microsoft org, the server published from that
org’s own repository under @microsoft/* / @azure/* (or an equivalent
Microsoft release pipeline), and a reviewable evidence file.
Tier 2 — verified-publisher
Servers from a known, reputable third-party organisation that FrootAI has positively verified, but which is outside the FrootAI / Microsoft operational boundary.
What it means for you: the server attaches without a prompt (you’ve trusted
curated publishers), but every destructive tool still confirms before it
runs. So a verified database server can attach silently, yet a DROP TABLE
still asks first.
Examples: Context7 (Upstash), Notion, Stripe, Tavily, MongoDB, Supabase, Elastic, pgEdge, Sonatype, SonarSource, Atlassian, Vercel, HashiCorp.
What it requires (the promotion gate):
- Identity match — the manifest key matches the upstream GitHub org exactly. No aliases, no shadowing.
- At least one documented positive signal, recorded in the evidence file:
- an existing Orchard accelerator already integrates this publisher, OR
- a code review of the server’s source by a FrootAI maintainer, OR
- a founder-verified business relationship / known-good vendor (e.g. the official server published from the vendor’s own verified org).
- Active maintenance — a release within the last 180 days.
- A real, named org with a public presence (not an anonymous handle).
One positive signal is the minimum, not popularity. A publisher with only a high install count and no documented signal stays
community.
Tier 3 — community
The default tier for every crawled publisher that is neither first-party, nor positively verified, nor disqualifying. This is not a negative judgement — it simply means “we have not done the verification work to elevate this, so you decide per attach.”
What it means for you: the kernel always prompts before attaching — you see a description of the server and choose. Destructive tools always confirm.
How a publisher leaves this tier: by satisfying the verified-publisher
gate above and landing an evidence file (see Requesting a promotion below).
The community tier is the majority of the catalog — the healthy long tail of independent MCP authors. It is safe to use; it just asks first.
Tier 4 — untrusted
Servers that are refused at attach time — the transport is never spawned. This tier is for servers that are actively risky, not merely unverified.
A publisher is auto-tagged untrusted when any one of these holds:
- Fork of a major server — the repo is
<other-org>/<canonical-slug>where that distinctive slug belongs to a first-party server under a different org. A fork ofmicrosoft/playwright-mcppublished byrandomuseris the classic supply-chain impersonation vector. - No owner identity — no resolvable GitHub org, or a deleted/suspended owner.
- 14-day unresponsive PR — a security or correctness PR sat unaddressed for 14+ days with no maintainer response.
untrustedis a flag for review, not a permanent blocklist. A legitimate hard-fork (a maintained successor after the original was abandoned) can be reclassified — but only with an evidence file and a changelog entry.
Important: generic server names (mcp, mcp-server) that many vendors use
independently are never treated as forks. Fork detection only fires on
distinctive first-party slugs.
How to read an evidence file
Every first-party-ms and verified-publisher entry has a public, CC0 evidence
file at frootai/orchard/registry/mcp-trust-evidence/<publisher>.md. It is the
sentence a CIO reads to understand why a publisher holds its tier.
An evidence file has YAML frontmatter plus reviewable sections:
---
publisher: upstash
tier: verified-publisher
servers_covered:
- upstash/context7
last_reviewed: 2026-06-25
reviewer: frootai-maintainer
signals:
prior_orchard_accelerator: true
code_review: false
founder_verified: false
contact_overlay: upstash.contact.local.md
---What to look at:
tier— the trust tier this evidence justifies.servers_covered— the exact catalog slugs the evidence backs.signals— which positive signal cleared the gate. At least one istruefor averified-publisher.last_reviewed— the date of the most recent human review (drives the 90-day cadence below).- The Decision section — the reviewer’s one-paragraph justification.
Reading evidence from the CLI or an agent
You don’t have to open the file by hand. The MCP tool
mcp_frootai_trust_evidence(publisher) returns the (redacted) evidence
content, the trust tier, and the last-reviewed date for any publisher:
mcp_frootai_trust_evidence({ "publisher": "upstash" })
→ { "found": true, "publisher": "upstash", "tier": "verified-publisher",
"last_reviewed": "2026-06-25", "content": "..." }For a community or untrusted publisher it returns found: false along with
the list of publishers that do have evidence.
Privacy: contact info is never public
Each evidence file may reference a contact_overlay — an incident-response
contact (email / handle) used only if a server is compromised. That contact is
consent-scoped and never published: it lives in a gitignored
*.contact.local.md sidecar, the committed evidence file records only a
last-reachable date, and a redaction step strips any contact field before any
public copy. (This is Doctrine #3 — never leak publisher metadata without
consent.)
Requesting a promotion
If you maintain an MCP server currently in the community tier and believe it
qualifies for verified-publisher, here’s the path:
- Open a promotion request (an issue or PR on
github.com/frootai/frootai) naming your publisher org and the server slug(s). - Provide a positive signal — at least one of:
- a link showing your server is integrated into an Orchard accelerator / solution play,
- an invitation for a FrootAI maintainer to code-review the server,
- evidence that the server is the official one published from your own verified GitHub org.
- Confirm identity — your GitHub org must exactly match the manifest key you’re requesting (Doctrine #2 — no aliases).
- A maintainer authors the evidence file, the change re-composes the trust
manifest, and a changelog row is appended recording
(date, publisher, old_tier → new_tier, reason, reviewer).
The review SLA
Community submissions are reviewed within 14 days of the request. A rejection always comes with a written reason in the thread and a path to remediation — we never block a community PR arbitrarily (Doctrine #7).
What will not promote you
- High install counts alone.
- A polished README with no verifiable identity.
- A third-party wrapper of someone else’s API (that is the original vendor’s server to publish, not yours).
The quarterly review cadence
Trust is not “set once and forget.” Every evidence file carries a
last_reviewed date, and 90 days after that date the publisher is due
for re-review. An automated job opens a [trust-review] <publisher> issue so a
maintainer re-confirms the tier still holds and refreshes the date.
A tier that was verified once and never re-reviewed is, by default, stale —
and FrootAI treats stale trust as risk (Doctrine #4 — never trust without
refresh). This is what keeps a verified-publisher badge meaningful months
after it was first granted.
Demotion + revocation
A publisher is demoted (or revoked to untrusted) when:
- identity changes in a way that breaks the exact-match invariant,
- the server is abandoned (no release in 180 days for a verified publisher),
- a security incident is confirmed (revoked to
untrustedpending remediation), - a security PR goes 14 days unaddressed.
Every demotion is a changelog entry with a reason. Demotions are never silent.
Overriding trust on your machine
The curated trust list is the base; you always win for your own machine. At
evaluator init, your personal overrides at ~/.frootai/trust.json are merged on
top of the shipped manifest.
You can:
- Downgrade a publisher you don’t trust on your laptop, or
- Upgrade a community publisher you’ve personally vetted.
You cannot force the curated list to elevate a publisher for everyone — overrides are per-user.
Sharing overrides with your team
Export your overrides as a clean, shareable trust file:
frootai mcp trust export > my-trust.jsonA teammate drops my-trust.json at their own ~/.frootai/trust.json to adopt
the same tier decisions. (Per Doctrine #3, overlay policies are never honoured
and are never exported — only the publisher → tier decisions are shared.)
Inspect the merged view any time:
frootai mcp trust list # combined shipped + your overrides
frootai mcp trust set <area> verified-publisher
frootai mcp trust unset <area> # revert to the shipped tierAwareness telemetry
When you attach a server that resolves to a non-curated publisher
(community, unknown, or untrusted), the kernel emits a
federation_trust_uncurated_attempt event. This is awareness only — it never
blocks you. It lets operators see which uncurated publishers users actually
reach for, so evidence-file backfill can be prioritised. The event carries no
secret-bearing fields.
The trust manifest is open
The trust list is CC0-1.0 licensed and shipped in three byte-identical copies (npm, Python, and the public CDN). Anyone can read it, audit it, fork it, or build on it. CI enforces that the three copies never drift and that the manifest always matches the evidence files behind it.
This openness is deliberate: an open, auditable trust list accumulates community trust over time in a way a closed, proprietary one never could.
How the kernel evaluates trust
When you ask to attach a server, the kernel runs a fixed decision tree. The first matching rule wins:
- Is it untrusted? A fork of a first-party canonical slug under a different org, or no owner identity, or a 14-day-unresponsive PR → refuse the attach. (Safety before convenience.)
- Is it first-party-ms? A verified Microsoft / FrootAI org publishing its own server → attach silently, destructive tools allowed.
- Is it verified-publisher? Exact identity match + ≥1 documented signal + active maintenance → attach silently, destructive tools still confirm.
- Otherwise → community: prompt before attaching.
The tree encodes the doctrine directly: untrusted is checked first (safety), elevated tiers require evidence, and community is the safe default — the kernel never silently elevates a publisher.
Trust verdict reference
Internally each evaluation produces a verdict. You may see these in logs or
the fai_attach_mcp response:
| Verdict | Tier | What happens |
|---|---|---|
attach-allowed | first-party-ms / verified-publisher | Attaches without a prompt |
attach-with-prompt | community | You’re asked to confirm before attaching |
unknown-publisher | (not in manifest) | Treated as uncurated; you’re asked to confirm |
blocked-untrusted | untrusted | Refused before the transport spawns |
Only attach-allowed is curated. The other three emit the awareness telemetry
described above.
Worked examples
A — Attaching a first-party server (Azure)
You attach the Azure MCP server. Its publisher (microsoft) is first-party-ms,
so the kernel attaches without a prompt. When you later run a destructive
tool — say, deleting a resource group — it runs without a per-call
confirmation, because attaching a first-party server already expressed that
consent. Usage meters to the Azure AOAI line.
B — Attaching a verified server with a destructive tool (Stripe)
You attach the Stripe server. Its publisher (stripe) is verified-publisher,
so it attaches silently. But when you call a destructive tool — issuing a
refund — the kernel confirms first, even though the attach itself was
silent. That’s the whole point of the verified tier: trusted enough to attach,
not trusted enough to mutate without asking.
C — Attaching a community server (an indie tool)
You attach a useful single-purpose server from an independent author with no evidence file. The kernel prompts you with a description of the server before attaching. You read it and decide. The attach proceeds only on your confirmation, and an awareness event is logged.
D — A fork is refused (impersonation)
You try to attach coolhacker/azure-mcp. The slug azure-mcp matches the
canonical first-party server, but the org is coolhacker, not Microsoft. The
kernel auto-classifies this untrusted and refuses the attach before any
transport is spawned, naming the reason (a fork of a first-party slug under a
non-Microsoft org). It’s flagged for human review; reclassification would
require an evidence file.
Glossary
- Trust manifest — the
publisher → tiermap (trust.json) the kernel consults at attach time. CC0-1.0, three byte-identical copies. - Evidence file — the public, reviewable
<publisher>.mdthat justifies an elevated tier. - Signal — a documented reason a publisher qualifies for
verified-publisher: a prior Orchard accelerator, a code review, or a founder-verified relationship. - Override — a per-user trust decision in
~/.frootai/trust.jsonthat wins for your machine only. - Verdict — the kernel’s per-attach decision (
attach-allowed,attach-with-prompt,unknown-publisher,blocked-untrusted). - Policy block — the per-tier rules the kernel enforces
(
attachWithoutPrompt,allowDestructive,metering,blockedAtAttach). - Canonical slug — a distinctive first-party server name used for fork
detection (generic names like
mcp/mcp-serverare excluded).
FAQ
Is community unsafe?
No. Community servers are safe to use — the kernel just prompts before attaching
so you make the call. It’s the healthy default for the independent long tail.
A community server has more installs than a verified one. Why isn’t it verified? Install count is a ranking signal, never a trust signal. Verification requires a documented positive signal, not popularity.
Can I attach an untrusted server anyway?
Only by an explicit local override in your own ~/.frootai/trust.json. The
curated list never attaches it for you, and your override is audited locally.
Who decides a verified-publisher promotion?
A FrootAI maintainer authors the evidence file; the founder review pass signs
off all elevated tiers before the manifest is tagged.
Where do I see the change history?
Every trust change is recorded in mcp-trust-changelog.md with
(date, publisher, old_tier, new_tier, reason, reviewer) — Doctrine #8, never
forget provenance.
The eight trust doctrines
The trust system is governed by eight non-negotiable principles:
- Never promote a publisher without evidence — every elevated tier has a reviewable evidence file.
- Never shadow publisher identity — the manifest key matches the upstream GitHub org exactly.
- Never leak publisher metadata without consent — incident-response contacts stay private.
- Never trust without refresh — quarterly 90-day re-review.
- Never bundle without signature — signed bundles must be FrootAI-signed.
- Never publish stale data — the catalog refreshes weekly; stale servers are flagged.
- Never block a community PR arbitrarily — 14-day review SLA with written reasons.
- Never forget provenance — every catalog entry and trust change is audit-ready.
How metering differs by tier
The metering field on each tier’s policy block decides which usage meter an
attach rolls up to:
azure-aoai(first-party-ms) — usage rolls into the Azure AOAI line, the same meter as first-party Azure model usage.per-publisher(verified-publisher+community) — usage is attributed to the individual publisher, so per-publisher cost and volume are visible.none/ blocked (untrusted) — an untrusted server never attaches, so there is nothing to meter.
Metering is about attribution and cost visibility, not billing publishers — publishers are never charged. The only paid product in the ecosystem is the hosted-MCP tenant fee.
See also
- What’s Federation? — why the router, namespacing, and trust tiers exist.
- How to Attach a Server — the step-by-step attach guide.
- Browse the marketplace — every federated server with its trust badge and evidence.
- Internal standard —
docs/internal/trust-assignment-criteria.md: the full tier criteria + worked examples the maintainers apply. - Live query — the
mcp_frootai_trust_evidence(publisher)MCP tool returns evidence + tier + last-reviewed date for any publisher. - CLI —
frootai mcp trust list | set | unset | exportto inspect and override trust on your machine. - Audit log —
mcp-trust-changelog.mdrecords every tier change with a reason and reviewer.
The trust manifest is CC0-1.0. Read the internal standard at
docs/internal/trust-assignment-criteria.md, or query any publisher live with
the mcp_frootai_trust_evidence tool.