use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonRpcRequest {
pub jsonrpc: String,
pub id: u64,
pub method: String,
pub params: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonRpcResponse {
pub jsonrpc: String,
pub id: u64,
pub result: Option<serde_json::Value>,
pub error: Option<JsonRpcError>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonRpcNotification {
pub jsonrpc: String,
pub method: String,
pub params: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonRpcError {
pub code: i32,
pub message: String,
pub data: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum JsonRpcMessage {
Response(JsonRpcResponse),
Notification(JsonRpcNotification),
Request(JsonRpcRequest),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeRequest {
pub protocol_version: u32,
pub client_capabilities: ClientCapabilities,
pub client_info: Option<Implementation>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeResponse {
pub protocol_version: u32,
#[serde(default)]
pub agent_capabilities: AgentCapabilities,
pub agent_info: Option<Implementation>,
#[serde(default)]
pub auth_methods: Vec<AuthMethod>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Implementation {
pub name: String,
pub title: Option<String>,
pub version: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientCapabilities {
pub fs: FsCapabilities,
pub terminal: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FsCapabilities {
pub read_text_file: bool,
pub write_text_file: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase", default)]
pub struct AgentCapabilities {
pub load_session: bool,
pub prompt_capabilities: PromptCapabilities,
pub mcp_capabilities: McpCapabilities,
pub session_capabilities: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase", default)]
pub struct PromptCapabilities {
pub image: bool,
pub audio: bool,
pub embedded_context: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase", default)]
pub struct McpCapabilities {
pub http: bool,
pub sse: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthMethod {
pub id: String,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthenticateRequest {
pub method_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthenticateResponse {}
pub type SessionId = String;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NewSessionRequest {
pub cwd: String,
#[serde(default)]
pub mcp_servers: Vec<McpServer>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NewSessionResponse {
pub session_id: SessionId,
pub modes: Option<SessionModeState>,
pub config_options: Option<Vec<SessionConfigOption>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LoadSessionRequest {
pub session_id: SessionId,
pub cwd: String,
#[serde(default)]
pub mcp_servers: Vec<McpServer>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LoadSessionResponse {
pub modes: Option<SessionModeState>,
pub config_options: Option<Vec<SessionConfigOption>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum McpServer {
Stdio {
name: String,
command: String,
#[serde(default)]
args: Vec<String>,
#[serde(default)]
env: Vec<EnvVariable>,
},
Http {
name: String,
url: String,
#[serde(default)]
headers: Vec<HttpHeader>,
},
Sse {
name: String,
url: String,
#[serde(default)]
headers: Vec<HttpHeader>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EnvVariable {
pub name: String,
pub value: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct HttpHeader {
pub name: String,
pub value: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PromptRequest {
pub session_id: SessionId,
pub prompt: Vec<ContentBlock>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PromptResponse {
pub stop_reason: StopReason,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum StopReason {
EndTurn,
MaxTokens,
MaxTurnRequests,
Refusal,
Cancelled,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentBlock {
Text {
text: String,
},
Image {
mime_type: String,
data: String,
},
Audio {
mime_type: String,
data: String,
},
Resource {
resource: EmbeddedResource,
},
ResourceLink {
uri: String,
name: String,
mime_type: Option<String>,
title: Option<String>,
description: Option<String>,
size: Option<u64>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EmbeddedResource {
pub uri: String,
pub mime_type: Option<String>,
pub text: Option<String>,
pub blob: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionNotification {
pub session_id: SessionId,
pub update: SessionUpdate,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "sessionUpdate", rename_all = "snake_case")]
pub enum SessionUpdate {
AgentMessageChunk {
content: ContentBlock,
},
UserMessageChunk {
content: ContentBlock,
},
ThoughtChunk {
content: ContentBlock,
},
ToolCall {
tool_call_id: String,
title: String,
kind: ToolKind,
status: ToolCallStatus,
#[serde(default)]
content: Option<Vec<ToolCallContent>>,
#[serde(default)]
locations: Option<Vec<ToolCallLocation>>,
raw_input: Option<serde_json::Value>,
raw_output: Option<serde_json::Value>,
},
ToolCallUpdate {
tool_call_id: String,
title: Option<String>,
status: Option<ToolCallStatus>,
#[serde(default)]
content: Option<Vec<ToolCallContent>>,
#[serde(default)]
locations: Option<Vec<ToolCallLocation>>,
},
Plan {
entries: Vec<PlanEntry>,
},
AvailableCommandsUpdate {
available_commands: Vec<AvailableCommand>,
},
CurrentModeUpdate {
mode_id: String,
},
ConfigOptionsUpdate {
config_options: Vec<SessionConfigOption>,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ToolKind {
Read,
Edit,
Delete,
Move,
Search,
Execute,
Think,
Fetch,
Other,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ToolCallStatus {
Pending,
InProgress,
Completed,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolCallLocation {
pub path: String,
pub line: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ToolCallContent {
Content {
content: ContentBlock,
},
Diff {
path: String,
old_text: Option<String>,
new_text: String,
},
Terminal {
terminal_id: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PlanEntry {
pub content: String,
pub priority: PlanEntryPriority,
pub status: PlanEntryStatus,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PlanEntryPriority {
High,
Medium,
Low,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PlanEntryStatus {
Pending,
InProgress,
Completed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AvailableCommand {
pub name: String,
pub description: String,
pub input: Option<AvailableCommandInput>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AvailableCommandInput {
pub hint: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestPermissionRequest {
pub session_id: SessionId,
pub tool_call: ToolCallForPermission,
#[serde(default)]
pub options: Vec<PermissionOption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolCallForPermission {
pub tool_call_id: String,
pub title: String,
pub kind: ToolKind,
pub status: ToolCallStatus,
#[serde(default)]
pub content: Option<Vec<ToolCallContent>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PermissionOption {
pub option_id: String,
pub name: String,
pub kind: PermissionOptionKind,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PermissionOptionKind {
AllowOnce,
AllowAlways,
RejectOnce,
RejectAlways,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestPermissionResponse {
pub outcome: RequestPermissionOutcome,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "outcome", rename_all = "snake_case")]
pub enum RequestPermissionOutcome {
Cancelled,
Selected { option_id: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ReadTextFileRequest {
pub session_id: SessionId,
pub path: String,
pub line: Option<u32>,
pub limit: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ReadTextFileResponse {
pub content: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WriteTextFileRequest {
pub session_id: SessionId,
pub path: String,
pub content: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WriteTextFileResponse {}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateTerminalRequest {
pub session_id: SessionId,
pub command: String,
#[serde(default)]
pub args: Vec<String>,
#[serde(default)]
pub env: Vec<EnvVariable>,
pub cwd: Option<String>,
pub output_byte_limit: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateTerminalResponse {
pub terminal_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TerminalOutputRequest {
pub session_id: SessionId,
pub terminal_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TerminalOutputResponse {
pub output: String,
pub truncated: bool,
pub exit_status: Option<TerminalExitStatus>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WaitForTerminalExitRequest {
pub session_id: SessionId,
pub terminal_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WaitForTerminalExitResponse {
pub exit_code: Option<i32>,
pub signal: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct KillTerminalRequest {
pub session_id: SessionId,
pub terminal_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KillTerminalResponse {}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ReleaseTerminalRequest {
pub session_id: SessionId,
pub terminal_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReleaseTerminalResponse {}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TerminalExitStatus {
pub exit_code: Option<i32>,
pub signal: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionModeState {
pub current_mode_id: String,
#[serde(default)]
pub available_modes: Vec<SessionMode>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionMode {
pub id: String,
pub name: String,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SetSessionModeRequest {
pub session_id: SessionId,
pub mode_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetSessionModeResponse {}
pub type SessionConfigId = String;
pub type SessionConfigValueId = String;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionConfigOption {
pub id: SessionConfigId,
pub label: String,
#[serde(default)]
pub values: Vec<SessionConfigValue>,
pub current: SessionConfigValueId,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SessionConfigValue {
pub id: SessionConfigValueId,
pub label: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SetSessionConfigOptionRequest {
pub session_id: SessionId,
pub config_id: SessionConfigId,
pub value: SessionConfigValueId,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SetSessionConfigOptionResponse {
#[serde(default)]
pub config_options: Vec<SessionConfigOption>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CancelNotification {
pub session_id: SessionId,
}