Common Types
Cross-cutting type definitions shared across every channel of the Agent Host Protocol — primitive aliases, action envelopes, base command shapes, the cross-channel auth/required notification, and the JSON-RPC wire types.
JSON Schema: state.schema.json
State Types
URI
A URI string (e.g. ahp-root:// or ahp-session:/<uuid>).
string
StringOrMarkdown
A string that may optionally be rendered as Markdown.
- A plain
stringis rendered as-is (no Markdown processing). - An object with
{ markdown: string }is rendered with Markdown formatting.
string | { markdown: string }
Icon
An optionally-sized icon that can be displayed in a user interface.
| Field | Type | Required | Description |
|---|---|---|---|
src | URI | Yes | A standard URI pointing to an icon resource. May be an HTTP/HTTPS URL or a data: URI with Base64-encoded image data.Consumers SHOULD take steps to ensure URLs serving icons are from the same domain as the client/server or a trusted domain. Consumers SHOULD take appropriate precautions when consuming SVGs as they can contain executable JavaScript. |
contentType | string | No | Optional MIME type override if the source MIME type is missing or generic. For example: "image/png", "image/jpeg", or "image/svg+xml". |
sizes | string[] | No | Optional array of strings that specify sizes at which the icon can be used. Each string should be in WxH format (e.g., "48x48", "96x96") or "any" for scalable formats like SVG.If not provided, the client should assume that the icon can be used at any size. |
theme | 'light' | 'dark' | No | Optional specifier for the theme this icon is designed for. "light" indicates the icon is designed to be used with a light background, and "dark" indicates the icon is designed to be used with a dark background.If not provided, the client should assume the icon can be used with any theme. |
ProtectedResourceMetadata
Describes a protected resource's authentication requirements using RFC 9728 (OAuth 2.0 Protected Resource Metadata) semantics.
Field names use snake_case to match the RFC 9728 JSON format.
| Field | Type | Required | Description |
|---|---|---|---|
resource | string | Yes | REQUIRED. The protected resource's resource identifier, a URL using the https scheme with no fragment component (e.g. "https://api.github.com"). |
resource_name | string | No | OPTIONAL. Human-readable name of the protected resource. |
authorization_servers | string[] | No | OPTIONAL. JSON array of OAuth authorization server identifier URLs. |
jwks_uri | string | No | OPTIONAL. URL of the protected resource's JWK Set document. |
scopes_supported | string[] | No | RECOMMENDED. JSON array of OAuth 2.0 scope values used in authorization requests. |
bearer_methods_supported | string[] | No | OPTIONAL. JSON array of Bearer Token presentation methods supported. |
resource_signing_alg_values_supported | string[] | No | OPTIONAL. JSON array of JWS signing algorithms supported. |
resource_encryption_alg_values_supported | string[] | No | OPTIONAL. JSON array of JWE encryption algorithms (alg) supported. |
resource_encryption_enc_values_supported | string[] | No | OPTIONAL. JSON array of JWE encryption algorithms (enc) supported. |
resource_documentation | string | No | OPTIONAL. URL of human-readable documentation for the resource. |
resource_policy_uri | string | No | OPTIONAL. URL of the resource's data-usage policy. |
resource_tos_uri | string | No | OPTIONAL. URL of the resource's terms of service. |
required | boolean | No | AHP extension. Whether authentication is required for this resource. - true (default) — the agent cannot be used without a valid token. The server SHOULD return AuthRequired (-32007) if the client attempts to use the agent without authenticating. - false — the agent works without authentication but MAY offer enhanced capabilities when a token is provided.Clients SHOULD treat an absent field the same as true. |
ConfigPropertySchema
A JSON Schema-compatible property descriptor with display extensions.
Standard JSON Schema fields (type, title, description, default, enum) allow validators to process the schema. Display extensions (enumLabels, enumDescriptions) are parallel arrays that provide UI metadata for each enum value.
This is the generic base type. See {@link SessionConfigPropertySchema} for session-specific extensions.
| Field | Type | Required | Description |
|---|---|---|---|
type | 'string' | 'number' | 'boolean' | 'array' | 'object' | Yes | JSON Schema: property type |
title | string | Yes | JSON Schema: human-readable label for the property |
description | string | No | JSON Schema: description / tooltip |
default | unknown | No | JSON Schema: default value |
enum | string[] | No | JSON Schema: allowed values (typically used with string type) |
enumLabels | string[] | No | Display extension: human-readable label per enum value (parallel array) |
enumDescriptions | string[] | No | Display extension: description per enum value (parallel array) |
readOnly | boolean | No | JSON Schema: when true, the property is displayed but cannot be modified by the user |
items | ConfigPropertySchema | No | JSON Schema: schema for array items (used when type is 'array') |
properties | Record<string, ConfigPropertySchema> | No | JSON Schema: property descriptors for object properties (used when type is 'object') |
required | string[] | No | JSON Schema: list of required property ids (used when type is 'object') |
ConfigSchema
A JSON Schema object describing available configuration properties.
This is the generic base type. See {@link SessionConfigSchema} for session-specific usage.
| Field | Type | Required | Description |
|---|---|---|---|
type | 'object' | Yes | JSON Schema: always 'object' |
properties | Record<string, ConfigPropertySchema> | Yes | JSON Schema: property descriptors keyed by property id |
required | string[] | No | JSON Schema: list of required property ids |
TextPosition
A zero-based position within a textual document.
| Field | Type | Description |
|---|---|---|
line | number | Zero-based line number. |
character | number | Zero-based character offset within the line. |
TextRange
A range within a textual document.
| Field | Type | Description |
|---|---|---|
start | TextPosition | Start position of the range. |
end | TextPosition | End position of the range. |
TextSelection
A selection within a textual resource.
This is only meaningful for textual resources. Binary resources may still use resource or embedded resource attachments, but they should not use this text selection field.
| Field | Type | Description |
|---|---|---|
range | TextRange | The range covered by the selection. |
ContentRef
A reference to large content stored outside the state tree.
| Field | Type | Required | Description |
|---|---|---|---|
uri | URI | Yes | Content URI |
sizeHint | number | No | Approximate size in bytes |
contentType | string | No | Content MIME type |
FileEdit
Describes a file modification with before/after state and diff metadata.
Supports creates (only after), deletes (only before), renames/moves (different uri in before and after), and edits (same uri, different content).
| Field | Type | Required | Description |
|---|---|---|---|
before | | No | The file state before the edit. Absent for file creations or for in-place file edits. |
after | | No | The file state after the edit. Absent for file deletions. |
diff | | No | Optional diff display metadata |
UsageInfo
| Field | Type | Required | Description |
|---|---|---|---|
inputTokens | number | No | Input tokens consumed |
outputTokens | number | No | Output tokens generated |
model | string | No | Model used |
cacheReadTokens | number | No | Tokens read from cache |
_meta | Record<string, unknown> | No | Additional provider-specific metadata for this usage report. Clients MAY look for well-known optional keys here to provide enhanced UI. |
ErrorInfo
| Field | Type | Required | Description |
|---|---|---|---|
errorType | string | Yes | Error type identifier |
message | string | Yes | Human-readable error message |
stack | string | No | Stack trace |
Snapshot
A point-in-time snapshot of a subscribed resource's state, returned by initialize, reconnect, and subscribe.
| Field | Type | Description |
|---|---|---|
resource | URI | The subscribed channel URI (e.g. ahp-root:// or ahp-session:/<uuid>) |
state | RootState | SessionState | TerminalState | ChangesetState | The current state of the resource |
fromSeq | number | The serverSeq at which this snapshot was taken. Subsequent actions will have serverSeq > fromSeq. |
Action Envelope
Every state-mutating message is wrapped in an ActionEnvelope and routed by its channel field. The full discriminated union of action payloads is StateAction; individual action variants are documented on the per-channel pages.
ActionType
Discriminant values for all state actions.
| Member | Value |
|---|---|
RootAgentsChanged | 'root/agentsChanged' |
RootActiveSessionsChanged | 'root/activeSessionsChanged' |
SessionReady | 'session/ready' |
SessionCreationFailed | 'session/creationFailed' |
SessionTurnStarted | 'session/turnStarted' |
SessionDelta | 'session/delta' |
SessionResponsePart | 'session/responsePart' |
SessionToolCallStart | 'session/toolCallStart' |
SessionToolCallDelta | 'session/toolCallDelta' |
SessionToolCallReady | 'session/toolCallReady' |
SessionToolCallConfirmed | 'session/toolCallConfirmed' |
SessionToolCallComplete | 'session/toolCallComplete' |
SessionToolCallResultConfirmed | 'session/toolCallResultConfirmed' |
SessionToolCallContentChanged | 'session/toolCallContentChanged' |
SessionTurnComplete | 'session/turnComplete' |
SessionTurnCancelled | 'session/turnCancelled' |
SessionError | 'session/error' |
SessionTitleChanged | 'session/titleChanged' |
SessionUsage | 'session/usage' |
SessionReasoning | 'session/reasoning' |
SessionModelChanged | 'session/modelChanged' |
SessionAgentChanged | 'session/agentChanged' |
SessionServerToolsChanged | 'session/serverToolsChanged' |
SessionActiveClientChanged | 'session/activeClientChanged' |
SessionActiveClientToolsChanged | 'session/activeClientToolsChanged' |
SessionPendingMessageSet | 'session/pendingMessageSet' |
SessionPendingMessageRemoved | 'session/pendingMessageRemoved' |
SessionQueuedMessagesReordered | 'session/queuedMessagesReordered' |
SessionInputRequested | 'session/inputRequested' |
SessionInputAnswerChanged | 'session/inputAnswerChanged' |
SessionInputCompleted | 'session/inputCompleted' |
SessionCustomizationsChanged | 'session/customizationsChanged' |
SessionCustomizationToggled | 'session/customizationToggled' |
SessionCustomizationUpdated | 'session/customizationUpdated' |
SessionCustomizationRemoved | 'session/customizationRemoved' |
SessionTruncated | 'session/truncated' |
SessionIsReadChanged | 'session/isReadChanged' |
SessionIsArchivedChanged | 'session/isArchivedChanged' |
SessionActivityChanged | 'session/activityChanged' |
SessionChangesetsChanged | 'session/changesetsChanged' |
SessionConfigChanged | 'session/configChanged' |
SessionMetaChanged | 'session/metaChanged' |
ChangesetStatusChanged | 'changeset/statusChanged' |
ChangesetFileSet | 'changeset/fileSet' |
ChangesetFileRemoved | 'changeset/fileRemoved' |
ChangesetOperationsChanged | 'changeset/operationsChanged' |
ChangesetCleared | 'changeset/cleared' |
RootTerminalsChanged | 'root/terminalsChanged' |
RootConfigChanged | 'root/configChanged' |
TerminalData | 'terminal/data' |
TerminalInput | 'terminal/input' |
TerminalResized | 'terminal/resized' |
TerminalClaimed | 'terminal/claimed' |
TerminalTitleChanged | 'terminal/titleChanged' |
TerminalCwdChanged | 'terminal/cwdChanged' |
TerminalExited | 'terminal/exited' |
TerminalCleared | 'terminal/cleared' |
TerminalCommandDetectionAvailable | 'terminal/commandDetectionAvailable' |
TerminalCommandExecuted | 'terminal/commandExecuted' |
TerminalCommandFinished | 'terminal/commandFinished' |
ActionOrigin
Identifies the client that originally dispatched an action.
| Field | Type | Description |
|---|---|---|
clientId | string | |
clientSeq | number |
ActionEnvelope
Every action is wrapped in an ActionEnvelope.
The envelope identifies the channel the action belongs to (e.g. ahp-root:// for root actions, the session URI for session actions, the terminal URI for terminal actions). Individual action payloads carry only fields that are intrinsic to the action; the channel comes from the envelope so that any subscribable resource can route its actions uniformly.
| Field | Type | Required | Description |
|---|---|---|---|
channel | URI | Yes | Channel URI this action belongs to. |
action | StateAction | Yes | |
serverSeq | number | Yes | |
origin | ActionOrigin | undefined | Yes | |
rejectionReason | string | No |
StateAction
Discriminated union of all state actions.
RootAgentsChangedAction | RootActiveSessionsChangedAction | RootTerminalsChangedAction | RootConfigChangedAction | SessionReadyAction | SessionCreationFailedAction | SessionTurnStartedAction | SessionDeltaAction | SessionResponsePartAction | SessionToolCallStartAction | SessionToolCallDeltaAction | SessionToolCallReadyAction | SessionToolCallConfirmedAction | SessionToolCallCompleteAction | SessionToolCallResultConfirmedAction | SessionToolCallContentChangedAction | SessionTurnCompleteAction | SessionTurnCancelledAction | SessionErrorAction | SessionTitleChangedAction | SessionUsageAction | SessionReasoningAction | SessionModelChangedAction | SessionAgentChangedAction | SessionServerToolsChangedAction | SessionActiveClientChangedAction | SessionActiveClientToolsChangedAction | SessionPendingMessageSetAction | SessionPendingMessageRemovedAction | SessionQueuedMessagesReorderedAction | SessionInputRequestedAction | SessionInputAnswerChangedAction | SessionInputCompletedAction | SessionCustomizationsChangedAction | SessionCustomizationToggledAction | SessionCustomizationUpdatedAction | SessionCustomizationRemovedAction | SessionTruncatedAction | SessionIsReadChangedAction | SessionIsArchivedChangedAction | SessionActivityChangedAction | SessionChangesetsChangedAction | SessionConfigChangedAction | SessionMetaChangedAction | ChangesetStatusChangedAction | ChangesetFileSetAction | ChangesetFileRemovedAction | ChangesetOperationsChangedAction | ChangesetClearedAction | TerminalDataAction | TerminalInputAction | TerminalResizedAction | TerminalClaimedAction | TerminalTitleChangedAction | TerminalCwdChangedAction | TerminalExitedAction | TerminalClearedAction | TerminalCommandDetectionAvailableAction | TerminalCommandExecutedAction | TerminalCommandFinishedAction
Base Parameters
Every command's params object extends BaseParams, ensuring a top-level channel: URI is always present.
BaseParams
Base shape every command's params extends.
channel identifies the channel the command targets, mirroring the channel field on every protocol notification. For commands that operate on a specific channel (a session, terminal, or changeset), channel is that channel's URI. For commands that are connection-level rather than channel-scoped (e.g. {@link InitializeParams | initialize}, {@link PingParams | ping}, {@link ListSessionsParams | listSessions}, the resource* filesystem commands, and {@link AuthenticateParams | authenticate}), the params type narrows channel to the literal root URI 'ahp-root://'.
This invariant lets implementations route every incoming message — request, response, or notification — by inspecting params.channel without needing to know the per-method param shape.
| Field | Type | Description |
|---|---|---|
channel | URI | Channel URI this command targets. |
Commands
Cross-channel commands and notifications. Channel-specific commands (createSession, listSessions, createTerminal, invokeChangesetOperation, etc.) live on the corresponding channel page.
JSON Schema: commands.schema.json
initialize
Establishes a new connection and negotiates the protocol version. This MUST be the first message sent by the client.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
protocolVersions | string[] | Yes | Protocol versions the client is willing to speak, ordered from most preferred to least preferred. Each entry is a SemVer MAJOR.MINOR.PATCH string (e.g. "0.1.0").The server selects one entry and returns it as InitializeResult.protocolVersion. If the server cannot speak any of the offered versions, it MUST return error code -32005 (UnsupportedProtocolVersion). |
clientId | string | Yes | Unique client identifier |
initialSubscriptions | URI[] | No | URIs to subscribe to during handshake |
locale | string | No | IETF BCP 47 language tag indicating the client's preferred locale (e.g. "en-US", "ja"). The server SHOULD use this to localise user-facing strings such as confirmation option labels. |
Result:
| Field | Type | Required | Description |
|---|---|---|---|
protocolVersion | string | Yes | Protocol version selected by the server. MUST be one of the entries in InitializeParams.protocolVersions. Formatted as a SemVer MAJOR.MINOR.PATCH string (e.g. "0.1.0"). |
serverSeq | number | Yes | Current server sequence number |
snapshots | Snapshot[] | Yes | Snapshots for each initialSubscriptions URI |
defaultDirectory | URI | No | Suggested default directory for remote filesystem browsing |
completionTriggerCharacters | string[] | No | Characters that, when typed in a {@link UserMessage} input, SHOULD cause the client to issue a completions request with {@link CompletionItemKind.UserMessage}. Typically includes characters like '@' or '/'. |
telemetry | TelemetryCapabilities | No | OTLP telemetry channels the host emits, if any. Each populated field is either a literal ahp-otlp: channel URI or an RFC 6570 URI template a client expands before subscribing (currently only the logs channel defines a template variable, {level}, for subscriber-side severity filtering). Clients MAY ignore signals they cannot process. |
See Lifecycle for details.
ping
Verifies that the AHP connection is still alive and keeps it from being closed by idle-timeout intermediaries (proxies, load balancers, etc.).
The server MUST respond regardless of whether the client has completed initialize or holds any subscriptions. Ping carries no payload in either direction; the response itself is the signal.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Description |
|---|---|---|
channel | 'ahp-root://' |
Result: null on success.
reconnect
Re-establishes a dropped connection. The server replays missed actions or provides fresh snapshots.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Description |
|---|---|---|
channel | 'ahp-root://' | |
clientId | string | Client identifier from the original connection |
lastSeenServerSeq | number | Last serverSeq the client received |
subscriptions | URI[] | URIs the client was subscribed to |
Result (replay): When the server can replay from the requested sequence:
| Field | Type | Description |
|---|---|---|
type | ReconnectResultType.Replay | Discriminant |
actions | ActionEnvelope[] | Missed action envelopes since lastSeenServerSeq |
missing | URI[] | URIs from ReconnectParams.subscriptions that the server cannot resume. This includes resources that no longer exist (e.g. disposed sessions or terminals) as well as resources the client is no longer permitted to observe. Clients SHOULD drop these from their local subscription set. |
Result (snapshot): When the gap exceeds the replay buffer:
| Field | Type | Description |
|---|---|---|
type | ReconnectResultType.Snapshot | Discriminant |
snapshots | Snapshot[] | Fresh snapshots for each subscription |
See Lifecycle for details.
subscribe
Subscribe to a URI-identified channel.
A channel MAY have state associated with it (e.g. root, sessions, terminals) or be stateless (pure pub/sub for streaming data). For state-bearing channels the result includes a snapshot; for stateless channels snapshot is omitted.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
No parameters.
Result:
| Field | Type | Required | Description |
|---|---|---|---|
snapshot | Snapshot | No | Snapshot of the subscribed channel's state (omitted for stateless channels) |
See Subscriptions for details.
unsubscribe
Stop receiving updates for a channel.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Notification |
Parameters:
| Field | Type | Description |
|---|---|---|
channel | URI | Channel URI to unsubscribe from |
See Subscriptions for details.
dispatchAction
Fire-and-forget action dispatch (write-ahead). The client applies actions optimistically to local state and the server echoes them back as an {@link ActionEnvelope} once accepted.
The client → server method is named dispatchAction; the server's reply arrives on the server → client action notification (params: {@link ActionEnvelope}).
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Notification |
Parameters:
| Field | Type | Description |
|---|---|---|
channel | URI | Channel URI this action targets |
clientSeq | number | Client sequence number |
action | StateAction | The action to dispatch |
See Actions for details.
resourceRead
Reads the content of a resource by URI.
Content references keep the state tree small by storing large data (images, long tool outputs) by reference rather than inline.
Binary content (images, etc.) MUST use base64 encoding. Text content MAY use utf-8 encoding.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
uri | string | Yes | Content URI from a ContentRef |
encoding | ContentEncoding | No | Preferred encoding for the returned data (default: server-chosen) |
Result:
| Field | Type | Required | Description |
|---|---|---|---|
data | string | Yes | Content encoded as a string |
encoding | ContentEncoding | Yes | How data is encoded |
contentType | string | No | Content type (e.g. "image/png", "text/plain") |
Example:
// Client → Server
{ "jsonrpc": "2.0", "id": 10, "method": "resourceRead",
"params": { "uri": "ahp-session:/<uuid>/content/img-1" } }
// Server → Client
{ "jsonrpc": "2.0", "id": 10, "result": {
"data": "iVBORw0KGgo...",
"encoding": "base64",
"contentType": "image/png"
}}resourceWrite
Writes content to a file on the server's filesystem.
Binary content (images, etc.) MUST use base64 encoding. Text content MAY use utf-8 encoding.
If the file does not exist, it is created. If the file already exists, it is overwritten unless createOnly is set.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
uri | URI | Yes | Target file URI on the server filesystem |
data | string | Yes | Content encoded as a string |
encoding | ContentEncoding | Yes | How data is encoded |
contentType | string | No | Content type (e.g. "text/plain", "image/png") |
createOnly | boolean | No | If true, the server MUST fail if the file already exists instead of overwriting it. Useful for safe creation of new files. |
Result:
(empty object)
Example:
// Client → Server
{ "jsonrpc": "2.0", "id": 11, "method": "resourceWrite",
"params": { "uri": "file:///workspace/hello.txt", "data": "SGVsbG8=",
"encoding": "base64", "contentType": "text/plain" } }
// Server → Client
{ "jsonrpc": "2.0", "id": 11, "result": {} }resourceList
Lists directory entries at a file URI on the server's filesystem.
This is intended for remote folder pickers and similar UI that needs to let users navigate the server's local filesystem.
The server MUST return success only if the target exists and is a directory. If the target does not exist, is not a directory, or cannot be accessed, the server MUST return a JSON-RPC error.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Description |
|---|---|---|
channel | 'ahp-root://' | |
uri | URI | Directory URI on the server filesystem |
Result:
| Field | Type | Description |
|---|---|---|
entries | DirectoryEntry[] | Entries directly contained in the requested directory |
resourceCopy
Copies a resource from one URI to another on the server's filesystem.
If the destination already exists, it is overwritten unless failIfExists is set.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
source | URI | Yes | Source URI to copy from |
destination | URI | Yes | Destination URI to copy to |
failIfExists | boolean | No | If true, the server MUST fail if the destination already exists instead of overwriting it. |
Result:
(empty object)
resourceDelete
Deletes a resource at a URI on the server's filesystem.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
uri | URI | Yes | URI of the resource to delete |
recursive | boolean | No | If true and the target is a directory, delete it and all its contents recursively. If false (default), deleting a non-empty directory MUST fail. |
Result:
(empty object)
resourceRequest
Requests permission to access a resource on the receiver's filesystem.
resourceRequest is symmetrical and MAY be sent in either direction: a client asks the server to grant access to a server-side resource, or a server asks the client to grant access to a client-side resource. The receiver decides whether to allow, deny, or prompt the user for the requested access.
If the receiver denies access, it MUST respond with PermissionDenied (-32009). The error data MAY include a ResourceRequestParams value describing the access the caller would need to be granted for the operation to succeed; see PermissionDeniedErrorData in types/errors.ts.
After a successful resourceRequest, the caller MAY use the corresponding resource* commands (e.g. resourceRead, resourceWrite) to perform the operation. Receivers MAY rescind access at any time by returning PermissionDenied on subsequent operations.
Either read, write, or both SHOULD be set to true. A request with neither flag set is treated as read: true by receivers.
| Property | Value |
|---|---|
| Direction | Client ↔ Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
uri | URI | Yes | Resource URI being requested. Typically a file: URI on the receiver's filesystem, but any URI scheme that the receiver mediates access to is allowed. |
read | boolean | No | Whether the caller needs read access to the resource. |
write | boolean | No | Whether the caller needs write access to the resource. |
Result:
(empty object)
resourceMove
Moves (renames) a resource from one URI to another on the server's filesystem.
If the destination already exists, it is overwritten unless failIfExists is set.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | 'ahp-root://' | Yes | |
source | URI | Yes | Source URI to move from |
destination | URI | Yes | Destination URI to move to |
failIfExists | boolean | No | If true, the server MUST fail if the destination already exists instead of overwriting it. |
Result:
(empty object)
authenticate
Pushes a Bearer token for a protected resource. The resource field MUST match a ProtectedResourceMetadata.resource value declared by an agent in AgentInfo.protectedResources.
Tokens are delivered using RFC 6750 (Bearer Token Usage) semantics. The client obtains the token from the authorization server(s) listed in the resource's metadata and pushes it to the server via this command.
| Property | Value |
|---|---|
| Direction | Client → Server |
| Type | Request |
Parameters:
| Field | Type | Description |
|---|---|---|
channel | 'ahp-root://' | |
resource | string | The protected resource identifier. MUST match a resource value from ProtectedResourceMetadata declared in AgentInfo.protectedResources. |
token | string | Bearer token obtained from the resource's authorization server |
Result:
(empty object)
See Authentication for details.
Example:
// Client → Server
{ "jsonrpc": "2.0", "id": 3, "method": "authenticate",
"params": { "channel": "ahp-root://", "resource": "https://api.github.com", "token": "gho_xxxx" } }
// Server → Client (success)
{ "jsonrpc": "2.0", "id": 3, "result": {} }
// Server → Client (failure — invalid token)
{ "jsonrpc": "2.0", "id": 3, "error": { "code": -32007, "message": "Invalid token" } }Notifications
Notifications are ephemeral broadcasts and are not part of the state tree. They are not processed by reducers and are not replayed on reconnection. Every notification carries a top-level channel: URI identifying the subscription it belongs to.
JSON Schema: notifications.schema.json
auth/required
Sent by the server when a protected resource requires (re-)authentication.
This notification MAY be associated with any channel — for example, an agent advertised on the root channel, or a per-session resource. The channel field identifies the subscription the auth requirement belongs to; the resource field carries the OAuth-protected resource identifier (per RFC 9728).
Clients should obtain a fresh token and push it via the authenticate command.
| Property | Value |
|---|---|
| Direction | Server → Client |
| Type | Notification |
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
channel | URI | Yes | Channel URI this notification belongs to |
resource | string | Yes | The protected resource identifier that requires authentication |
reason | AuthRequiredReason | No | Why authentication is required |
Example:
{
"jsonrpc": "2.0",
"method": "auth/required",
"params": {
"channel": "ahp-root://",
"resource": "https://api.github.com",
"reason": "expired"
}
}JSON-RPC Wire Types
Base JSON-RPC message shapes and the typed registries that drive the discriminated-union wrappers (AhpRequest, AhpResponse, AhpClientNotification, AhpServerNotification, AhpNotification, ProtocolMessage).
JsonRpcRequest
A JSON-RPC request: has both method and id.
| Field | Type | Required | Description |
|---|---|---|---|
jsonrpc | '2.0' | Yes | |
id | number | Yes | |
method | string | Yes | |
params | unknown | No |
JsonRpcSuccessResponse
A JSON-RPC success response.
| Field | Type | Description |
|---|---|---|
jsonrpc | '2.0' | |
id | number | |
result | unknown |
JsonRpcErrorResponse
A JSON-RPC error response.
| Field | Type | Description |
|---|---|---|
jsonrpc | '2.0' | |
id | number | |
error | |
JsonRpcNotification
A JSON-RPC notification: has method but no id.
| Field | Type | Required | Description |
|---|---|---|---|
jsonrpc | '2.0' | Yes | |
method | string | Yes | |
params | unknown | No |
AhpErrorResponse
A typed JSON-RPC error response whose error object is a fully typed {@link AhpError}. Useful when the caller knows the response is an AHP application error and wants data narrowed by code.
| Field | Type | Description |
|---|---|---|
jsonrpc | '2.0' | |
id | number | |
error | AhpError |
Registries
The discriminated-union wrappers are parameterised over these registry interfaces. Each property is a JSON-RPC method name; each value is a { params; result? } type literal.
CommandMap
Registry mapping each command method name to its params and result types.
CommandMap covers methods that the client sends to the server. Methods that may also be initiated by the server are duplicated in {@link ServerCommandMap}; the entries in the two maps are kept identical.
export interface CommandMap {
'initialize': { params: InitializeParams; result: InitializeResult };
'ping': { params: PingParams; result: null };
'reconnect': { params: ReconnectParams; result: ReconnectResult };
'subscribe': { params: SubscribeParams; result: SubscribeResult };
'createSession': { params: CreateSessionParams; result: null };
'disposeSession': { params: DisposeSessionParams; result: null };
'createTerminal': { params: CreateTerminalParams; result: null };
'disposeTerminal': { params: DisposeTerminalParams; result: null };
'listSessions': { params: ListSessionsParams; result: ListSessionsResult };
'resourceRead': { params: ResourceReadParams; result: ResourceReadResult };
'resourceWrite': { params: ResourceWriteParams; result: ResourceWriteResult };
'resourceList': { params: ResourceListParams; result: ResourceListResult };
'resourceCopy': { params: ResourceCopyParams; result: ResourceCopyResult };
'resourceDelete': { params: ResourceDeleteParams; result: ResourceDeleteResult };
'resourceMove': { params: ResourceMoveParams; result: ResourceMoveResult };
'resourceRequest': { params: ResourceRequestParams; result: ResourceRequestResult };
'fetchTurns': { params: FetchTurnsParams; result: FetchTurnsResult };
'authenticate': { params: AuthenticateParams; result: AuthenticateResult };
'resolveSessionConfig': { params: ResolveSessionConfigParams; result: ResolveSessionConfigResult };
'sessionConfigCompletions': { params: SessionConfigCompletionsParams; result: SessionConfigCompletionsResult };
'completions': { params: CompletionsParams; result: CompletionsResult };
'invokeChangesetOperation': { params: InvokeChangesetOperationParams; result: InvokeChangesetOperationResult };
}ServerCommandMap
Registry mapping each server → client request method to its params and result types.
Bidirectional commands (currently only resourceRequest) appear in both {@link CommandMap} and ServerCommandMap with identical params/result shapes. The receiver decides whether to allow, deny, or prompt for the requested operation regardless of which peer initiated it.
export interface ServerCommandMap {
'resourceRequest': { params: ResourceRequestParams; result: ResourceRequestResult };
}ClientNotificationMap
Registry mapping each client → server notification method to its params type.
Every notification's params MUST carry a top-level channel: URI so that the server can route the message to the correct subscription. See {@link UnsubscribeParams} for the canonical "base" shape.
export interface ClientNotificationMap {
'unsubscribe': { params: UnsubscribeParams };
'dispatchAction': { params: DispatchActionParams };
}ServerNotificationMap
Registry mapping each server → client notification method to its params type.
Every notification's params MUST carry a top-level channel: URI so that the client can dispatch the message to the right subscription.
export interface ServerNotificationMap {
'action': { params: ActionEnvelope };
'root/sessionAdded': { params: SessionAddedParams };
'root/sessionRemoved': { params: SessionRemovedParams };
'root/sessionSummaryChanged': { params: SessionSummaryChangedParams };
'auth/required': { params: AuthRequiredParams };
'otlp/exportLogs': { params: OtlpExportLogsParams };
'otlp/exportTraces': { params: OtlpExportTracesParams };
'otlp/exportMetrics': { params: OtlpExportMetricsParams };
}Typed Wrappers
AhpRequest
A fully typed JSON-RPC request for a specific AHP command.
When used as a union (default generic), narrowing on method gives typed params:
function handle(req: AhpRequest) {
if (req.method === 'fetchTurns') {
req.params.session; // typed as URI
}
}Defaults to client → server requests ({@link CommandMap}). Use {@link AhpServerRequest} for server → client requests.
M extends unknown ? { readonly jsonrpc: '2.0'; readonly id: number; readonly method: M; readonly params: CommandMap[M]['params']; } : never
AhpServerRequest
A fully typed JSON-RPC request initiated by the server. Identical in shape to {@link AhpRequest} but parameterised over {@link ServerCommandMap}.
M extends unknown ? { readonly jsonrpc: '2.0'; readonly id: number; readonly method: M; readonly params: ServerCommandMap[M]['params']; } : never
AhpSuccessResponse
A fully typed JSON-RPC success response for a specific AHP command.
Since JSON-RPC responses do not carry method, use this with an explicit generic parameter when you know the method from the associated request:
const result: AhpSuccessResponse<'fetchTurns'> = ...;
result.result.turns; // typed as Turn[]M extends unknown ? { readonly jsonrpc: '2.0'; readonly id: number; readonly result: CommandMap[M]['result']; } : never
AhpResponse
Typed JSON-RPC response (success with known result type, or error).
AhpSuccessResponse<M> | JsonRpcErrorResponse
AhpServerSuccessResponse
A fully typed JSON-RPC success response for a server → client request ({@link ServerCommandMap}).
M extends unknown ? { readonly jsonrpc: '2.0'; readonly id: number; readonly result: ServerCommandMap[M]['result']; } : never
AhpServerResponse
Typed JSON-RPC response to a server → client request.
AhpServerSuccessResponse<M> | JsonRpcErrorResponse
AhpClientNotification
A client → server notification.
M extends unknown ? { readonly jsonrpc: '2.0'; readonly method: M; readonly params: ClientNotificationMap[M]['params']; } : never
AhpServerNotification
A server → client notification.
M extends unknown ? { readonly jsonrpc: '2.0'; readonly method: M; readonly params: ServerNotificationMap[M]['params']; } : never
AhpNotification
A fully typed JSON-RPC notification — either direction.
The client → server dispatchAction method and the server → client action method are distinct entries in the registries; their params have unrelated shapes ({@link DispatchActionParams} vs {@link ActionEnvelope}).
AhpClientNotification | AhpServerNotification
ProtocolMessage
Discriminated union of all AHP protocol messages.
Narrow using standard JSON-RPC structure:
- Has
method+id→ request ({@link AhpRequest} or {@link AhpServerRequest}) - Has
method, noid→ notification ({@link AhpNotification}) - Has
resultorerror+id→ response ({@link AhpResponse})
Then narrow on method for fully typed params:
function dispatch(msg: ProtocolMessage) {
if ('method' in msg && 'id' in msg) {
// msg is AhpRequest | AhpServerRequest
if (msg.method === 'fetchTurns') {
msg.params.session; // URI
}
}
}AhpRequest | AhpServerRequest | AhpSuccessResponse | AhpServerSuccessResponse | JsonRpcErrorResponse | AhpNotification