A proposal, not a standard — nothing here is implemented yet. Open for discussion →

Semantic capability contracts

MCP standardised how tools are called. This is a proposal for what they mean.

A Class Profile names a capability — the job, not the vendor — and fixes its vocabulary, its optional parts, and what you lose when one of them is missing. An agent that has learned the job once can then use an implementation it has never seen, including one written later.

01 · The problem

Three services do the same job. None of them agrees what to call it.

Ask an agent to put a meeting in the calendar. Your organisation has three, all speaking fluent MCP. Here is the same intent, as each one wants to hear it.

Service A

{
  "summary": "Design review",
  "start": { "dateTime": "…" },
  "end":   { "dateTime": "…" }
}

Calls the title summary.

Service B

{
  "subject": "Design review",
  "startTime": "…",
  "endTime": "…"
}

Calls it subject, and flattens the times.

Service C

{
  "name": "Design review",
  "start_date": "…",
  "end_date": "…"
}

Calls it name, and uses snake case.

Now the expensive part. Almost everywhere except one major calendar API, a summary is an abstract — the short version of a longer text. So an agent fluent in that dialect, writing to a service that uses the other reading, puts the meeting title into the description field.

The event is created. Nothing fails. Nobody is told.

This is not a calendar problem. Across 300 of the most-used MCP listings, something reference-shaped appears under 894 distinct spellings, and not one of 9,390 declared tools says whether calling it changes anything. See the measurements →

02 · What is proposed

Name the job once, in the open, and freeze what it means.

Not a new protocol — MCP already carries the calls. A Class Profile is an agreement layered on top of it about what a capability is.

The job, not the vendor

A profile names a capability by what it does for someone. operator is a job; browser is only where that job happens, so it is an optional part rather than a category of its own.

A small mandatory floor

The handful of operations that make something a member of the capability at all. If a real implementation could reasonably lack it, it does not belong in the floor.

Optional parts that declare their absence

Everything beyond the floor is declared by exact version and carries one plain sentence: what you lose without it. An agent knows before it calls, not by failing.

Meaning that never moves

A published contract means exactly one thing forever. A vocabulary that drifts cannot be learned by anyone, because what was learned stops being true.

03 · How it works

Three levels, and a claim that has to be earned.

The same three levels apply to any capability. An implementation declares exactly which parts it has.
LevelWhat it meansWho has it
Core baselineMandatory. A thing that cannot do it is not a member of the capability. Small on purpose, and all-or-nothing.Everyone
FacetAn optional, job-shaped module. Declared by exact version, never assumed, and it states what its absence costs.Some
Vendor memberSomething genuinely yours. Stays visible instead of being flattened away, without entering anyone else’s floor.One

Levels of universality, not of quality. A vendor member is not a feature that failed to become standard — it is how a real difference stays usable, the way a 3D display reports something only its own driver understands.

Route on meaning, not spelling

Hosts rename tools — prefixing, sanitising, replacing separators. Routing on the displayed name breaks the first time that happens.

Semantic identity
org.classprofiles.calendar/create_event@1 — canonical, frozen, what routing and tests key on
Preferred spelling
calendar.create_event — presentation
Actual tool name
google_calendar_create — whatever the host shows

Conformance means one thing

Passed this exact suite, at this exact version. Nothing else counts, and behaviour is checked rather than asserted:

  • A read-only claim is checked by taking a snapshot and showing nothing moved.
  • An idempotent claim is checked by calling twice.
  • MCP itself now tells clients to treat tool annotations as untrusted. This is how one earns belief instead of asking for it.

04 · Two capabilities

A calendar and a browser have nothing in common. The shape fits both.

One example proves nothing about a framework, so there are two — chosen to be as unlike each other as possible. The way a display and a mass-storage device share no purpose whatsoever, yet plug into the same host and work.

org.classprofiles.calendar

Calendar

Manage the entries on a calendar I control, and tell me when I am free.

Without a shared contract

The title is summary, name, or subject. The time range has seven spellings. An agent relearns all of it per vendor, and gets it silently wrong across dialects.

Floor · 6 operations

list_events get_event create_event update_event cancel_event find_free_time

calendar.create_event
{ "title": "Design review",
  "start": "2026-02-26T15:00:00-05:00",
  "end":   "2026-02-26T15:45:00-05:00",
  "request_key": "k_7ab3" }

No ceremony. Omitted optionals take declared defaults, and request_key means a re-issued call after a dropped stream cannot book twice.

Optional · 5 facets

invitations recurrence reminders rsvp tombstones

A personal calendar cannot invite anyone. A backend that hard-deletes is still a calendar. Both stay outside the floor and say so.

What that buys

One manual for every calendar, including ones not written yet. Absent features are known before calling, not discovered by failing halfway through a booking.

Descriptor · Fixtures · How to operate it

org.classprofiles.operator

Operator

Operate a surface on the user’s behalf — a browser, a desktop, a terminal.

Without a shared contract

Three independently built browser servers expose the same five jobs under three vocabularies, at roughly 25 to 50 tools each. browser_snapshot, take_snapshot, read_page — all the same act.

Floor · 4 operations

list_surfaces perceive act settle

