> ## Documentation Index
> Fetch the complete documentation index at: https://agentclientprotocol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Extensibility

> Adding custom data and capabilities

The Agent Client Protocol provides built-in extension mechanisms that allow implementations to add custom functionality while maintaining compatibility with the core protocol. These mechanisms ensure that Agents and Clients can innovate without breaking interoperability.

## Experimental Features and Negotiation

**Stability**, **support**, and **forward compatibility** are separate:

* Stability describes whether a feature is part of the baseline schema or is an experimental addition that may change or be removed.
* Support describes whether a peer implements the feature's behavior, as advertised by its capability or another explicitly documented negotiation mechanism.
* Forward compatibility describes whether a receiver can safely accept a field or variant without implementing its behavior.

Negotiating `protocolVersion: 2` selects the v2 protocol, not all experimental
features in `schema/v2/schema.unstable.json`. There is no connection-wide
"unstable schema" flag. Implementations **MUST NOT** infer peer support from
their own schema selection, generated types, or local feature flags.

### When a Capability Is Required

Each feature defines its negotiation requirements, whether stable or experimental:

* **Optional operations requiring peer participation** need an advertised capability or another explicitly documented negotiation mechanism. Callers **MUST** follow that feature's requirements; an omitted or `null` support marker means unsupported.
* **Informational additions with a safe fallback** may be sent without a capability when the feature explicitly permits it. A receiver may ignore or generically display them. Senders **MUST NOT** depend on feature-specific presentation, acknowledgement, or action.
* **Local feature flags** control implementation and rollout. They neither advertise peer support nor replace a required capability.

For example:

