Docs/Lanes Link/Under the Hood/Capabilities

Capabilities

Why each capability is a tool, a resource, or a prompt, where its list comes from, and what that decides about what can be checked.

Every provider page says what that connection can do. This page is the layer underneath: why a capability takes the shape it does, and where the list of them comes from.

If you only want to know what an agent can reach, you do not need this page.

Tool, resource, or prompt

Three MCP primitives, decided per capability rather than per provider:

  • A tool is an action, or a query whose answer depends on its arguments. Searching mail is a tool, because the result is a function of the query, not of an address.
  • A resource is read-oriented context at a stable address. memory://entry/{id} is a resource; it is a function of its URI alone, which is why it has nowhere to put routing arguments.
  • A prompt is a procedure a person selects. Every skill is a prompt, and that is what stops an agent choosing one on your behalf.

Enumeration is always a query rather than a document, so listing mailboxes, labels, or calendars is a tool everywhere.

What redaction is for

Every invocation is recorded, allowed or refused. The question each provider answers is which arguments are identifiers and which are content, because an audit log that reproduced the content would be a second copy of the thing it was meant to make accountable.

The rule across every provider is the same: keep the shape, withhold the words. What each one keeps is on its own page, and the audit log has the reasoning that applies everywhere.

Where a capability list comes from

Three sources, and which one a provider uses decides what can be checked.

A vendored OpenAPI document. Google, Reddit, Discord, and bunq. The committed copy is what stops a breaking change upstream becoming a provider that stops working, and it makes the surface reviewable in a diff. Reddit's is hand-authored, because Reddit publishes no OpenAPI document at all; it is still a document rather than code, so the operations become capabilities mechanically.

The vendored list is the security boundary, not a convenience. connect writes one rule per provider, and policy has nothing between a whole provider and one exact name. Discord is the clearest case: twenty operations out of 242, with bulk_delete_messages and every moderation, role, invite, and guild-settings endpoint excluded, and a test that pins the list so a spec refresh cannot widen it quietly.

The vendor's own MCP server. GitHub, Slack, Notion, Linear, and most of the catalogue. Capabilities are discovered at connect time, so the tool list is theirs.

That has a cost worth stating rather than leaving to be discovered: nothing in the codebase can check the argument names against the vendor's. If GitHub renames an argument, the value is withheld and the log reads exactly as it does when redaction is working. lanes link doctor reporting capability drift is the signal that the list wants re-reading.

Authored in the codebase. Rare, and only where a document cannot express the thing. gmail.send_message is the example: assembling a MIME message with attachments resolved by reference is not something an OpenAPI description can describe.

Why scopes are asked for narrowly

A scope on a consent screen that no tool can spend is a grant asked for and never noticed, so each provider asks for the narrowest set that makes its capabilities work, and a scope that reaches further than the rest is marked broad and needs an explicit yes at connect time.

Which scopes a provider asks for, and which it refuses, is on that provider's page. Scopes and permissions is how you change either.

Two places a credential reaches the model

Both are recorded as NOT-GUARANTEED rows in the security model rather than glossed over, and both are accepted because the alternative is not the same capability made safe but the capability not existing:

  • Discord's create_webhook and list_channel_webhooks return the webhook's token in their response. A webhook token is standalone: anybody holding it posts to that channel. It is bounded to one channel, with no read access.
  • A pasted token, for Slack or GitHub or Discord, is the credential itself rather than a means of obtaining one, so rotating it is manual and what it can do cannot be read back.

The example provider

No external service, no credentials, no browser. It ships as the provider SDK reference and as the way to exercise connection isolation without any accounts, and it is a built-in in miniature.

Its redaction is the pattern in one line: echo records its message, because the message is the whole payload; set_note and get_note record the key and never the value. A provider handling real correspondence would record neither.

example.set_note and example.delete_note sit in the write bundle, which is not granted by default, so a fresh profile can read and echo but not modify. That is the smallest demonstration that bundles do something.


Next: the security model for the guarantee table, or Connectivity coverage for what the two closed lists reach.