Open Harness API

A standardized interface for AI agent harnesses enabling interoperability across Claude Code, Goose, LangChain Deep Agent, Letta, and more.

Base URL https://api.openharness.org/v1
Auth Bearer token
Format MAPI v0.93
13
Domains
107
Capabilities
50+
Types
6
Transports

Transport Protocols

REST Standard HTTP request/response
SSE Server-Sent Events streaming
WS WebSocket bidirectional
Multipart File upload (multipart/form-data)
Binary Binary file download
ZIP Bundled archive download
Webhook Async callback notification

1. Harness Registry

8 capabilities
GET /harnesses REST harnesses.list
Intention

Retrieves all registered harnesses with their current status and capabilities. Use this to discover available harnesses and their supported features before executing operations.

Input
interface ListHarnessesRequest extends PaginationParams {
  status?: HarnessStatus;        // Filter by status
  execution_type?: ExecutionType; // Filter by type
}
Output
interface ListHarnessesResponse extends PaginatedResponse<Harness> {}
GET /harnesses/{harnessId} REST harnesses.get
Intention

Retrieves detailed information about a specific harness including its full capability manifest.

POST /harnesses REST harnesses.register
Intention

Registers a new harness with the Open Harness system. Typically used by harness vendors or administrators to add support for a new agent harness.

PATCH /harnesses/{harnessId} REST harnesses.update
Intention

Updates configuration for an existing harness.

DELETE /harnesses/{harnessId} REST harnesses.unregister
Intention

Removes a harness from the registry. This does not uninstall the harness itself, only removes it from Open Harness management.

Logic Constraints
  • Cannot unregister a harness with active sessions or running executions
  • Credentials associated with this harness will be deleted
GET /harnesses/{harnessId}/capabilities REST harnesses.capabilities
Intention

Retrieves the full capability manifest for a harness. Use this to determine which operations are supported before attempting them.

GET /harnesses/{harnessId}/health REST harnesses.health
Intention

Checks connectivity and health of a harness. Returns status information useful for monitoring and debugging.

POST /harnesses/{harnessId}/validate-credentials REST harnesses.validateCredentials
Intention

Validates API credentials for a harness and optionally stores them for future use.

2. Agents

8 capabilities
GET /harnesses/{harnessId}/agents REST agents.list
Intention

Lists all agents deployed on a specific harness.

POST /harnesses/{harnessId}/agents Multipart agents.create
Intention

Creates and deploys a new agent on the harness. The agent bundle includes the AGENTS.md manifest and any supporting files.

Logic Constraints
  • Agent name in AGENTS.md frontmatter must be unique on this harness
  • Maximum bundle size: 50MB
  • Files array preserves directory structure via filename paths
  • AGENTS.md is required at the root of the bundle
GET /harnesses/{harnessId}/agents/{agentId} REST agents.get
Intention

Retrieves the current state and configuration of an agent.

PATCH /harnesses/{harnessId}/agents/{agentId} REST agents.update
Intention

Updates agent configuration without redeploying the full bundle.

DELETE /harnesses/{harnessId}/agents/{agentId} REST agents.delete
Intention

Removes an agent from the harness.

Logic Constraints
  • Cannot delete an agent with active sessions
  • Associated memory blocks will be deleted
POST /harnesses/{harnessId}/agents/{agentId}/clone REST agents.clone
Intention

Creates a copy of an existing agent with a new name.

GET /harnesses/{harnessId}/agents/{agentId}/export ZIP agents.export
Intention

Downloads the complete agent bundle as a ZIP file, including AGENTS.md and all supporting files.

POST /harnesses/{harnessId}/agents/import Multipart agents.import
Intention

Imports an agent from a previously exported bundle or external source.

3. Skills

11 capabilities
GET /harnesses/{harnessId}/skills REST skills.list
Intention

Lists all skills installed or registered on the harness.

POST /harnesses/{harnessId}/skills Multipart skills.register
Intention

Registers or installs a skill on the harness. Skills consist of a SKILL.md manifest plus optional supporting files.

Logic Constraints
  • Skill name in SKILL.md frontmatter must match root directory name
  • Maximum bundle size: 10MB
  • SKILL.md is required at the root
  • Binary assets should be in an assets/ subdirectory
GET /harnesses/{harnessId}/skills/{skillId} REST skills.get
Intention

Retrieves details about a specific skill.

