# Model Context Protocol (MCP)

> Everruns is both an MCP server, exposing its agents and tools to external clients with OAuth 2.1, and an MCP client that registers remote servers as virtual capabilities.

Source: <https://everruns.com/docs/features/mcp/>

Everruns speaks the [Model Context Protocol](https://spec.modelcontextprotocol.io) on **both sides**: it exposes its own agents and tools as an MCP server, and it consumes remote MCP servers as agent capabilities.

## Everruns as an MCP server

Every Everruns deployment exposes an authenticated MCP endpoint at `/mcp` so external clients, Claude Desktop, Cursor, VS Code, or another agent, can discover and call your agents and tools over JSON-RPC. It is a standard product surface, with no deployment variable or organization feature toggle.

* **Transport**: JSON-RPC 2.0 over Streamable HTTP (`POST /mcp`). Protocol versions `2026-07-28`, `2025-06-18` and `2025-03-26` are supported.
* **Methods**: `initialize`, `server/discover`, `ping`, `tools/list`, `tools/call`, `resources/list`, `resources/templates/list`, `resources/read`; under `2026-07-28`, `skills/list`, `skills/get`, and `resources/directory/read`; and, for organizations that turn on MCP Events, `events/list`, `events/subscribe` and `events/unsubscribe`.
* **Auth**: MCP requests authenticate and resolve an organization before dispatch. OAuth 2.1 uses mandatory PKCE, and MCP access tokens are bound to the exact `/mcp` resource so they cannot be reused against the REST API. Unauthenticated requests fail with `401` and protected-resource discovery metadata is served at `/.well-known/oauth-protected-resource/mcp`.
* **Entity cards**: under protocol `2025-06-18`, tools like `agent_get_card` return a sandboxed `text/html` MCP App resource at the `ui://` scheme alongside a text summary, so MCP-Apps-aware hosts render rich cards while others fall back to text.

Routing is intentionally split: REST under `/api/*`, MCP OAuth under `/oauth/*`, and MCP JSON-RPC at `/mcp`.

### Skills for MCP clients

The endpoint serves public workflow guidance through the official [MCP Skills extension](https://modelcontextprotocol.io/extensions/skills/overview). With protocol `2026-07-28`, `server/discover` advertises `io.modelcontextprotocol/skills` with directory reading enabled. Use `skills/list` to discover complete entries or `skills/get` to look up a known `SKILL.md` URI directly, then read instructions and supporting files with `resources/read`.

| Skill                                       | Use it for                                                                                           |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `skill://everruns-mcp/SKILL.md`             | Finding agents, running sessions, inspecting results, and managing resources through MCP             |
| `skill://everruns-agent-authoring/SKILL.md` | Creating or revising agent definitions, selecting capabilities and harnesses, and verifying behavior |

Each entry preserves all authored frontmatter and includes every file’s URI, SHA-256 digest, and byte size. Supporting references resolve relative to the skill directory. `resources/directory/read` lists direct children of a directory, for example `skill://everruns-mcp`, without a trailing slash. Unknown skills, files, directories, and cursors return JSON-RPC `-32602`.

These files ship with the server and are identical for every organization. They use public cache hints, while organization data resources remain private. Requests still require MCP authentication. Organization-managed Skills registry entries, the Rust Framework skill, and repository contributor workflows are not published in this catalog or accessible through its skill resource reads.

Reading a resource does not itself activate a skill. A host supporting the extension loads it through its skill loader, checks the manifest and frontmatter, and applies its approval policy. Older clients can read a known skill URI as an ordinary resource but receive no Skills extension capability.

### In ChatGPT and Codex

`/mcp` is an [MCP App](https://github.com/modelcontextprotocol/ext-apps): hosts that render MCP Apps, including ChatGPT, Codex and Claude, show a live session view after `agent_run`, answer an agent’s questions in a form, approve or decline a pending action, and open an Everruns panel from the sidebar. Hosts that do not render apps get the same tools as plain text.

### Session events (experimental)

With the **MCP Events** feature flag turned on for an organization, an MCP client can subscribe to webhooks for `session.completed`, `session.failed` and `session.input_required`, filtered by agent or session. Callbacks must be public HTTPS URLs and are verified before the first event. Deliveries are signed per [Standard Webhooks](https://www.standardwebhooks.com/) and carry identifiers and state, not message content: read the session with `session_get_status`.

## Everruns as an MCP client

People can also add MCP servers for themselves; agents with the User MCP Servers capability use them while that person chats. See [User MCP Servers](https://everruns.com/docs/features/user-mcp-servers/).

A server the agent adds for one conversation only ([`"scope": "chat"`](https://everruns.com/docs/capabilities/user-mcp-servers/#this-conversation-only)) shows under the **MCP** button in that conversation’s header, where you can see whether you have signed in and remove it; its tools leave from the next message. Over the API: `GET /v1/sessions/{session_id}/mcp-servers` and `DELETE /v1/sessions/{session_id}/mcp-servers/{name}`.

Register a remote MCP server and its tools appear as a **virtual capability**: auto-discovered, namespaced, and executed alongside built-in capabilities. No code changes are needed to give an agent new tools.

* **Org-managed servers**: organization-scoped `McpServer` records connect over remote HTTP (Streamable HTTP). `stdio` is rejected by the hosted control plane and is only available to single-tenant runtime/CLI hosts. People who manage MCP servers keep these presets in **Settings > Organization > MCP catalog**; a preset does nothing until an agent or a person adds it. MCP sign-ins you authorized for agent servers that act as you are listed in **Settings > My agent experience**.
* **Scoped `mcpServers`**: harnesses, agents, and sessions can embed remote MCP config directly (the remote-server subset of `.mcp.json`) for session-local or agent-local wiring without creating an org-global record.
* **Restricted egress**: on deployments that limit where requests that send data may go (such as Everruns Cloud), MCP traffic only reaches approved services. Once a platform administrator allows it, org admins can add their own MCP hosts under **Settings > Organization > Outbound allowlist**.
* **Tool naming**: discovered tools are namespaced per server so they never collide with built-in capabilities.
* **Protocol compatibility**: the client negotiates the MCP protocol era per server. By default (`auto`) it issues a session-less `2026-07-28` request and transparently falls back to the stateful `initialize` handshake (`2025-11-25`, then `2025-06-18` / `2025-03-26`) for servers that require it, caching the verdict per server. Set the protocol mode to `legacy`, `stable`, or `rc` to pin a specific era and skip negotiation. No setting is needed for the common case.

### Reading a server’s resources

Many MCP servers publish context as [resources](https://modelcontextprotocol.io/specification/2025-11-25/server/resources): files, schemas, documents. Whenever a conversation has an MCP server attached, the agent gets two read-only tools:

* `list_mcp_resources` lists a server’s resources and resource templates, one page at a time.
* `read_mcp_resource` reads one resource by URI, including a URI the agent filled in from a template.

Text is returned to the agent as is, images arrive as images, and other binary content is saved to the session’s files (or only described, where the session has no files) instead of being pasted into the conversation. Content a server marks as meant only for the user stays out of the agent’s context. Resources are read with the same sign-in as the server’s tools, and only servers attached to the conversation can be reached. A server that publishes no resources says so when asked.

### Who a server acts as

Each MCP server attached to an agent says whose sign-in its calls use (`actsAs`, or **Who should this server act as?** on the agent’s **MCP servers** sheet):

| `actsAs`          | On the sheet                                       | Calls run as                                                                 |
| ----------------- | -------------------------------------------------- | ---------------------------------------------------------------------------- |
| `none`            | No identity                                        | Nobody: the server needs no sign-in                                          |
| `service`         | Service identity                                   | The agent’s own account, signed in once by someone who manages MCP servers   |
| `user`            | Invoking user                                      | The person chatting, with their own sign-in; nothing when nobody is chatting |
| `user_or_service` | Each user, or the agent if they have not connected | The person chatting when they have signed in, otherwise the agent’s account  |

`user_or_service` is never chosen for you. Unattended runs (schedules, triggers) always use the agent’s account, since nobody is chatting. Every MCP tool call records which account it used in its `tool.completed` event (`acted_as`: `user` or `service`), so a fallback to the agent is visible.

When someone adds an OAuth server to the catalog, Everruns checks right away that it can reach the server’s sign-in service and register with it. The catalog row then says **Ready to connect**, or why not, for example “Can’t reach mcp.linear.app: this host is not on the allowed network list”. Saving works either way; **Check again** re-runs the check after you change the network list.

An OAuth server from the catalog can be attached before anyone has signed in to it. The first **Authorize** or **Connect** registers Everruns with the server and signs in; until then the attachment shows **Connection required** and its tools are unavailable. If a sign-in fails, you return to the page you started from with the reason, for example that the server’s host is not on the organization’s allowed network list.

An agent with a server acting as `user` or `user_or_service` gets the `connect_mcp_server` tool, so it can show a **Connect** card in chat before a call fails.

### Connecting from chat

When a call needs a sign-in that is missing, the chat pauses on a **Connect** card (or, for the agent’s own account, an **Authorize** card for someone who manages MCP servers and **Ask an admin** for everyone else). Set `connectInChat` on the attachment (**Ask to connect in chat** on the agent’s **MCP servers** sheet) to choose:

| `connectInChat` | A missing sign-in                                                                                                                                                                                    |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ask` (default) | Pauses the chat with the card                                                                                                                                                                        |
| `never`         | Fails the call with an error naming the server and its settings link (`/settings/connections` for the person’s own sign-in, the agent’s **MCP servers** sheet for the agent’s), and the turn goes on |

`never` suits agents behind channels that cannot show a card, such as a chat bridge. `connect_mcp_server` follows it too and returns the same link instead of a card.

```json
{
  "mcpServers": {
    "github": { "use": "catalog:github", "actsAs": "user", "connectInChat": "never" }
  }
}
```

### Loading tools on demand

Every server’s tools are normally listed at the start of each turn, which costs one `tools/list` round trip per server. Set `deferred: true` on an attachment (**Load tools on demand** on the agent’s **MCP servers** sheet) to skip that: the agent sees one line for the server, `mcp_<name>` with its name and description, and loads the server’s tools when it needs them, by finding it with `tool_search` or calling that line. The tools are callable from the agent’s next step and stay loaded for the rest of the conversation. Off is the default, so existing agents are unchanged. A person’s own servers ([User MCP servers](https://everruns.com/docs/capabilities/user-mcp-servers/)) load on demand by default; a person can turn that off for one of their servers with its **Load tools on demand** switch in **Settings > My MCP servers**.

```json
{
  "mcpServers": {
    "linear": { "use": "catalog:linear", "actsAs": "user", "deferred": true }
  }
}
```

A catalog entry can take the agent’s account from an existing connection instead of its own sign-in (`service_connection_provider`, **Agent credential** in the catalog form). The seeded `github` entry (`https://api.githubcopilot.com/mcp/`) uses the agent’s GitHub App, so an agent with a GitHub App needs no second GitHub login. A connection is only accepted for servers on its provider’s own hosts, so its tokens cannot be sent anywhere else.

GitHub’s MCP server accepts the App’s installation token, but that token acts as the App, not a person. It reaches only the repositories the App is installed on, with the App’s permissions, and tools about a person (`get_me`, notifications, starred repositories, “my” issues and pull requests) fail. For those, attach the server acting as `user` so the person signs in.

### Waking an agent on a server’s events (experimental)

With the **MCP Events** flag on, an agent can also subscribe to events that one of its own MCP servers publishes, such as a tracker announcing new issues. Create an agent trigger with `trigger_type: "mcp_event"`, the attachment’s name in `mcp_server`, the event name from the server’s `events/list` in `mcp_event`, and any subscription arguments in `mcp_event_arguments`:

```bash
curl -X POST "$EVERRUNS_API/v1/agents/$AGENT_ID/triggers" \
  -H "Content-Type: application/json" \
  -d '{
    "trigger_type": "mcp_event",
    "mcp_server": "tracker",
    "mcp_event": "issue.created",
    "mcp_event_arguments": {"team": "eng"},
    "message": "Triage {{payload.issue.title}}"
  }'
```

Everruns subscribes with the agent’s credential for that attachment (its sign-in to the server, or the connection a catalog entry such as `github` names), a signing secret it generates, and a callback URL of its own; the server must accept webhook delivery. Each signed event starts a run with the event’s `data` as `{{payload}}`. Subscriptions are renewed before they expire and cancelled when the trigger is disabled or deleted. The attachment must act as the agent (`service` or `user_or_service`), not only as the calling user, since a trigger runs as the agent.

## Which tools ask before they run

In the normal approval mode, a tool that can change something asks a person before it runs. Everruns can’t see inside a remote tool, so most MCP tools ask by default, even ones that only read. You can tell Everruns what each tool does:

* **Read only**: the tool only looks things up. It never asks.
* **Changes**: the tool changes or sends something. It always asks.

Your label wins over what the server says about its own tools, and it stays when the server’s tool list changes. A tool with no label follows what the server says about it.

In the app, open **Settings > MCP catalog** and click **Tools** on a server. Each tool shows its description, what the server says about it, and a choice: **Default**, **Read only**, or **Changes things**.

**Suggest labels** asks a decision model to judge every tool that has no label yet. It only fills in a suggestion, such as “Suggested: read only”. Nothing changes until a person picks a choice or clicks **Use suggestion**.

The deployment’s decision model judges, unless your organization set **System decisions** to **This organization’s model**: then your organization’s default decision model judges, on your provider account. If that model is not usable, the button reports an error rather than using the deployment’s.

List a server’s tools with their labels, then set or clear one:

```bash
curl "$EVERRUNS_API/v1/mcp-servers/mcp_01h9/tools"
curl -X PUT "$EVERRUNS_API/v1/mcp-servers/mcp_01h9/tools/search_docs/label" \
  -H "Content-Type: application/json" -d '{"label": "read_only"}'
```

Send `{"label": "changes"}` to always ask, or `{"label": null}` to remove the label. Setting a label needs the same permission as editing the server, and it removes the tool’s suggestion. To get suggestions, which come back with the tool list:

```bash
curl -X POST "$EVERRUNS_API/v1/mcp-servers/mcp_01h9/tools/suggest-labels"
```

Labels work on the other places an MCP server can live too:

* **An agent’s or harness’s own server** (one added by URL): put the labels in the server’s `tool_labels`, keyed by the tool’s own name. They win over a catalog server’s saved labels when the entry uses one.

  ```json
  "mcpServers": {
    "notes": {
      "url": "https://notes.example.com/mcp",
      "tool_labels": { "search": "read_only", "publish": "changes" }
    }
  }
  ```

* **Your own server** (one you added by URL under **My MCP servers**): click **Tools** on it. Everruns asks the server for its tools with your sign-in. A server you added from the catalog uses the catalog’s labels.

Servers added during a conversation never carry labels, because the agent can add them itself and a label only ever lets a tool run without asking.

## When a tool needs a person

Some MCP tools cannot finish without a human: a payment to authorize, an API key to paste, a consent screen to click. Under protocol `2026-07-28` the server hands back a URL instead of asking for the value, and Everruns holds the turn until someone answers. See [URL mode elicitation](https://everruns.com/docs/features/mcp-url-elicitation/).

A server can also ask the person a few structured questions (form mode elicitation), such as which environment to deploy to. This is off by default: set the server’s **Elicitation** setting (`elicitation_policy`) to `url_and_form` to allow it. The questions appear in the conversation marked as coming from that server, and the answer goes back to the server when the tool runs again. Everruns refuses questions that ask for a password or key, and declines on the person’s behalf if nobody answers in time. `none` stops a server eliciting at all.

## Use Everruns from your AI tools

To give Claude Code, Codex, Cursor or Gemini CLI the MCP server plus skills for building, debugging and shipping agents, install the [`everruns` plugin](https://github.com/everruns/plugins); see [Use in AI tools](https://everruns.com/docs/getting-started/use-in-ai-tools/).

## Related

* [URL mode elicitation](https://everruns.com/docs/features/mcp-url-elicitation/), tool calls that need a person
* [Capabilities](https://everruns.com/docs/features/capabilities/), how virtual capabilities fit the capability system
* [Slack Integration](https://everruns.com/docs/capabilities/slack/), publishing an Agent through a messaging endpoint