| Feature | Negotiation and receiver behavior |
| - | - |
| [Provider configuration](/protocol/v2/draft/initialization#agent-capabilities) (experimental) | The Agent advertises `capabilities.providers`; Clients must not call provider configuration methods without it. |
| [Notices](/protocol/v2/draft/prompt-lifecycle#session-notices) and [compaction](/protocol/v2/draft/prompt-lifecycle#session-compaction) | No Client capability is required in v2. Clients without feature-specific handling may preserve, ignore, or generically display the updates. |
| [Markdown and file-backed plans](/protocol/v2/draft/agent-plan#unstable-plan-operations) (experimental) | No Client capability is required in v2. Clients without these plan representations use the unknown plan-content fallback; sending one does not establish that it will be rendered. |
| [End-turn token usage](/protocol/v2/draft/prompt-lifecycle#end-turn-token-usage-unstable) (experimental) | Optional `usage` on an idle `state_update`, not on the prompt response. No capability is required; Clients may ignore it. |

These rules are specific to v2. Features with capability gates in v1 retain
those gates on v1 connections.

Experimental schema revisions may disagree about a feature's shape or semantics.
A capability advertises the behavior defined for that feature, not compatibility
with every revision of the unstable schema. Experiments that require matching
revisions should define feature-specific revision negotiation rather than rely
on a global unstable-schema flag.

### Validation

Receivers **MUST** accept unknown fields and genuinely unknown discriminator
values where their schema permits them. Closed discriminators remain closed.
For open tagged unions, receivers validate the fallback's required envelope
fields, then [preserve unknown payloads or use safe generic handling](#enum-and-tagged-union-variants).
Accepting an unknown variant does not advertise support for its behavior.

A malformed value for a discriminator recognized by the receiver **MUST NOT**
fall through to the unknown-variant fallback. Validate recognized variants
against their defined shapes, honoring documented field-level tolerance (for
example, discarding malformed optional display metadata). Forward compatibility
does not make operational request parameters permissive.

Payload validation and capability checks are separate. A schema-valid request
is not necessarily supported or permitted on the connection.

## The `_meta` Field

Protocol object types that define a `_meta` field can use it to attach custom information. This includes requests, responses, notifications, and nested object types such as content blocks, tool calls, plan entries, and capability objects. Primitive types and object types that do not define `_meta` cannot carry it.

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "session/prompt",
  "params": {
    "sessionId": "sess_abc123def456",
    "prompt": [
      {
        "type": "text",
        "text": "Hello, world!"
      }
    ],
    "_meta": {
      "traceparent": "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01",
      "zed.dev/debugMode": true
    }
  }
}
```

Clients may propagate fields to the agent for correlation purposes, such as `requestId`. The following root-level keys in `_meta` **SHOULD** be reserved for [W3C trace context](https://www.w3.org/TR/trace-context/) to guarantee interop with existing MCP implementations and OpenTelemetry tooling:

* `traceparent`
* `tracestate`
* `baggage`

Implementations **MUST NOT** add any custom fields at the root of a type that's part of the specification. All possible names are reserved for future protocol versions.

## Unknown Object Fields

Receivers **MUST** ignore unrecognized properties of protocol-defined objects, including properties nested within capability objects. An otherwise valid message **MUST NOT** be rejected solely because it contains unrecognized properties. Ignoring a property means not assigning protocol behavior to it. It does not imply support for the feature it describes.

This rule does not relax validation of known properties or change their documented handling of malformed values. Unknown enum values, discriminator values, and method names follow their own rules. They are not unknown object fields. A malformed value for a known discriminator **MUST NOT** be treated as an unknown variant.

Ignoring an unknown property means not interpreting it. Implementations are not required to remove it from the message.

## Extension Methods

The protocol reserves any method name starting with an underscore (`_`) for custom extensions. This allows implementations to add new functionality without the risk of conflicting with future protocol versions.

Extension methods follow standard [JSON-RPC 2.0](https://www.jsonrpc.org/specification) semantics:

* **[Requests](https://www.jsonrpc.org/specification#request_object)** - Include an `id` field and expect a response
* **[Notifications](https://www.jsonrpc.org/specification#notification)** - Omit the `id` field and are one-way

### Custom Requests

In addition to the requests specified by the protocol, implementations **MAY** expose and call custom JSON-RPC requests as long as their name starts with an underscore (`_`).

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "_zed.dev/workspace/buffers",
  "params": {
    "language": "rust"
  }
}
```

Upon receiving a custom request, implementations **MUST** respond accordingly with the provided `id`:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "buffers": [
      { "id": 0, "path": "/home/user/project/src/main.rs" },
      { "id": 1, "path": "/home/user/project/src/editor.rs" }
    ]
  }
}
```

If the receiving end doesn't recognize the custom method name, it should respond with the standard "Method not found" error:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "Method not found"
  }
}
```

To avoid such cases, extensions **SHOULD** advertise their [custom capabilities](#advertising-custom-capabilities) so that callers can check their availability first and adapt their behavior or interface accordingly.

### Custom Notifications

Custom notifications are regular JSON-RPC notifications that start with an underscore (`_`). Like all notifications, they omit the `id` field:

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "_zed.dev/file_opened",
  "params": {
    "path": "/home/user/project/src/editor.rs"
  }
}
```

Unlike with custom requests, implementations **SHOULD** ignore unrecognized notifications.

## Enum and Tagged-Union Variants

ACP also reserves `_`-prefixed values for implementation-specific extensions in enum-like fields and tagged unions that define a custom or future fallback.

* Values beginning with `_` are reserved for implementation-specific extensions.
* Unknown values that do not begin with `_` are reserved for future ACP variants.
* Extensions **MUST NOT** define custom non-underscore values.
* Implementations **MUST NOT** treat unknown non-underscore values as custom extensions.

This rule applies only where the schema defines a fallback path. Closed discriminators can still reject unknown values when the receiver cannot safely continue without understanding the variant.

When storing, replaying, proxying, or forwarding data, implementations **SHOULD** preserve unknown values and any raw tagged-union payloads. When displaying an unknown value, implementations **SHOULD** fall back to generic UI behavior that matches the field's purpose.

## Advertising Custom Capabilities

Implementations **SHOULD** advertise support for extensions and their methods using namespaced entries in capability objects' `_meta` fields:

* Use `capabilities._meta` for independent extension surfaces or extensions that apply across capability groups.
* Use a nested capability object's `_meta`, where that object defines one, for extensions scoped to that capability. For example, an extension to session prompting belongs in `capabilities.session.prompt._meta`.
* Creating a standard capability object to carry `_meta` still advertises the standard support associated with that object. An Agent **MUST NOT** send `capabilities.session: { "_meta": ... }` unless it supports all seven baseline session methods.

Custom capability names **MUST NOT** be added as properties directly on either the root capability object or nested protocol-defined capability objects. Use the same metadata location and namespaced key on both sides of an extension's negotiation.

For example, an Agent can advertise an independent workspace extension without advertising session support:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "protocolVersion": 2,
    "capabilities": {
      "_meta": {
        "zed.dev": {
          "workspace": true,
          "fileNotifications": true
        }
      }
    },
    "info": {
      "name": "my-agent",
      "title": "My Agent",
      "version": "1.0.0"
    }
  }
}
```

This allows implementations to negotiate custom features during initialization without breaking compatibility with standard Clients and Agents.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.