DELETE /harnesses/{harnessId}/skills/{skillId} REST skills.uninstall
Intention

Uninstalls or unregisters a skill from the harness.

GET /harnesses/{harnessId}/skills/{skillId}/versions REST skills.listVersions
Intention

Lists all available versions of a skill.

POST /harnesses/{harnessId}/skills/{skillId}/rollback REST skills.rollback
Intention

Reverts a skill to a previous version.

POST /harnesses/{harnessId}/skills/discover REST skills.discover
Intention

Discovers skills available on the harness that are not yet registered. Useful for finding built-in or auto-detected skills.

POST /harnesses/{harnessId}/skills/validate Multipart skills.validate
Intention

Validates a skill bundle without installing it. Returns any errors or warnings.

GET /harnesses/{harnessId}/skills/{skillId}/download ZIP skills.download
Intention

Downloads the complete skill bundle as a ZIP file.

POST /harnesses/{harnessId}/skills/{skillId}/upgrade Multipart skills.upgrade
Intention

Upgrades an existing skill to a new version.

PATCH /harnesses/{harnessId}/skills/{skillId} REST skills.update
Intention

Updates skill metadata without uploading a new version.

6. Execution

11 capabilities
POST /harnesses/{harnessId}/execute REST execution.run
Intention

Executes a task on the harness. Returns immediately with an execution ID; use the stream endpoint to follow progress.

Input
interface ExecuteRequest {
  harnessId: HarnessId;        // path parameter
  message: string;            // 1-100000 chars
  agent_id?: AgentId;         // Use specific agent
  skills?: SkillId[];          // Skills to enable
  model?: string;             // Override default model
  max_tokens?: number;        // 1-200000
  temperature?: number;       // 0.0-1.0
}
POST /harnesses/{harnessId}/execute/stream SSE execution.stream
Intention

Executes a task with streaming response. Use this for real-time feedback during execution.

Logic Constraints
  • Client should handle reconnection using Last-Event-ID header
  • Stream may include multiple tool calls before completion
  • done event signals stream completion
Output (SSE Events)
type ExecutionEvent =
  | { type: "text"; content: string }
  | { type: "thinking"; content: string }
  | { type: "tool_call_start"; id: string; name: string }
  | { type: "tool_call_delta"; id: string; input_delta: object }
  | { type: "tool_call_end"; id: string }
  | { type: "tool_result"; id: string; success: boolean }
  | { type: "artifact"; id: string; name: string; mime_type: string }
  | { type: "progress"; percentage: number; step: string }
  | { type: "error"; code: string; message: string }
  | { type: "done"; usage: UsageStats };
GET /harnesses/{harnessId}/executions/{executionId}/stream SSE execution.attachStream
Intention

Attaches to an existing execution's event stream. Use Last-Event-ID header to resume from a specific point.

POST /harnesses/{harnessId}/executions/{executionId}/cancel REST execution.cancel
Intention

Cancels a running execution.

GET /harnesses/{harnessId}/executions/{executionId}/artifacts/{artifactId} Binary execution.downloadArtifact
Intention

Downloads a specific artifact generated by an execution.

Logic Constraints
  • Content-Type header matches the artifact's MIME type
  • Content-Disposition header contains original filename
  • Large files use chunked transfer encoding

7. Sessions

11 capabilities
WS /harnesses/{harnessId}/sessions/{sessionId}/connect WebSocket sessions.connect
Intention

Establishes a WebSocket connection for real-time interactive communication with a session.

Client Messages
type ClientMessage =
  | { type: "message"; id: string; content: string }
  | { type: "stdin"; id: string; data: string }
  | { type: "cancel"; execution_id: string };
Server Messages
type ServerMessage =
  | { type: "text"; id: string; content: string }
  | { type: "tool_call"; id: string; tool: string }
  | { type: "stdout"; id: string; data: string }
  | { type: "prompt"; id: string; prompt: string }
  | { type: "done"; id: string; usage: UsageStats };
POST /harnesses/{harnessId}/sessions REST sessions.create
Intention

Creates a new interactive session.

POST /harnesses/{harnessId}/sessions/{sessionId}/message/stream SSE sessions.sendMessageStream
Intention

Sends a message to a session with streaming response.

POST /harnesses/{harnessId}/sessions/{sessionId}/fork REST sessions.fork
Intention

