Skip to content

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 string is 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.

FieldTypeRequiredDescription
srcURIYesA 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.
contentTypestringNoOptional MIME type override if the source MIME type is missing or generic. For example: "image/png", "image/jpeg", or "image/svg+xml".
sizesstring[]NoOptional 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'NoOptional 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.

FieldTypeRequiredDescription
resourcestringYesREQUIRED. The protected resource's resource identifier, a URL using the https scheme with no fragment component (e.g. "https://api.github.com").
resource_namestringNoOPTIONAL. Human-readable name of the protected resource.
authorization_serversstring[]NoOPTIONAL. JSON array of OAuth authorization server identifier URLs.
jwks_uristringNoOPTIONAL. URL of the protected resource's JWK Set document.
scopes_supportedstring[]NoRECOMMENDED. JSON array of OAuth 2.0 scope values used in authorization requests.
bearer_methods_supportedstring[]NoOPTIONAL. JSON array of Bearer Token presentation methods supported.
resource_signing_alg_values_supportedstring[]NoOPTIONAL. JSON array of JWS signing algorithms supported.
resource_encryption_alg_values_supportedstring[]NoOPTIONAL. JSON array of JWE encryption algorithms (alg) supported.
resource_encryption_enc_values_supportedstring[]NoOPTIONAL. JSON array of JWE encryption algorithms (enc) supported.
resource_documentationstringNoOPTIONAL. URL of human-readable documentation for the resource.
resource_policy_uristringNoOPTIONAL. URL of the resource's data-usage policy.
resource_tos_uristringNoOPTIONAL. URL of the resource's terms of service.
requiredbooleanNoAHP 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.

FieldTypeRequiredDescription
type'string' | 'number' | 'boolean' | 'array' | 'object'YesJSON Schema: property type
titlestringYesJSON Schema: human-readable label for the property
descriptionstringNoJSON Schema: description / tooltip
defaultunknownNoJSON Schema: default value
enumstring[]NoJSON Schema: allowed values (typically used with string type)
enumLabelsstring[]NoDisplay extension: human-readable label per enum value (parallel array)
enumDescriptionsstring[]NoDisplay extension: description per enum value (parallel array)
readOnlybooleanNoJSON Schema: when true, the property is displayed but cannot be modified by the user
itemsConfigPropertySchemaNoJSON Schema: schema for array items (used when type is 'array')
propertiesRecord<string, ConfigPropertySchema>NoJSON Schema: property descriptors for object properties (used when type is 'object')
requiredstring[]NoJSON 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.

FieldTypeRequiredDescription
type'object'YesJSON Schema: always 'object'
propertiesRecord<string, ConfigPropertySchema>YesJSON Schema: property descriptors keyed by property id
requiredstring[]NoJSON Schema: list of required property ids

TextPosition

A zero-based position within a textual document.

FieldTypeDescription
linenumberZero-based line number.
characternumberZero-based character offset within the line.

TextRange

A range within a textual document.

FieldTypeDescription
startTextPositionStart position of the range.
endTextPositionEnd 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.

FieldTypeDescription
rangeTextRangeThe range covered by the selection.

ContentRef

A reference to large content stored outside the state tree.

FieldTypeRequiredDescription
uriURIYesContent URI
sizeHintnumberNoApproximate size in bytes
contentTypestringNoContent 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).

FieldTypeRequiredDescription
before
{
  uri: URI;
  content: ContentRef;
}
NoThe file state before the edit. Absent for file creations or for in-place file edits.
after
{
  uri: URI;
  content: ContentRef;
}
NoThe file state after the edit. Absent for file deletions.
diff
{
  added?: number;
  removed?: number;
}
NoOptional diff display metadata

UsageInfo

FieldTypeRequiredDescription
inputTokensnumberNoInput tokens consumed
outputTokensnumberNoOutput tokens generated
modelstringNoModel used
cacheReadTokensnumberNoTokens read from cache
_metaRecord<string, unknown>NoAdditional provider-specific metadata for this usage report. Clients MAY look for well-known optional keys here to provide enhanced UI.

ErrorInfo

FieldTypeRequiredDescription
errorTypestringYesError type identifier
messagestringYesHuman-readable error message
stackstringNoStack trace

Snapshot

A point-in-time snapshot of a subscribed resource's state, returned by initialize, reconnect, and subscribe.

FieldTypeDescription
resourceURIThe subscribed channel URI (e.g. ahp-root:// or ahp-session:/&lt;uuid&gt;)
stateRootState | SessionState | TerminalState | ChangesetStateThe current state of the resource
fromSeqnumberThe serverSeq at which this snapshot was taken. Subsequent actions will have serverSeq &gt; 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.

MemberValue
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.

FieldTypeDescription
clientIdstring
clientSeqnumber

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.

FieldTypeRequiredDescription
channelURIYesChannel URI this action belongs to.
actionStateActionYes
serverSeqnumberYes
originActionOrigin | undefinedYes
rejectionReasonstringNo

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.

FieldTypeDescription
channelURIChannel 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
protocolVersionsstring[]YesProtocol 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).
clientIdstringYesUnique client identifier
initialSubscriptionsURI[]NoURIs to subscribe to during handshake
localestringNoIETF 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:

