docs: add mcp and skill session config (#106)

This commit is contained in:
NathanFlurry 2026-02-09 10:13:25 +00:00
parent d236edf35c
commit 4c8d93e077
No known key found for this signature in database
GPG key ID: 6A5F43A4F3241BCA
95 changed files with 10014 additions and 1342 deletions

View file

@ -8,6 +8,18 @@ import type {
CreateSessionResponse,
EventsQuery,
EventsResponse,
FsActionResponse,
FsDeleteQuery,
FsEntriesQuery,
FsEntry,
FsMoveRequest,
FsMoveResponse,
FsPathQuery,
FsSessionQuery,
FsStat,
FsUploadBatchQuery,
FsUploadBatchResponse,
FsWriteResponse,
HealthResponse,
MessageRequest,
PermissionReplyRequest,
@ -52,6 +64,8 @@ type QueryValue = string | number | boolean | null | undefined;
type RequestOptions = {
query?: Record<string, QueryValue>;
body?: unknown;
rawBody?: BodyInit;
contentType?: string;
headers?: HeadersInit;
accept?: string;
signal?: AbortSignal;
@ -216,6 +230,57 @@ export class SandboxAgent {
await this.requestJson("POST", `${API_PREFIX}/sessions/${encodeURIComponent(sessionId)}/terminate`);
}
async listFsEntries(query?: FsEntriesQuery): Promise<FsEntry[]> {
return this.requestJson("GET", `${API_PREFIX}/fs/entries`, { query });
}
async readFsFile(query: FsPathQuery): Promise<Uint8Array> {
const response = await this.requestRaw("GET", `${API_PREFIX}/fs/file`, {
query,
accept: "application/octet-stream",
});
const buffer = await response.arrayBuffer();
return new Uint8Array(buffer);
}
async writeFsFile(query: FsPathQuery, body: BodyInit): Promise<FsWriteResponse> {
const response = await this.requestRaw("PUT", `${API_PREFIX}/fs/file`, {
query,
rawBody: body,
contentType: "application/octet-stream",
accept: "application/json",
});
const text = await response.text();
return text ? (JSON.parse(text) as FsWriteResponse) : { path: "", bytesWritten: 0 };
}
async deleteFsEntry(query: FsDeleteQuery): Promise<FsActionResponse> {
return this.requestJson("DELETE", `${API_PREFIX}/fs/entry`, { query });
}
async mkdirFs(query: FsPathQuery): Promise<FsActionResponse> {
return this.requestJson("POST", `${API_PREFIX}/fs/mkdir`, { query });
}
async moveFs(request: FsMoveRequest, query?: FsSessionQuery): Promise<FsMoveResponse> {
return this.requestJson("POST", `${API_PREFIX}/fs/move`, { query, body: request });
}
async statFs(query: FsPathQuery): Promise<FsStat> {
return this.requestJson("GET", `${API_PREFIX}/fs/stat`, { query });
}
async uploadFsBatch(body: BodyInit, query?: FsUploadBatchQuery): Promise<FsUploadBatchResponse> {
const response = await this.requestRaw("POST", `${API_PREFIX}/fs/upload-batch`, {
query,
rawBody: body,
contentType: "application/x-tar",
accept: "application/json",
});
const text = await response.text();
return text ? (JSON.parse(text) as FsUploadBatchResponse) : { paths: [], truncated: false };
}
async dispose(): Promise<void> {
if (this.spawnHandle) {
await this.spawnHandle.dispose();
@ -256,7 +321,15 @@ export class SandboxAgent {
}
const init: RequestInit = { method, headers, signal: options.signal };
if (options.body !== undefined) {
if (options.rawBody !== undefined && options.body !== undefined) {
throw new Error("requestRaw received both rawBody and body");
}
if (options.rawBody !== undefined) {
if (options.contentType) {
headers.set("Content-Type", options.contentType);
}
init.body = options.rawBody;
} else if (options.body !== undefined) {
headers.set("Content-Type", "application/json");
init.body = JSON.stringify(options.body);
}

View file

@ -6,48 +6,162 @@
export interface paths {
"/v1/agents": {
/**
* List Agents
* @description Returns all available coding agents and their installation status.
*/
get: operations["list_agents"];
};
"/v1/agents/{agent}/install": {
/**
* Install Agent
* @description Installs or updates a coding agent (e.g. claude, codex, opencode, amp).
*/
post: operations["install_agent"];
};
"/v1/agents/{agent}/models": {
/**
* List Agent Models
* @description Returns the available LLM models for an agent.
*/
get: operations["get_agent_models"];
};
"/v1/agents/{agent}/modes": {
/**
* List Agent Modes
* @description Returns the available interaction modes for an agent.
*/
get: operations["get_agent_modes"];
};
"/v1/fs/entries": {
/**
* List Directory
* @description Lists files and directories at the given path.
*/
get: operations["fs_entries"];
};
"/v1/fs/entry": {
/**
* Delete Entry
* @description Deletes a file or directory.
*/
delete: operations["fs_delete_entry"];
};
"/v1/fs/file": {
/**
* Read File
* @description Reads the raw bytes of a file.
*/
get: operations["fs_read_file"];
/**
* Write File
* @description Writes raw bytes to a file, creating it if it doesn't exist.
*/
put: operations["fs_write_file"];
};
"/v1/fs/mkdir": {
/**
* Create Directory
* @description Creates a directory, including any missing parent directories.
*/
post: operations["fs_mkdir"];
};
"/v1/fs/move": {
/**
* Move Entry
* @description Moves or renames a file or directory.
*/
post: operations["fs_move"];
};
"/v1/fs/stat": {
/**
* Get File Info
* @description Returns metadata (size, timestamps, type) for a path.
*/
get: operations["fs_stat"];
};
"/v1/fs/upload-batch": {
/**
* Upload Files
* @description Uploads a tar.gz archive and extracts it to the destination directory.
*/
post: operations["fs_upload_batch"];
};
"/v1/health": {
/**
* Health Check
* @description Returns the server health status.
*/
get: operations["get_health"];
};
"/v1/sessions": {
/**
* List Sessions
* @description Returns all active sessions.
*/
get: operations["list_sessions"];
};
"/v1/sessions/{session_id}": {
/**
* Create Session
* @description Creates a new agent session with the given configuration.
*/
post: operations["create_session"];
};
"/v1/sessions/{session_id}/events": {
/**
* Get Events
* @description Returns session events with optional offset-based pagination.
*/
get: operations["get_events"];
};
"/v1/sessions/{session_id}/events/sse": {
/**
* Subscribe to Events (SSE)
* @description Opens an SSE stream for real-time session events.
*/
get: operations["get_events_sse"];
};
"/v1/sessions/{session_id}/messages": {
/**
* Send Message
* @description Sends a message to a session and returns immediately.
*/
post: operations["post_message"];
};
"/v1/sessions/{session_id}/messages/stream": {
/**
* Send Message (Streaming)
* @description Sends a message and returns an SSE event stream of the agent's response.
*/
post: operations["post_message_stream"];
};
"/v1/sessions/{session_id}/permissions/{permission_id}/reply": {
/**
* Reply to Permission
* @description Approves or denies a permission request from the agent.
*/
post: operations["reply_permission"];
};
"/v1/sessions/{session_id}/questions/{question_id}/reject": {
/**
* Reject Question
* @description Rejects a human-in-the-loop question from the agent.
*/
post: operations["reject_question"];
};
"/v1/sessions/{session_id}/questions/{question_id}/reply": {
/**
* Reply to Question
* @description Replies to a human-in-the-loop question from the agent.
*/
post: operations["reply_question"];
};
"/v1/sessions/{session_id}/terminate": {
/**
* Terminate Session
* @description Terminates a running session and cleans up resources.
*/
post: operations["terminate_session"];
};
}
@ -76,7 +190,6 @@ export interface components {
textMessages: boolean;
toolCalls: boolean;
toolResults: boolean;
variants: boolean;
};
AgentError: {
agent?: string | null;
@ -170,8 +283,12 @@ export interface components {
agentMode?: string | null;
agentVersion?: string | null;
directory?: string | null;
mcp?: {
[key: string]: components["schemas"]["McpServerConfig"];
} | null;
model?: string | null;
permissionMode?: string | null;
skills?: components["schemas"]["SkillsConfig"] | null;
title?: string | null;
variant?: string | null;
};
@ -202,6 +319,64 @@ export interface components {
};
/** @enum {string} */
FileAction: "read" | "write" | "patch";
FsActionResponse: {
path: string;
};
FsDeleteQuery: {
path: string;
recursive?: boolean | null;
sessionId?: string | null;
};
FsEntriesQuery: {
path?: string | null;
sessionId?: string | null;
};
FsEntry: {
entryType: components["schemas"]["FsEntryType"];
modified?: string | null;
name: string;
path: string;
/** Format: int64 */
size: number;
};
/** @enum {string} */
FsEntryType: "file" | "directory";
FsMoveRequest: {
from: string;
overwrite?: boolean | null;
to: string;
};
FsMoveResponse: {
from: string;
to: string;
};
FsPathQuery: {
path: string;
sessionId?: string | null;
};
FsSessionQuery: {
sessionId?: string | null;
};
FsStat: {
entryType: components["schemas"]["FsEntryType"];
modified?: string | null;
path: string;
/** Format: int64 */
size: number;
};
FsUploadBatchQuery: {
path?: string | null;
sessionId?: string | null;
};
FsUploadBatchResponse: {
paths: string[];
truncated: boolean;
};
FsWriteResponse: {
/** Format: int64 */
bytesWritten: number;
path: string;
};
HealthResponse: {
status: string;
};
@ -219,7 +394,51 @@ export interface components {
ItemRole: "user" | "assistant" | "system" | "tool";
/** @enum {string} */
ItemStatus: "in_progress" | "completed" | "failed";
McpCommand: string | string[];
McpOAuthConfig: {
clientId?: string | null;
clientSecret?: string | null;
scope?: string | null;
};
McpOAuthConfigOrDisabled: components["schemas"]["McpOAuthConfig"] | boolean;
/** @enum {string} */
McpRemoteTransport: "http" | "sse";
McpServerConfig: ({
args?: string[];
command: components["schemas"]["McpCommand"];
cwd?: string | null;
enabled?: boolean | null;
env?: {
[key: string]: string;
} | null;
/** Format: int64 */
timeoutMs?: number | null;
/** @enum {string} */
type: "local";
}) | ({
bearerTokenEnvVar?: string | null;
enabled?: boolean | null;
envHeaders?: {
[key: string]: string;
} | null;
headers?: {
[key: string]: string;
} | null;
oauth?: components["schemas"]["McpOAuthConfigOrDisabled"] | null;
/** Format: int64 */
timeoutMs?: number | null;
transport?: components["schemas"]["McpRemoteTransport"] | null;
/** @enum {string} */
type: "remote";
url: string;
});
MessageAttachment: {
filename?: string | null;
mime?: string | null;
path: string;
};
MessageRequest: {
attachments?: components["schemas"]["MessageAttachment"][];
message: string;
};
PermissionEventData: {
@ -295,10 +514,14 @@ export interface components {
ended: boolean;
/** Format: int64 */
eventCount: number;
mcp?: {
[key: string]: components["schemas"]["McpServerConfig"];
} | null;
model?: string | null;
nativeSessionId?: string | null;
permissionMode: string;
sessionId: string;
skills?: components["schemas"]["SkillsConfig"] | null;
title?: string | null;
/** Format: int64 */
updatedAt: number;
@ -310,6 +533,16 @@ export interface components {
SessionStartedData: {
metadata?: unknown;
};
SkillSource: {
ref?: string | null;
skills?: string[] | null;
source: string;
subpath?: string | null;
type: string;
};
SkillsConfig: {
sources: components["schemas"]["SkillSource"][];
};
StderrOutput: {
/** @description First N lines of stderr (if truncated) or full stderr (if not truncated) */
head?: string | null;
@ -371,8 +604,13 @@ export type external = Record<string, never>;
export interface operations {
/**
* List Agents
* @description Returns all available coding agents and their installation status.
*/
list_agents: {
responses: {
/** @description List of available agents */
200: {
content: {
"application/json": components["schemas"]["AgentListResponse"];
@ -380,6 +618,10 @@ export interface operations {
};
};
};
/**
* Install Agent
* @description Installs or updates a coding agent (e.g. claude, codex, opencode, amp).
*/
install_agent: {
parameters: {
path: {
@ -397,16 +639,19 @@ export interface operations {
204: {
content: never;
};
/** @description Invalid request */
400: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
};
};
/** @description Agent not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
};
};
/** @description Installation failed */
500: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -414,6 +659,10 @@ export interface operations {
};
};
};
/**
* List Agent Models
* @description Returns the available LLM models for an agent.
*/
get_agent_models: {
parameters: {
path: {
@ -422,18 +671,24 @@ export interface operations {
};
};
responses: {
/** @description Available models */
200: {
content: {
"application/json": components["schemas"]["AgentModelsResponse"];
};
};
400: {
/** @description Agent not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
};
};
};
};
/**
* List Agent Modes
* @description Returns the available interaction modes for an agent.
*/
get_agent_modes: {
parameters: {
path: {
@ -442,11 +697,13 @@ export interface operations {
};
};
responses: {
/** @description Available modes */
200: {
content: {
"application/json": components["schemas"]["AgentModesResponse"];
};
};
/** @description Invalid request */
400: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -454,8 +711,204 @@ export interface operations {
};
};
};
/**
* List Directory
* @description Lists files and directories at the given path.
*/
fs_entries: {
parameters: {
query?: {
/** @description Path to list (relative or absolute) */
path?: string | null;
/** @description Session id for relative paths */
session_id?: string | null;
};
};
responses: {
/** @description Directory listing */
200: {
content: {
"application/json": components["schemas"]["FsEntry"][];
};
};
};
};
/**
* Delete Entry
* @description Deletes a file or directory.
*/
fs_delete_entry: {
parameters: {
query: {
/** @description File or directory path */
path: string;
/** @description Session id for relative paths */
session_id?: string | null;
/** @description Delete directories recursively */
recursive?: boolean | null;
};
};
responses: {
/** @description Delete result */
200: {
content: {
"application/json": components["schemas"]["FsActionResponse"];
};
};
};
};
/**
* Read File
* @description Reads the raw bytes of a file.
*/
fs_read_file: {
parameters: {
query: {
/** @description File path (relative or absolute) */
path: string;
/** @description Session id for relative paths */
session_id?: string | null;
};
};
responses: {
/** @description File content */
200: {
content: {
"application/octet-stream": string;
};
};
};
};
/**
* Write File
* @description Writes raw bytes to a file, creating it if it doesn't exist.
*/
fs_write_file: {
parameters: {
query: {
/** @description File path (relative or absolute) */
path: string;
/** @description Session id for relative paths */
session_id?: string | null;
};
};
requestBody: {
content: {
"application/octet-stream": string;
};
};
responses: {
/** @description Write result */
200: {
content: {
"application/json": components["schemas"]["FsWriteResponse"];
};
};
};
};
/**
* Create Directory
* @description Creates a directory, including any missing parent directories.
*/
fs_mkdir: {
parameters: {
query: {
/** @description Directory path to create */
path: string;
/** @description Session id for relative paths */
session_id?: string | null;
};
};
responses: {
/** @description Directory created */
200: {
content: {
"application/json": components["schemas"]["FsActionResponse"];
};
};
};
};
/**
* Move Entry
* @description Moves or renames a file or directory.
*/
fs_move: {
parameters: {
query?: {
/** @description Session id for relative paths */
session_id?: string | null;
};
};
requestBody: {
content: {
"application/json": components["schemas"]["FsMoveRequest"];
};
};
responses: {
/** @description Move result */
200: {
content: {
"application/json": components["schemas"]["FsMoveResponse"];
};
};
};
};
/**
* Get File Info
* @description Returns metadata (size, timestamps, type) for a path.
*/
fs_stat: {
parameters: {
query: {
/** @description Path to stat */
path: string;
/** @description Session id for relative paths */
session_id?: string | null;
};
};
responses: {
/** @description File metadata */
200: {
content: {
"application/json": components["schemas"]["FsStat"];
};
};
};
};
/**
* Upload Files
* @description Uploads a tar.gz archive and extracts it to the destination directory.
*/
fs_upload_batch: {
parameters: {
query?: {
/** @description Destination directory for extraction */
path?: string | null;
/** @description Session id for relative paths */
session_id?: string | null;
};
};
requestBody: {
content: {
"application/octet-stream": string;
};
};
responses: {
/** @description Upload result */
200: {
content: {
"application/json": components["schemas"]["FsUploadBatchResponse"];
};
};
};
};
/**
* Health Check
* @description Returns the server health status.
*/
get_health: {
responses: {
/** @description Server is healthy */
200: {
content: {
"application/json": components["schemas"]["HealthResponse"];
@ -463,8 +916,13 @@ export interface operations {
};
};
};
/**
* List Sessions
* @description Returns all active sessions.
*/
list_sessions: {
responses: {
/** @description List of active sessions */
200: {
content: {
"application/json": components["schemas"]["SessionListResponse"];
@ -472,6 +930,10 @@ export interface operations {
};
};
};
/**
* Create Session
* @description Creates a new agent session with the given configuration.
*/
create_session: {
parameters: {
path: {
@ -485,16 +947,19 @@ export interface operations {
};
};
responses: {
/** @description Session created */
200: {
content: {
"application/json": components["schemas"]["CreateSessionResponse"];
};
};
/** @description Invalid request */
400: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
};
};
/** @description Session already exists */
409: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -502,6 +967,10 @@ export interface operations {
};
};
};
/**
* Get Events
* @description Returns session events with optional offset-based pagination.
*/
get_events: {
parameters: {
query?: {
@ -518,11 +987,13 @@ export interface operations {
};
};
responses: {
/** @description Session events */
200: {
content: {
"application/json": components["schemas"]["EventsResponse"];
};
};
/** @description Session not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -530,6 +1001,10 @@ export interface operations {
};
};
};
/**
* Subscribe to Events (SSE)
* @description Opens an SSE stream for real-time session events.
*/
get_events_sse: {
parameters: {
query?: {
@ -550,6 +1025,10 @@ export interface operations {
};
};
};
/**
* Send Message
* @description Sends a message to a session and returns immediately.
*/
post_message: {
parameters: {
path: {
@ -567,6 +1046,7 @@ export interface operations {
204: {
content: never;
};
/** @description Session not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -574,6 +1054,10 @@ export interface operations {
};
};
};
/**
* Send Message (Streaming)
* @description Sends a message and returns an SSE event stream of the agent's response.
*/
post_message_stream: {
parameters: {
query?: {
@ -595,6 +1079,7 @@ export interface operations {
200: {
content: never;
};
/** @description Session not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -602,6 +1087,10 @@ export interface operations {
};
};
};
/**
* Reply to Permission
* @description Approves or denies a permission request from the agent.
*/
reply_permission: {
parameters: {
path: {
@ -621,6 +1110,7 @@ export interface operations {
204: {
content: never;
};
/** @description Session or permission not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -628,6 +1118,10 @@ export interface operations {
};
};
};
/**
* Reject Question
* @description Rejects a human-in-the-loop question from the agent.
*/
reject_question: {
parameters: {
path: {
@ -642,6 +1136,7 @@ export interface operations {
204: {
content: never;
};
/** @description Session or question not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -649,6 +1144,10 @@ export interface operations {
};
};
};
/**
* Reply to Question
* @description Replies to a human-in-the-loop question from the agent.
*/
reply_question: {
parameters: {
path: {
@ -668,6 +1167,7 @@ export interface operations {
204: {
content: never;
};
/** @description Session or question not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];
@ -675,6 +1175,10 @@ export interface operations {
};
};
};
/**
* Terminate Session
* @description Terminates a running session and cleans up resources.
*/
terminate_session: {
parameters: {
path: {
@ -687,6 +1191,7 @@ export interface operations {
204: {
content: never;
};
/** @description Session not found */
404: {
content: {
"application/json": components["schemas"]["ProblemDetails"];

View file

@ -23,12 +23,26 @@ export type {
EventsQuery,
EventsResponse,
FileAction,
FsActionResponse,
FsDeleteQuery,
FsEntriesQuery,
FsEntry,
FsEntryType,
FsMoveRequest,
FsMoveResponse,
FsPathQuery,
FsSessionQuery,
FsStat,
FsUploadBatchQuery,
FsUploadBatchResponse,
FsWriteResponse,
HealthResponse,
ItemDeltaData,
ItemEventData,
ItemKind,
ItemRole,
ItemStatus,
MessageAttachment,
MessageRequest,
PermissionEventData,
PermissionReply,
@ -50,6 +64,13 @@ export type {
UniversalEventData,
UniversalEventType,
UniversalItem,
McpServerConfig,
McpCommand,
McpRemoteTransport,
McpOAuthConfig,
McpOAuthConfigOrDisabled,
SkillSource,
SkillsConfig,
} from "./types.ts";
export type { components, paths } from "./generated/openapi.ts";
export type { SandboxAgentSpawnOptions, SandboxAgentSpawnLogMode } from "./spawn.ts";

View file

@ -19,6 +19,19 @@ export type EventSource = S["EventSource"];
export type EventsQuery = S["EventsQuery"];
export type EventsResponse = S["EventsResponse"];
export type FileAction = S["FileAction"];
export type FsActionResponse = S["FsActionResponse"];
export type FsDeleteQuery = S["FsDeleteQuery"];
export type FsEntriesQuery = S["FsEntriesQuery"];
export type FsEntry = S["FsEntry"];
export type FsEntryType = S["FsEntryType"];
export type FsMoveRequest = S["FsMoveRequest"];
export type FsMoveResponse = S["FsMoveResponse"];
export type FsPathQuery = S["FsPathQuery"];
export type FsSessionQuery = S["FsSessionQuery"];
export type FsStat = S["FsStat"];
export type FsUploadBatchQuery = S["FsUploadBatchQuery"];
export type FsUploadBatchResponse = S["FsUploadBatchResponse"];
export type FsWriteResponse = S["FsWriteResponse"];
export type HealthResponse = S["HealthResponse"];
export type ItemDeltaData = S["ItemDeltaData"];
export type ItemEventData = S["ItemEventData"];
@ -26,6 +39,7 @@ export type ItemKind = S["ItemKind"];
export type ItemRole = S["ItemRole"];
export type ItemStatus = S["ItemStatus"];
export type MessageRequest = S["MessageRequest"];
export type MessageAttachment = S["MessageAttachment"];
export type PermissionEventData = S["PermissionEventData"];
export type PermissionReply = S["PermissionReply"];
export type PermissionReplyRequest = S["PermissionReplyRequest"];
@ -46,3 +60,11 @@ export type UniversalEvent = S["UniversalEvent"];
export type UniversalEventData = S["UniversalEventData"];
export type UniversalEventType = S["UniversalEventType"];
export type UniversalItem = S["UniversalItem"];
export type McpServerConfig = S["McpServerConfig"];
export type McpCommand = S["McpCommand"];
export type McpRemoteTransport = S["McpRemoteTransport"];
export type McpOAuthConfig = S["McpOAuthConfig"];
export type McpOAuthConfigOrDisabled = S["McpOAuthConfigOrDisabled"];
export type SkillSource = S["SkillSource"];
export type SkillsConfig = S["SkillsConfig"];