Creates a copy of a session with its history, allowing experimentation from a specific point.

11. Hooks & Events

9 capabilities
GET /harnesses/{harnessId}/events/stream SSE hooks.streamEvents
Intention

Subscribes to real-time events from the harness.

WEBHOOK {callback_url} Webhook webhooks.executionCompleted
Intention

Notifies when an execution completes.

Payload
interface ExecutionCompletedWebhook {
  event: "execution.completed";
  execution_id: ExecutionId;
  harness_id: HarnessId;
  status: ExecutionStatus;
  artifacts: ArtifactSummary[];
  signature: string;     // HMAC-SHA256
}
Logic Constraints
  • Signature: HMAC-SHA256 of raw body using webhook secret
  • Header: X-OpenHarness-Signature: sha256=<signature>
  • Timeout: 30 seconds
  • Retry: exponential backoff (1min, 5min, 30min, 2hr)
POST /harnesses/{harnessId}/webhooks REST webhooks.register
Intention

Registers a webhook endpoint to receive async notifications.

4. MCP Servers

9 capabilities
GET /harnesses/{harnessId}/mcp-servers REST mcp.list
Intention

Lists all MCP servers connected to the harness.

POST /harnesses/{harnessId}/mcp-servers REST mcp.connect
Intention

Connects a new MCP server to the harness.

Input
interface ConnectMcpServerRequest {
  name: string;           // 1-100 chars
  transport: McpTransport;
  auto_reconnect?: boolean; // default: true
}

type McpTransport =
  | { type: "stdio"; command: string; args?: string[] }
  | { type: "http"; url: string }
  | { type: "sse"; url: string };
GET /harnesses/{harnessId}/mcp-servers/{serverId} REST mcp.get
Intention

Retrieves details about a connected MCP server.

PATCH /harnesses/{harnessId}/mcp-servers/{serverId} REST mcp.update
Intention

Updates MCP server configuration.

DELETE /harnesses/{harnessId}/mcp-servers/{serverId} REST mcp.disconnect
Intention

Disconnects an MCP server from the harness.

GET /harnesses/{harnessId}/mcp-servers/{serverId}/tools REST mcp.listTools
Intention

Lists all tools provided by an MCP server.

GET /harnesses/{harnessId}/mcp-servers/{serverId}/resources REST mcp.listResources
Intention

Lists all resources provided by an MCP server.

GET /harnesses/{harnessId}/mcp-servers/{serverId}/prompts REST mcp.listPrompts
Intention

Lists all prompts provided by an MCP server.

POST /harnesses/{harnessId}/mcp-servers/{serverId}/health REST mcp.health
Intention

Checks the health and connectivity of an MCP server.

5. Tools

6 capabilities
GET /harnesses/{harnessId}/tools REST tools.list
Intention

Lists all available tools on the harness, including built-in tools, MCP tools, and skill-provided tools.

Output
interface Tool {
  id: string;
  name: string;
  description: string;
  source: "builtin" | "mcp" | "skill" | "custom";
  source_id?: string;        // MCP server ID or skill ID
  input_schema: object;
}
GET /harnesses/{harnessId}/tools/{toolId} REST tools.get
Intention

Retrieves the schema and details for a specific tool.

POST /harnesses/{harnessId}/tools REST tools.register
Intention

Registers a custom tool with the harness.

Input
interface RegisterToolRequest {
  name: string;            // 1-100 chars
  description: string;     // 1-1000 chars
  input_schema: object;    // JSON Schema
  handler: ToolHandler;
}

type ToolHandler =
  | { type: "webhook"; url: string }
  | { type: "command"; command: string; args?: string[] };
DELETE /harnesses/{harnessId}/tools/{toolId} REST tools.unregister
Intention

Unregisters a custom tool from the harness.

Logic Constraints
  • Can only unregister custom tools, not built-in or MCP tools
POST /harnesses/{harnessId}/tools/{toolId}/invoke REST tools.invoke
Intention

Directly invokes a tool outside of an execution context.

POST /harnesses/{harnessId}/tools/{toolId}/invoke/stream SSE tools.invokeStream
Intention

Invokes a tool with streaming output. Useful for tools that produce incremental results.

Output (SSE Events)
type ToolStreamEvent =
  | { type: "output"; data: object }
  | { type: "progress"; percentage: number; message: string }
  | { type: "error"; code: string; message: string }
  | { type: "done"; success: boolean; duration_ms: number };