Navigation is not in the floor: a desktop has nowhere to navigate to and a terminal has no location at all.

operator.act
{ "surface_id": "sfc_2ab9", "target": "e47", "action": "press" }

→ { "changed": true, "readiness": "settled" }

The result is the point: you know the press landed without a second call. When nothing happens you are told — "changed": false — rather than left to assume.

Optional · 3 facets

browser desktop screenshot

For agents that control a browser, and for agents that control a desktop. The surface type is a facet, not the capability — nobody’s job is “browser”; the job is having something done, using one.

operator.navigate      operator/browser@1
{ "surface_id": "sfc_2ab9", "url": "https://example.org" }

operator.focus_app     operator/desktop@1
{ "surface_id": "sfc_7c10", "application": "Text Editor" }

What that buys

Learn the job once and drive a browser, a desktop, or a terminal. Today an implementer buys familiarity by copying another vendor’s tool names — which works against exactly one vendor, and breaks quietly when they rename something.

Descriptor · Fixtures · How to operate it

Almost nothing in common at the semantic level — one touches records you own, the other a live surface you do not control — and yet both describe the same way. The shared shape is the proposal; the two contracts are evidence it is not domain-specific.

05 · See it run

The same two calls, against two different backends

One speaks the contract directly. The other is a legacy API behind a mapping. The requests and the compared outcome are identical; only the traces differ. Both are local simulations — no servers, no network.

Scenario
Find 45 minutes Thursday afternoon and book Design review.

Fixture date: 2026-02-26 · America/New_York

Profile side

Requests supplied to either simulation

Fixed input
  1. 01 calendar.find_free_time
    {
      "duration_minutes": 45,
      "window_start": "2026-02-26T13:00:00-05:00",
      "window_end": "2026-02-26T17:00:00-05:00",
      "max_results": 3
    }
  2. 02 calendar.create_event
    {
      "title": "Design review",
      "start": "2026-02-26T15:00:00-05:00",
      "end": "2026-02-26T15:45:00-05:00",
      "timezone": "America/New_York"
    }
Implementation side

Native simulation

Speaks the profile directly

Display a backend trace
  1. 01 calendar.find_free_time direct
    Arguments and result
    Arguments
    { "duration_minutes": 45, "window_start": "2026-02-26T13:00:00-05:00", "window_end": "2026-02-26T17:00:00-05:00", "max_results": 3 }
    Result
    { "slots": [{ "start": "2026-02-26T15:00:00-05:00", "end": "2026-02-26T17:00:00-05:00" }] }
  2. 02 calendar.create_event direct
    Arguments and result
    Arguments
    { "title": "Design review", "start": "2026-02-26T15:00:00-05:00", "end": "2026-02-26T15:45:00-05:00", "timezone": "America/New_York" }
    Result
    { "title": "Design review", "start": "2026-02-26T15:00:00-05:00", "end": "2026-02-26T15:45:00-05:00", "timezone": "America/New_York", "state": "confirmed" }

Native simulation ready.

Compared result

Thursday, February 26, 2026

America/New_York

The comparison includes free intervals plus event title, start, end, timezone, and state. Opaque backend IDs are intentionally excluded.

06 · Adopting it

Existing servers do not have to change.

This is the part that decides whether any of it is usable.

Someone else can do it for you

A projection presents a profile’s operations backed by an unmodified upstream server. The mapping is written once, reviewed, frozen, pinned, and behaviourally tested. A host can do that today without waiting for a vendor — and the vendor can later adopt the very same artifact.

A projection passes the identical suite as a direct implementation. Native and projected record provenance, never grade.

Losses are declared, never silent

Every upstream tool in the mapped domain gets exactly one disposition: mapped, approximated with a readable note, reachable only by passthrough, or unmapped. Silent loss is a specification violation.

The seam shows. That is the intent, not a compromise.

And the benefit arrives even for clients that never heard of this

A conformant server is, to any ordinary MCP client, simply one whose surface is unusually hard to misread: a short description, a shallow schema, defaults that are actually applied, and annotations that are true because they were checked. Nobody else has to adopt anything for that to be worth doing — which is why one publisher adopting is enough to pay for itself.

Map an existing server · Implement it directly · Read the concepts

Honest state

Where this is unfinished

Discussion is more useful when it points at a contract field or a fixture.

Real today

  • Two reviewable contracts — Calendar and Operator — with 31 fixture scenarios pinning their meaning.
  • Two local simulations — one direct, one projected — producing the same compared outcome.
  • A 300-listing discovery study with its measurements published.

Not yet

  • No two independent servers have passed the same suite. That is the empirical crux.
  • No official runner, passing claim, or receipt exists.
  • Neither contract has been implemented by anyone. They are reviewable, not proven.
  • Whether the shape generalises past these two examples is untested.
  1. 01

    Is a floor of six operations right for a calendar — too big, too small, or wrong at the edges?

  2. 02

    Which result fields should count when two implementations are compared, and which stay backend-specific?

  3. 03

    Does a service you maintain do one of these jobs in a way the proposed floor cannot express?

  4. 04

    Is there prior art that makes part of this unnecessary? That would be a good outcome, not a bad one.