Service A
{
"summary": "Design review",
"start": { "dateTime": "…" },
"end": { "dateTime": "…" }
}
Calls the title summary.
A proposal, not a standard — nothing here is implemented yet. Open for discussion →
Skip to contentSemantic capability contracts
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
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.
{
"summary": "Design review",
"start": { "dateTime": "…" },
"end": { "dateTime": "…" }
}
Calls the title summary.
{
"subject": "Design review",
"startTime": "…",
"endTime": "…"
}
Calls it subject, and flattens the times.
{
"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
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.
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.
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.
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.
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
| Level | What it means | Who has it |
|---|---|---|
| Core baseline | Mandatory. A thing that cannot do it is not a member of the capability. Small on purpose, and all-or-nothing. | Everyone |
| Facet | An optional, job-shaped module. Declared by exact version, never assumed, and it states what its absence costs. | Some |
| Vendor member | Something 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.
Hosts rename tools — prefixing, sanitising, replacing separators. Routing on the displayed name breaks the first time that happens.
org.classprofiles.calendar/create_event@1 — canonical, frozen, what routing and tests key oncalendar.create_event — presentationgoogle_calendar_create — whatever the host showsPassed this exact suite, at this exact version. Nothing else counts, and behaviour is checked rather than asserted:
04 · Two capabilities
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
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.
org.classprofiles.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.
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
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.
Find 45 minutes Thursday afternoon and book Design review.
Fixture date: 2026-02-26 · America/New_York
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
}
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"
}
Speaks the profile directly
calendar.find_free_time
direct
{ "duration_minutes": 45, "window_start": "2026-02-26T13:00:00-05:00", "window_end": "2026-02-26T17:00:00-05:00", "max_results": 3 }{ "slots": [{ "start": "2026-02-26T15:00:00-05:00", "end": "2026-02-26T17:00:00-05:00" }] }calendar.create_event
direct
{ "title": "Design review", "start": "2026-02-26T15:00:00-05:00", "end": "2026-02-26T15:45:00-05:00", "timezone": "America/New_York" }{ "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" }The comparison includes free intervals plus event title, start, end, timezone, and state. Opaque backend IDs are intentionally excluded.
06 · Adopting it
This is the part that decides whether any of it is usable.
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.
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.
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
Discussion is more useful when it points at a contract field or a fixture.
Is a floor of six operations right for a calendar — too big, too small, or wrong at the edges?
Which result fields should count when two implementations are compared, and which stay backend-specific?
Does a service you maintain do one of these jobs in a way the proposed floor cannot express?
Is there prior art that makes part of this unnecessary? That would be a good outcome, not a bad one.