8. Memory

11 capabilities
GET /harnesses/{harnessId}/agents/{agentId}/memory REST memory.get
Intention

Retrieves the complete memory state for an agent.

Output
interface MemoryState {
  agent_id: AgentId;
  blocks: MemoryBlock[];
  archive_size: number;
}

interface MemoryBlock {
  label: string;
  value: string;
  read_only: boolean;
  updated_at: ISO8601;
}
GET /harnesses/{harnessId}/agents/{agentId}/memory/blocks REST memory.listBlocks
Intention

Lists all memory blocks for an agent.

GET /harnesses/{harnessId}/agents/{agentId}/memory/blocks/{label} REST memory.getBlock
Intention

Retrieves a specific memory block by label.

POST /harnesses/{harnessId}/agents/{agentId}/memory/blocks REST memory.createBlock
Intention

Creates a new memory block for an agent.

Logic Constraints
  • Label must be unique for this agent
  • Labels should be descriptive (e.g., "persona", "user_preferences")
PUT /harnesses/{harnessId}/agents/{agentId}/memory/blocks/{label} REST memory.updateBlock
Intention

Updates the value of a memory block.

Logic Constraints
  • Cannot update read-only blocks
DELETE /harnesses/{harnessId}/agents/{agentId}/memory/blocks/{label} REST memory.deleteBlock
Intention

Deletes a memory block.

Logic Constraints
  • Cannot delete read-only blocks
POST /harnesses/{harnessId}/agents/{agentId}/memory/search REST memory.search
Intention

Searches across memory blocks and archive for relevant content.

Output
interface MemorySearchResult {
  source: "block" | "archive";
  label?: string;          // For block results
  content: string;
  relevance_score: number;  // 0.0-1.0
}
GET /harnesses/{harnessId}/agents/{agentId}/memory/archive REST memory.getArchive
Intention

Retrieves the archival/long-term memory for an agent.

POST /harnesses/{harnessId}/agents/{agentId}/memory/archive REST memory.addToArchive
Intention

Adds an entry to the agent's archival memory.

POST /harnesses/{harnessId}/agents/{agentId}/memory/export ZIP memory.export
Intention

Exports the complete memory state as a downloadable snapshot.

Logic Constraints
  • ZIP contains blocks.json and archive.json
POST /harnesses/{harnessId}/agents/{agentId}/memory/import Multipart memory.import
Intention

Imports a previously exported memory snapshot.

Logic Constraints
  • Existing blocks with same labels will be overwritten
  • Archive entries are appended, not replaced

9. Subagents

8 capabilities
GET /harnesses/{harnessId}/agents/{agentId}/subagents REST subagents.list
Intention

Lists all subagents spawned by a parent agent.

Output
interface Subagent {
  id: string;
  name: string;
  description: string;
  status: "idle" | "running" | "completed" | "failed";
  parent_agent_id: AgentId;
  created_at: ISO8601;
}
POST /harnesses/{harnessId}/agents/{agentId}/subagents REST subagents.spawn
Intention

Spawns a new subagent to handle a specific task in isolation.

GET /harnesses/{harnessId}/agents/{agentId}/subagents/{subagentId} REST subagents.get
Intention

Retrieves the current state of a subagent.

DELETE /harnesses/{harnessId}/agents/{agentId}/subagents/{subagentId} REST subagents.terminate
Intention

Terminates a running subagent.

POST /harnesses/{harnessId}/agents/{agentId}/subagents/{subagentId}/delegate REST subagents.delegate
Intention

Delegates a task to a subagent and waits for completion.

POST /harnesses/{harnessId}/agents/{agentId}/subagents/{subagentId}/delegate/stream SSE subagents.delegateStream
Intention

Delegates a task to a subagent with streaming progress.

GET /harnesses/{harnessId}/agents/{agentId}/subagents/{subagentId}/result REST subagents.result
Intention

Retrieves the result of a completed subagent task.

GET /harnesses/{harnessId}/agents/{agentId}/subagents/{subagentId}/stream SSE subagents.attachStream
Intention

Attaches to a running subagent's execution stream.

10. Files & Artifacts

10 capabilities
GET /harnesses/{harnessId}/files REST files.list
Intention

Lists files in the harness workspace.