FieldTypeRequiredDescription
protocolVersionstringYesProtocol 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").
serverSeqnumberYesCurrent server sequence number
snapshotsSnapshot[]YesSnapshots for each initialSubscriptions URI
defaultDirectoryURINoSuggested default directory for remote filesystem browsing
completionTriggerCharactersstring[]NoCharacters 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 '/'.
telemetryTelemetryCapabilitiesNoOTLP 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeDescription
channel'ahp-root://'

Result: null on success.


reconnect

Re-establishes a dropped connection. The server replays missed actions or provides fresh snapshots.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeDescription
channel'ahp-root://'
clientIdstringClient identifier from the original connection
lastSeenServerSeqnumberLast serverSeq the client received
subscriptionsURI[]URIs the client was subscribed to

Result (replay): When the server can replay from the requested sequence:

FieldTypeDescription
typeReconnectResultType.ReplayDiscriminant
actionsActionEnvelope[]Missed action envelopes since lastSeenServerSeq
missingURI[]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:

FieldTypeDescription
typeReconnectResultType.SnapshotDiscriminant
snapshotsSnapshot[]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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

No parameters.

Result:

FieldTypeRequiredDescription
snapshotSnapshotNoSnapshot of the subscribed channel's state (omitted for stateless channels)

See Subscriptions for details.


unsubscribe

Stop receiving updates for a channel.

PropertyValue
DirectionClient → Server
TypeNotification

Parameters:

FieldTypeDescription
channelURIChannel 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}).

PropertyValue
DirectionClient → Server
TypeNotification

Parameters:

FieldTypeDescription
channelURIChannel URI this action targets
clientSeqnumberClient sequence number
actionStateActionThe 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
uristringYesContent URI from a ContentRef
encodingContentEncodingNoPreferred encoding for the returned data (default: server-chosen)

Result:

FieldTypeRequiredDescription
datastringYesContent encoded as a string
encodingContentEncodingYesHow data is encoded
contentTypestringNoContent type (e.g. "image/png", "text/plain")

Example:

jsonc
// 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
uriURIYesTarget file URI on the server filesystem
datastringYesContent encoded as a string
encodingContentEncodingYesHow data is encoded
contentTypestringNoContent type (e.g. "text/plain", "image/png")
createOnlybooleanNoIf 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:

jsonc
// 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeDescription
channel'ahp-root://'
uriURIDirectory URI on the server filesystem

Result:

FieldTypeDescription
entriesDirectoryEntry[]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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
sourceURIYesSource URI to copy from
destinationURIYesDestination URI to copy to
failIfExistsbooleanNoIf 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
uriURIYesURI of the resource to delete
recursivebooleanNoIf 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.

PropertyValue
DirectionClient ↔ Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
uriURIYesResource URI being requested. Typically a file: URI on the receiver's filesystem, but any URI scheme that the receiver mediates access to is allowed.
readbooleanNoWhether the caller needs read access to the resource.
writebooleanNoWhether 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeRequiredDescription
channel'ahp-root://'Yes
sourceURIYesSource URI to move from
destinationURIYesDestination URI to move to
failIfExistsbooleanNoIf 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.

PropertyValue
DirectionClient → Server
TypeRequest

Parameters:

FieldTypeDescription
channel'ahp-root://'
resourcestringThe protected resource identifier. MUST match a resource value from ProtectedResourceMetadata declared in AgentInfo.protectedResources.
tokenstringBearer token obtained from the resource's authorization server

Result:

(empty object)

See Authentication for details.

Example:

jsonc
// 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.

PropertyValue
DirectionServer → Client
TypeNotification

Parameters:

FieldTypeRequiredDescription
channelURIYesChannel URI this notification belongs to
resourcestringYesThe protected resource identifier that requires authentication
reasonAuthRequiredReasonNoWhy authentication is required

Example:

json
{
  "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.

FieldTypeRequiredDescription
jsonrpc'2.0'Yes
idnumberYes
methodstringYes
paramsunknownNo

JsonRpcSuccessResponse

A JSON-RPC success response.

FieldTypeDescription
jsonrpc'2.0'
idnumber
resultunknown

JsonRpcErrorResponse

A JSON-RPC error response.

FieldTypeDescription
jsonrpc'2.0'
idnumber
error
{
  readonly code: number;
  readonly message: string;
  readonly data?: unknown;
}

JsonRpcNotification

A JSON-RPC notification: has method but no id.

FieldTypeRequiredDescription
jsonrpc'2.0'Yes
methodstringYes
paramsunknownNo

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.

FieldTypeDescription
jsonrpc'2.0'
idnumber
errorAhpError

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.

ts
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.

ts
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.

ts
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.

ts
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:

ts
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:

ts
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, no id → notification ({@link AhpNotification})
  • Has result or error + id → response ({@link AhpResponse})

Then narrow on method for fully typed params:

ts
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

Released under the MIT License.