Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Contributing

This repository is an incubation space for the
[Tool Annotations Interest Group](https://modelcontextprotocol.io/community/tool-annotations/charter).
We welcome proposals, schema changes, and reference implementations that
inform a future Extensions Track SEP.

## What lives here

- **Specification drafts** — `specification/draft/<extension-name>.mdx`,
one file per extension, written in the same RFC-2119 style as the core MCP
specification (per [SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2133-extensions.md)).
- **Decision records** — `docs/decisions.md`. Append, do not rewrite.
- **Open questions** — `docs/open-questions.md`.

## What does *not* live here

- Implementation code. Reference implementations live in their own
repositories and are linked from the relevant `specification/draft/*.mdx`.
- Binding specification changes. Those are made through the
[SEP process](https://modelcontextprotocol.io/community/sep-guidelines).

## Proposing a change to an existing extension

1. Open a PR against `specification/draft/<name>.mdx`.
2. Update the **Status** and **Changelog** sections in the frontmatter.
3. If the change is breaking (per the SEP-2133 definition), use a new
extension identifier and a new file.
4. Append an entry to `docs/decisions.md` if the change reflects a design
decision worth preserving.

## Proposing a new extension

1. Read [SEP-2133, "Experimental Extensions"](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2133-extensions.md#experimental-extensions).
2. Open a discussion or PR proposing the identifier and scope.
3. On acceptance, add `specification/draft/<new-name>.mdx` using the
frontmatter from an existing draft as a template.

## Code of conduct

This repository follows the
[MCP Code of Conduct](https://github.com/modelcontextprotocol/.github/blob/main/CODE_OF_CONDUCT.md).
11 changes: 11 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

Per SEP-2133, official MCP extensions are required to be available under the
Apache 2.0 license. Experimental extensions in this repository follow the
same convention so that contributions made here can flow into a future
official extension repository without re-licensing.

The full text of the Apache License, Version 2.0 is available at:
https://www.apache.org/licenses/LICENSE-2.0
20 changes: 20 additions & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Maintainers

This repository is governed by the
[Tool Annotations Interest Group](https://modelcontextprotocol.io/community/tool-annotations/charter).
Day-to-day repository maintenance follows the IG's facilitator structure.

| Role | Name | Organization | GitHub |
| ----------- | -------------- | ------------ | ---------------------------------------------------- |
| Facilitator | Sam Morrow | GitHub | [@SamMorrowDrums](https://github.com/SamMorrowDrums) |
| Facilitator | Robert Reichel | OpenAI | [@rreichel3](https://github.com/rreichel3) |

Per [SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2133-extensions.md#experimental-extensions),
core maintainers of the modelcontextprotocol organization retain oversight,
including the ability to archive or remove this repository.

## Per-extension maintainers

Individual extensions may nominate additional maintainers responsible for
their specification draft and reference implementations. List them in the
`specification/draft/<name>.mdx` frontmatter.
97 changes: 96 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,96 @@
# experimental-ext-tool-annotations
# Tool Annotations Interest Group — Experimental Extensions

> ⚠️ **Experimental** — This repository is an incubation space for the
> [Tool Annotations Interest Group](https://modelcontextprotocol.io/community/tool-annotations/charter).
> Contents are exploratory drafts intended to feed future Extensions Track SEPs
> ([SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133)).
> They do not represent official MCP specifications or recommendations.

**Charter:** [modelcontextprotocol.io/community/tool-annotations/charter](https://modelcontextprotocol.io/community/tool-annotations/charter)
**Discord:** [#tool-annotations-ig](https://discord.com/channels/1358869848138059966/1482836798517543073)
**Open work:** [Pull requests](https://github.com/modelcontextprotocol/experimental-ext-tool-annotations/pulls)

## Why split the work?

[SEP-1913 (Trust and Sensitivity Annotations)](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1913)
bundles four concerns that have proven hard to evaluate as a single unit: a
client-facing trust taxonomy, action-security metadata for tool I/O, a
malicious-activity signal, and propagation rules across session boundaries.

The sponsor, [@localden](https://github.com/localden), asked the central
question directly in review: the SEP "adds a few schema modifications and a
thorny array-or-scalar polymorphism on enum fields. If the taxonomy turns out
to be wrong, I worry that we can't remove it or easily modify it. Can we do a
potential narrower first cut?" The subsequent design discussion converged on a
layered answer: a small, stable annotation surface on the wire, with richer
evidence kept out-of-band and referenced by a bounded pointer.

This repo follows that steer. Each concern becomes a **separate experimental
extension** with its own [reverse-DNS identifier](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2133-extensions.md#definition),
its own reference implementation, and its own path to a future Extensions
Track SEP. Drafts can graduate independently — directly addressing the "narrower
first cut" ask without throwing away the combinatoric value of the full set.

See [docs/decisions.md](docs/decisions.md) for the decision record and
[docs/trust-model.md](docs/trust-model.md) for the shared enforcement model.

## Extensions

| Identifier | Status | What it specifies | Reference implementation(s) |
| :--- | :--- | :--- | :--- |
| [`io.modelcontextprotocol/trust-annotations`](specification/draft/trust-annotations.mdx) | Draft skeleton | **Primary extension.** A small, scheme-agnostic client-facing data-classification vocabulary (`sensitive`, `untrusted`) on result `_meta`, plus an optional `evidenceRef` pointer slot that carries richer payloads out-of-band. | Python SDK: [`kapil8811/mcp-trust-annotations`](https://github.com/kapil8811/mcp-trust-annotations) (138-test suite, healthcare demo, LLM usability study). |
| [`io.modelcontextprotocol/action-metadata`](specification/draft/action-metadata.mdx) | Draft skeleton | `inputMetadata` / `returnMetadata` / outcome classifiers (incl. `requires_review`) on `ToolAnnotations`, describing where inputs go, where outputs originate, and what real-world effects a tool can cause. | Carries forward [SEP-2061 (Action Security Metadata)](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2061) by [@rreichel3](https://github.com/rreichel3); reference impl per that proposal (`read_drafts` / `list_inbox` / `send_email`). |
| [`io.modelcontextprotocol/ifc-fides`](specification/draft/ifc-fides.mdx) | Draft skeleton | A **profile** of the `trust-annotations` `evidenceRef` slot: `type: "ifc.fides.v1"` carrying an integrity + confidentiality label for deterministic information-flow control, following the FIDES paper ([arXiv:2505.23643](https://arxiv.org/abs/2505.23643)). | Emitter candidate: [`github-mcp-server`](https://github.com/github/github-mcp-server) (does not emit IFC labels today — closing that gap is the proof point). |

### Why FIDES is a profile, not a top-level extension

Information-flow control is modelled as a profile rather than the namespace
root because IFC (an integrity × confidentiality lattice) is one enforcement
model among several that reviewers raised — capability tokens, caller/tool
cosigning, and sequence-shape audit records. A top-level `ifc/` root would bake
one academic model into the namespace and foreclose the others. As one reviewer
put it, IFC "fits relatively well if you use annotations" — an endorsement of
IFC *as a profile*, not as the wire root. As a `type` value under
`trust-annotations`'s open-ended `evidenceRef` slot, the FIDES work stays
first-class while every other model can occupy the same slot.

## Relationship to SEP-1913

SEP-1913 remains the canonical place to discuss the overall problem framing.
This repository develops the schema-bearing parts of that proposal as
independently shippable extensions. When an extension here is ready to graduate,
an Extensions Track SEP can reference this repo as the prior art and the working
implementation that SEP-2133 [requires](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2133-extensions.md#creation).

For the full per-SEP plan — what happens to SEP-1913, SEP-2061, SEP-1862 and
others, and the SEP-2127 refactor precedent — see
[docs/sep-disposition.md](docs/sep-disposition.md).

**Out of scope for these extensions** (see [docs/open-questions.md](docs/open-questions.md)):

- **`maliciousActivityHint`** — reviewer concerns are structural (it fires at
`tools/resolve` before execution can produce evidence; a boolean is the wrong
granularity for client UX; clients won't trust server self-attestation). If it
returns, it is per-`ContentBlock` with spans, on a different clock. It stays
on the SEP-1913 umbrella rather than in an extension here.
- **Propagation rules** — sensitivity escalation across session boundaries, and
the sequence-shape gap (an annotation surface for "this was call N in a
flagged sequence") remain open. Likely a future extension once the taxonomy
and `evidenceRef` shape are stable.

## Repository layout

This repo mirrors the structure of official extension repositories such as
[`ext-auth`](https://github.com/modelcontextprotocol/ext-auth):

```
specification/draft/<extension-name>.mdx # one spec per extension
docs/ # decision log, open questions, related work
MAINTAINERS.md # IG facilitators
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Substantive design discussion happens
on PRs against the relevant `specification/draft/*.mdx` file, in the IG
Discord, and (for cross-extension concerns) on [SEP-1913](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1913).
91 changes: 91 additions & 0 deletions docs/decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Decision log

Append-only record of design decisions for the Tool Annotations IG's trust /
privacy extension work. Newest at the bottom.

## 2026-06-10 — Split SEP-1913 into independent extensions

**Decision.** Split the schema-bearing parts of SEP-1913 into separate
experimental extensions, each with its own `io.modelcontextprotocol/…`
identifier and reference implementation, rather than pursuing one broad
Standards Track SEP.

**Rationale.** @localden's review asked for a *narrower first cut*; the IG
[aligned 2026-05-28](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2820)
on an extension-first strategy. Independent extensions can graduate on their own
clock and avoid hard-to-remove schema.

## 2026-06-10 — Three initial extensions

**Decision.** `trust-annotations` (primary), `action-metadata`, `ifc-fides`.

**Rationale.** These are the three pieces with either a reference implementation
or an existing SEP behind them: Kapil's SDK, SEP-2061 (Reichel), and the FIDES
model respectively.

## 2026-06-10 — FIDES is a profile, not a top-level extension

**Decision.** Information-flow control is `type: "ifc.fides.v1"`, a profile of
the `trust-annotations` `evidenceRef` slot — not a top-level `io.modelcontextprotocol/ifc`
extension.

**Rationale.** IFC is one enforcement model among several raised in review
(capability tokens — pshkv; cosigning — viftode4; sequence shape — marras0914).
A top-level `ifc/` root would foreclose those. Reviewer endorsement was for IFC
"if you use annotations" — i.e. as a profile.

## 2026-06-10 — `evidenceRef.type` is an open string

**Decision.** `type` MUST remain an open string with a non-binding registry of
well-known values; never a closed enum. Required fields are `digest` and
`canonicalization`; `schema` recommended; `ref` optional.

**Rationale.** Adapted from the vaaraio / Rul1an convergence in the SEP-1913
thread. An open `type` is what lets IFC, data-class, sequence-shape, and
attestation profiles share one slot.

## 2026-06-10 — `requiresReview` moves to `action-metadata`

**Decision.** `requiresReview` is an `action-metadata` field, not a
`trust-annotations` field.

**Rationale.** It is a workflow/consent signal, not a data-classification
property. Keeping it out of the trust taxonomy avoids reproducing SEP-1913's
"several concerns in one schema" problem at smaller scale.

## 2026-06-10 — DataClass demoted to a profile

**Decision.** The wire taxonomy keeps only the coarse `sensitive` boolean.
The four-level classification + regulatory scope becomes an `evidenceRef`
profile `type: "data-class.v1"`.

**Rationale.** Coarse binary is universally client-actionable and cheap on the
wire; the richer taxonomy can evolve behind a profile without a breaking schema
change.

## 2026-06-10 — Parked: maliciousActivityHint, propagation rules

**Decision.** Neither becomes an extension now; both stay on the SEP-1913
umbrella.

**Rationale.** `maliciousActivityHint` has unresolved structural objections
(fires pre-execution at `tools/resolve`; boolean granularity wrong for UX;
clients won't trust server self-attestation). Propagation/sequence-shape needs
the taxonomy and `evidenceRef` stable first.

## 2026-06-10 — Citations: public sources only

**Decision.** Reference implementations and motivating examples cite **public**
artifacts — [`github-mcp-server`](https://github.com/github/github-mcp-server),
[`kapil8811/mcp-trust-annotations`](https://github.com/kapil8811/mcp-trust-annotations),
[arXiv:2505.23643](https://arxiv.org/abs/2505.23643) — and index on the public
SEP-1913 review record (esp. @localden). Private/internal implementations are
not named or linked.

## 2026-06-10 — Pre-flight (SEP-1862) stays core

**Decision.** These extensions are response-level and do not depend on Tool
Resolution. SEP-1862 remains a core/Standards-Track protocol change.

**Rationale.** The 2026-05-28 IG meeting concluded pre-flight is inherently a
protocol-level change, not an extension.
61 changes: 61 additions & 0 deletions docs/intent-comment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Intent comment (draft, pre-post review)

This is the comment we plan to post on
[SEP-1913](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1913),
with an abbreviated pointer version for
[SEP-2061](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2061).
Kept here so it can be reviewed and stays in sync with
[sep-disposition.md](./sep-disposition.md).

---

## For SEP-1913

> **Intent: split this SEP and migrate to the Extensions Track**
> >
> A note on direction for everyone following this thread. When SEP-1913 was
> first framed, the **Extensions Track** (SEP-2133) and the `experimental-ext-*`
> incubation process didn't exist in their current form. They now do, and
> they're a better fit for this work than a single Standards Track SEP.
> >
> Two things pushed us here:
> >
> - @localden's review ask for a **narrower first cut** — the concern that a
> broad taxonomy with array-or-scalar polymorphism is hard to remove or change
> once it lands.
> - The Tool Annotations IG's
> [May 28 decision](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2820)
> to pursue trust/privacy as an **experimental extension first**, gather
> adoption evidence, then ask core maintainers to absorb anything.
> >
> So the plan is to \*\*split this proposal into a few small,
> independently-shippable extensions\*\*, each with its own
> `io.modelcontextprotocol/…` identifier, reference implementation, and path to
> an Extensions Track SEP. Incubation is in
> [`experimental-ext-tool-annotations`](https://github.com/modelcontextprotocol/experimental-ext-tool-annotations).
> >
> Kicking off with a few draft extensions in the tool annotations repo — not
> sure yet whether they'd each need separate repos eventually, or whether
> grouping them in one is fine. That's part of what incubation is for.
> >
> | Extension | Scope |
> |---|---|
> | `trust-annotations` | The narrow data-classification taxonomy (`sensitive`, `untrusted`) + an open-ended `evidenceRef` pointer for richer, out-of-band evidence. |
> | `action-metadata` | Tool I/O + outcome contract (folds in @rreichel3's SEP-2061). |
> | `ifc-fides` | Information-flow control ([arXiv:2505.23643](https://arxiv.org/abs/2505.23643)) as **one profile** of `evidenceRef`, not a wire root — the public/private-repo confidentiality case, with github-mcp-server as an emitter example. |
> >
> Deliberately removed: `maliciousActivityHint` (the structural concerns raised
> here are unresolved) and session-level propagation rules.
> >
> This follows the same Standards-Track → Extensions-Track refactor pattern as
> SEP-2127 (#2893). This PR will eventually pivot to the `trust-annotations`
> piece itself, with the other schema-bearing pieces moving out into their own
> extensions. Everything is still in the incubation phase, so naming, design,
> and the choice of what to put forward as an extension are all open for
> discussion in the IG.

---

## For SEP-2061 (coordination note)

> @rreichel3 — splitting this out into an independent extension as discussed: https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1913#issuecomment-4675047154
45 changes: 45 additions & 0 deletions docs/open-questions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Open questions

Tracked here rather than in the spec drafts, so the drafts stay non-temporal.

## Cross-cutting

- **Where does the policy-enforcement engine live** across different user
universes (cross-org, cross-domain)? Engines work well within one universe;
cross-domain is the hard case. (IG 2026-05-28.)
- **Cross-domain integrity verification** — is asymmetric crypto for domain
identity in scope for a future extension, or out of scope entirely? CLI tools
remain a persistent gap for enforcing these constraints.
- **`evidenceRef.type` registry** — who curates the list of well-known profile
types, and how do we coordinate with attestation SEPs (e.g. SEP-2787) so
values don't collide?

## trust-annotations

- Is `sensitive` the right single coarse signal, or do we need the
`data-class.v1` profile from day one?
- Content-block-level vs. result-level attachment — does the draft need a
worked multi-result example before it's implementable?
- `list_changed`: confirmed response-level annotations don't participate; revisit
only if trust vocabulary ever attaches to tool definitions.

## action-metadata

- Coexistence vs. replacement of legacy `destructiveHint` / `readOnlyHint` /
`idempotentHint` / `openWorldHint`.
- Open strings vs. closed enums for `destination` / `source` / `sensitivity`.
- Does `requiresReview` need a machine-readable *reason* for good client UX?

## ifc-fides

- Inline `_meta.ifc` for low-friction adoption vs. always behind `evidenceRef`.
- GitHub Enterprise `internal` repo visibility → public/private/reader-set
mapping (audience is the whole org, broader than collaborators).

## Parked (SEP-1913 umbrella)

- **`maliciousActivityHint`** — if it returns, it is per-`ContentBlock` with
spans, driven by the host's own detection, not a server-attested boolean.
- **Session-level propagation rules** — escalation semantics and the
sequence-shape gap ("this was call N in a flagged sequence" has no response
annotation surface today).
Loading