GET /harnesses/{harnessId}/files/{path} Binary files.read
Intention

Reads the contents of a file.

PUT /harnesses/{harnessId}/files/{path} REST files.write
Intention

Writes content to a file, creating it if it doesn't exist.

Logic Constraints
  • Creates parent directories if they don't exist
  • Overwrites existing files
DELETE /harnesses/{harnessId}/files/{path} REST files.delete
Intention

Deletes a file or empty directory.

POST /harnesses/{harnessId}/files/search REST files.search
Intention

Searches for files using glob patterns or content grep.

POST /harnesses/{harnessId}/files/upload Multipart files.upload
Intention

Uploads a single file to the workspace.

POST /harnesses/{harnessId}/files/upload-batch Multipart files.uploadBatch
Intention

Uploads multiple files preserving directory structure.

Logic Constraints
  • Maximum total size: 100MB
  • Maximum 500 files per batch
GET /harnesses/{harnessId}/files/{path}/download Binary files.download
Intention

Downloads a file with Content-Disposition header for saving.

POST /harnesses/{harnessId}/files/download-batch ZIP files.downloadBatch
Intention

Downloads multiple files as a ZIP archive.

POST /harnesses/{harnessId}/files/mkdir REST files.mkdir
Intention

Creates a directory and any necessary parent directories.

12. Planning & Tasks

5 capabilities
GET /harnesses/{harnessId}/executions/{executionId}/plan REST planning.get
Intention

Retrieves the current execution plan (todo list).

Output
interface Plan {
  execution_id: ExecutionId;
  tasks: PlanTask[];
  updated_at: ISO8601;
}

interface PlanTask {
  id: string;
  content: string;
  status: "pending" | "in_progress" | "completed";
  order: number;
}
PATCH /harnesses/{harnessId}/executions/{executionId}/plan REST planning.update
Intention

Updates the execution plan, typically to add or reorder tasks.

GET /harnesses/{harnessId}/executions/{executionId}/plan/tasks REST planning.listTasks
Intention

Lists all tasks in the execution plan.

PATCH /harnesses/{harnessId}/executions/{executionId}/plan/tasks/{taskId} REST planning.updateTask
Intention

Updates a specific task's status or content.

GET /harnesses/{harnessId}/executions/{executionId}/plan/stream SSE planning.stream
Intention

Subscribes to real-time plan updates during execution.

Output (SSE Events)
type PlanEvent =
  | { type: "task.added"; task: PlanTask }
  | { type: "task.updated"; task: PlanTask }
  | { type: "task.removed"; task_id: string }
  | { type: "plan.reordered"; task_ids: string[] };

13. Conformance & Diagnostics

7 capabilities
POST /harnesses/{harnessId}/conformance/run REST conformance.run
Intention

Initiates a conformance test run against a harness.

GET /harnesses/{harnessId}/conformance/run/stream SSE conformance.stream
Intention

Streams real-time progress of conformance tests.

Output (SSE Events)
type ConformanceEvent =
  | { type: "test.started"; test_id: string; test_name: string }
  | { type: "test.passed"; test_id: string }
  | { type: "test.failed"; test_id: string; error: string }
  | { type: "progress"; completed: number; total: number }
  | { type: "done"; result: ConformanceResult };
GET /harnesses/{harnessId}/conformance/results REST conformance.results
Intention

Retrieves results from conformance test runs.

GET /harnesses/{harnessId}/conformance/status REST conformance.status
Intention

Retrieves the current conformance certification status.

Output
interface ConformanceStatus {
  status: "certified" | "partial" | "failing" | "not_tested";
  certified_version?: string;
  pass_rate: number;           // 0.0-1.0
  golden_rule_compliant: boolean;
}
GET /harnesses/{harnessId}/diagnostics REST diagnostics.get
Intention

Retrieves diagnostic information about the harness.

Output
interface DiagnosticsResponse {
  harness_id: HarnessId;
  version: string;
  uptime_seconds: number;
  memory_usage_mb: number;
  active_sessions: number;
  active_executions: number;
  connected_mcp_servers: number;
  installed_skills: number;
}
GET /harnesses/{harnessId}/logs REST diagnostics.logs
Intention

Retrieves recent logs from the harness.

GET /harnesses/{harnessId}/logs/stream SSE diagnostics.streamLogs
Intention

Streams logs in real-time. Useful for debugging and monitoring.