openapi: 3.1.0
info:
title: Warmplane HTTP Facade API
version: "v1"
description: |
Warmplane exposes a compact, deterministic HTTP facade over multiple upstream MCP servers.
This API is index-first: list compact capability/resource/prompt entries, then request detail
or execute operations on-demand.
servers:
- url: http://127.0.0.1:9090
description: local default
paths:
/v1/capabilities:
get:
summary: List capabilities
operationId: listCapabilities
responses:
"200":
description: Capability index with cache hints
headers:
ETag:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/CapabilitiesListResponse"
"304":
description: Not Modified (catalog unchanged)
/v1/capabilities/search:
post:
summary: Search capabilities
operationId: searchCapabilities
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SearchCapabilitiesRequest"
responses:
"200":
description: Ranked search results
content:
application/json:
schema:
$ref: "#/components/schemas/SearchCapabilitiesResponse"
/v1/capabilities/{id}:
get:
summary: Describe capability
operationId: describeCapability
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"200":
description: Capability detail
content:
application/json:
schema:
$ref: "#/components/schemas/CapabilityDescribeResponse"
"404":
description: Capability not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/v1/tools/call:
post:
summary: Execute capability
operationId: callCapability
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CallCapabilityRequest"
responses:
"200":
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessEnvelope"
"400":
description: Invalid request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"403":
description: Policy blocked
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"404":
description: Capability not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"502":
description: Upstream error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"504":
description: Upstream timeout
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/v1/tools/batch_call:
post:
summary: Execute chained multi-step batch capabilities
operationId: batchCallCapabilities
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BatchCallRequest"
responses:
"200":
description: Batch execution summary response
content:
application/json:
schema:
$ref: "#/components/schemas/BatchCallResponse"
/v1/resources:
get:
summary: List resources
operationId: listResources
responses:
"200":
description: Resource index with cache hints
headers:
ETag:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/ResourcesListResponse"
"304":
description: Not Modified (catalog unchanged)
/v1/resources/read:
post:
summary: Read resource
operationId: readResource
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ReadResourceRequest"
responses:
"200":
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessEnvelope"
"400":
description: Invalid request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"403":
description: Policy blocked
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"404":
description: Resource not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"502":
description: Upstream error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"504":
description: Upstream timeout
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/v1/resources/updates:
get:
summary: Real-time resource update SSE feed
operationId: resourceUpdates
responses:
"200":
description: SSE event stream
content:
text/event-stream:
schema:
type: string
/v1/prompts:
get:
summary: List prompts
operationId: listPrompts
responses:
"200":
description: Prompt index with cache hints
headers:
ETag:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/PromptsListResponse"
"304":
description: Not Modified (catalog unchanged)
/v1/prompts/get:
post:
summary: Get prompt output
operationId: getPrompt
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/GetPromptRequest"
responses:
"200":
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/SuccessEnvelope"
"400":
description: Invalid request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"403":
description: Policy blocked
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"404":
description: Prompt not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"502":
description: Upstream error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"504":
description: Upstream timeout
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/v1/catalog/events:
get:
summary: Catalog mutation events change feed
operationId: catalogEvents
parameters:
- in: query
name: after
required: false
schema:
type: string
responses:
"200":
description: Event log feed
content:
application/json:
schema:
$ref: "#/components/schemas/CatalogEventsResponse"
/v1/completion/complete:
post:
summary: Argument completion for prompt or resource
operationId: completeArgument
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CompletionRequest"
responses:
"200":
description: Completion candidate results
content:
application/json:
schema:
$ref: "#/components/schemas/CompletionResponse"
/v1/sampling/create_message:
post:
summary: Sampling completion delegation
operationId: samplingCreateMessage
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SamplingRequest"
responses:
"200":
description: Sampling response
content:
application/json:
schema:
$ref: "#/components/schemas/SamplingResponse"
/v1/config:
get:
summary: Get active configuration and metrics
operationId: getConfig
responses:
"200":
description: Active configuration and runtime metrics
/v1/config/servers:
post:
summary: Upsert upstream server with hot-mounting
operationId: upsertServer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpsertServerRequest"
responses:
"200":
description: Server upserted and mounted
/v1/config/servers/{id}:
delete:
summary: Delete upstream server and unmount dynamically
operationId: deleteServer
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"200":
description: Server deleted and unmounted
/v1/config/ecosystem:
get:
summary: Discover external MCP server configurations from Claude Desktop, Cursor, or Zed
operationId: getEcosystemSources
responses:
"200":
description: Discovered ecosystem configuration files and servers
/v1/config/import:
post:
summary: Import MCP servers from external client configurations
operationId: importConfig
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ImportConfigRequest"
responses:
"200":
description: Summary of imported servers
/v1/config/alias:
post:
summary: Add or remove capability, resource, or prompt aliases
operationId: updateAlias
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateAliasRequest"
responses:
"200":
description: Alias updated
/v1/config/policy:
post:
summary: Update security policy rules, approval requirements, and redaction keys
operationId: updatePolicy
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PolicyConfig"
responses:
"200":
description: Policy updated
/v1/config/reload:
post:
summary: Hot-reload daemon configuration and upstream servers from disk
operationId: reloadConfig
responses:
"200":
description: Summary of mounted, unmounted, and updated servers
/v1/approvals:
get:
summary: List pending and resolved human approval tickets
operationId: listApprovals
responses:
"200":
description: List of approval tickets
content:
application/json:
schema:
$ref: "#/components/schemas/ListApprovalsResponse"
/v1/approvals/{id}:
get:
summary: Get details and sanitized parameters for an approval ticket
operationId: getApproval
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"200":
description: Approval ticket details
content:
application/json:
schema:
$ref: "#/components/schemas/GetApprovalResponse"
"404":
description: Approval ticket not found
/v1/approvals/{id}/approve:
post:
summary: Approve a suspended capability execution
operationId: approveTicket
parameters:
- in: path
name: id
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ApproveTicketRequest"
responses:
"200":
description: Ticket approved and execution resumed
"409":
description: Ticket is not pending or already resolved
/v1/approvals/{id}/reject:
post:
summary: Reject a suspended capability execution
operationId: rejectTicket
parameters:
- in: path
name: id
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RejectTicketRequest"
responses:
"200":
description: Ticket rejected
"409":
description: Ticket is not pending or already resolved
/v1/audit/events:
get:
summary: Query paginated WORM audit events with filters
operationId: listAuditEvents
parameters:
- in: query
name: actor_id
schema:
type: string
- in: query
name: capability_id
schema:
type: string
- in: query
name: event_type
schema:
type: string
- in: query
name: limit
schema:
type: integer
default: 50
- in: query
name: offset
schema:
type: integer
default: 0
responses:
"200":
description: List of audit events
/v1/audit/events/{id}:
get:
summary: Get details of a single audit event record
operationId: getAuditEvent
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"200":
description: Audit event record
"404":
description: Audit event not found
/v1/audit/verify:
get:
summary: Verify complete cryptographic SHA-256 hash chain integrity
operationId: verifyAuditChain
responses:
"200":
description: Hash chain verification report
/v1/audit/stats:
get:
summary: Retrieve summary metrics and event breakdown of the audit log
operationId: getAuditStats
responses:
"200":
description: Aggregate audit statistics
/v1/audit/export:
get:
summary: Export raw audit log as JSONL or CSV file attachment
operationId: exportAuditLog
parameters:
- in: query
name: format
schema:
type: string
enum: [jsonl, csv]
default: jsonl
responses:
"200":
description: Streamed audit log file
/v1/operations/{id}/cancel:
post:
summary: Cancel in-flight operation
operationId: cancelOperation
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"200":
description: Operation cancelled
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
request_id:
type: string
cancelled:
type: boolean
components:
schemas:
CapabilityListItem:
type: object
required: [id, summary, server, tool, tags]
properties:
id:
type: string
summary:
type: string
server:
type: string
tool:
type: string
tags:
type: array
items:
type: string
ResourceListItem:
type: object
required: [id, server, uri, name, tags]
properties:
id:
type: string
server:
type: string
uri:
type: string
name:
type: string
description:
type: [string, "null"]
mime_type:
type: [string, "null"]
tags:
type: array
items:
type: string
PromptListItem:
type: object
required: [id, server, name, arguments, tags]
properties:
id:
type: string
server:
type: string
name:
type: string
title:
type: [string, "null"]
description:
type: [string, "null"]
arguments:
type: array
items:
type: object
tags:
type: array
items:
type: string
CapabilitiesListResponse:
type: object
required: [version, catalog_version, ttl_ms, cache_scope, capabilities]
properties:
version:
type: string
const: v1
catalog_version:
type: string
ttl_ms:
type: integer
example: 300000
cache_scope:
type: string
example: "public"
capabilities:
type: array
items:
$ref: "#/components/schemas/CapabilityListItem"
CapabilityDescribeResponse:
type: object
required: [version, capability]
properties:
version:
type: string
const: v1
catalog_version:
type: string
capability:
type: object
required: [id, server, tool, description, input_schema, examples]
properties:
id:
type: string
server:
type: string
tool:
type: string
description:
type: string
input_schema:
type: object
examples:
type: array
items: {}
ResourcesListResponse:
type: object
required: [version, catalog_version, ttl_ms, cache_scope, resources]
properties:
version:
type: string
const: v1
catalog_version:
type: string
ttl_ms:
type: integer
example: 300000
cache_scope:
type: string
example: "public"
resources:
type: array
items:
$ref: "#/components/schemas/ResourceListItem"
PromptsListResponse:
type: object
required: [version, catalog_version, ttl_ms, cache_scope, prompts]
properties:
version:
type: string
const: v1
catalog_version:
type: string
ttl_ms:
type: integer
example: 300000
cache_scope:
type: string
example: "public"
prompts:
type: array
items:
$ref: "#/components/schemas/PromptListItem"
SearchCapabilitiesRequest:
type: object
properties:
query:
type: [string, "null"]
limit:
type: integer
default: 8
server_ids:
type: array
items:
type: string
tags:
type: array
items:
type: string
modes:
type: array
items:
type: string
SearchCapabilitiesResponse:
type: object
required: [version, catalog_version, capabilities]
properties:
version:
type: string
catalog_version:
type: string
capabilities:
type: array
items:
type: object
CallCapabilityRequest:
type: object
required: [capability_id, args]
properties:
capability_id:
type: string
args:
type: object
request_id:
type: [string, "null"]
context:
$ref: "#/components/schemas/RequestContext"
idempotency_key:
type: [string, "null"]
input_responses:
type: [object, "null"]
description: MRTR client responses for interactive tool turns
request_state:
type: [string, "null"]
description: MRTR opaque state string
ReadResourceRequest:
type: object
required: [resource_id]
properties:
resource_id:
type: string
request_id:
type: [string, "null"]
context:
$ref: "#/components/schemas/RequestContext"
idempotency_key:
type: [string, "null"]
input_responses:
type: [object, "null"]
request_state:
type: [string, "null"]
GetPromptRequest:
type: object
required: [prompt_id]
properties:
prompt_id:
type: string
arguments:
type: [object, "null"]
request_id:
type: [string, "null"]
context:
$ref: "#/components/schemas/RequestContext"
idempotency_key:
type: [string, "null"]
input_responses:
type: [object, "null"]
request_state:
type: [string, "null"]
CompletionRequest:
type: object
required: [ref_type, ref_name, argument_name]
properties:
ref_type:
type: string
enum: [prompt, resource]
ref_name:
type: string
argument_name:
type: string
argument_value:
type: string
CompletionResponse:
type: object
properties:
ok:
type: boolean
trace_id:
type: string
data:
type: object
SamplingRequest:
type: object
required: [server_id, messages]
properties:
server_id:
type: string
messages:
type: array
items:
type: object
max_tokens:
type: [integer, "null"]
SamplingResponse:
type: object
properties:
ok:
type: boolean
trace_id:
type: string
data:
type: object
CatalogEventsResponse:
type: object
required: [catalog_version, cursor, events]
properties:
catalog_version:
type: string
cursor:
type: string
events:
type: array
items:
type: object
RequestContext:
type: object
properties:
operation_id:
type: [string, "null"]
work_item_id:
type: [string, "null"]
actor_id:
type: [string, "null"]
grant_id:
type: [string, "null"]
RetryMetadata:
type: object
required: [classification, upstream_execution_state]
properties:
classification:
type: string
enum: [safe, unsafe, idempotent]
upstream_execution_state:
type: string
enum: [not_started, completed, unknown]
ServerConfig:
type: object
properties:
command:
type: [string, "null"]
args:
type: array
items:
type: string
env:
type: object
additionalProperties:
type: string
url:
type: [string, "null"]
protocolVersion:
type: [string, "null"]
example: "2026-07-28"
allowStateless:
type: [boolean, "null"]
headers:
type: object
additionalProperties:
type: string
auth:
type: object
resilience:
$ref: "#/components/schemas/ResilienceConfig"
UpsertServerRequest:
type: object
required: [name, server]
properties:
name:
type: string
server:
$ref: "#/components/schemas/ServerConfig"
ImportConfigRequest:
type: object
properties:
source_path:
type: [string, "null"]
overwrite:
type: [boolean, "null"]
UpdateAliasRequest:
type: object
required: [kind, alias]
properties:
kind:
type: string
enum: [tool, resource, prompt]
alias:
type: string
target:
type: [string, "null"]
WebhookConfig:
type: object
required: [url]
properties:
url:
type: string
secret:
type: [string, "null"]
secret_env:
type: [string, "null"]
auth_header:
type: [string, "null"]
headers:
type: object
additionalProperties:
type: string
PolicyConfig:
type: object
properties:
allow:
type: array
items:
type: string
deny:
type: array
items:
type: string
require_approval:
type: array
items:
type: string
approval_timeout_secs:
type: integer
redact_keys:
type: array
items:
type: string
webhook:
$ref: "#/components/schemas/WebhookConfig"
ApprovalStatus:
type: object
required: [status]
properties:
status:
type: string
enum: [pending, approved, rejected, expired]
operator:
type: string
timestamp:
type: integer
reason:
type: string
modified_args:
type: object
ApprovalTicket:
type: object
required: [id, capability_id, server_id, args, sanitized_args, status, created_at, expires_at]
properties:
id:
type: string
capability_id:
type: string
server_id:
type: string
args:
type: object
sanitized_args:
type: object
request_id:
type: [string, "null"]
status:
$ref: "#/components/schemas/ApprovalStatus"
created_at:
type: integer
expires_at:
type: integer
ListApprovalsResponse:
type: object
required: [ok, approvals, total]
properties:
ok:
type: boolean
approvals:
type: array
items:
$ref: "#/components/schemas/ApprovalTicket"
total:
type: integer
GetApprovalResponse:
type: object
required: [ok, approval]
properties:
ok:
type: boolean
approval:
$ref: "#/components/schemas/ApprovalTicket"
ApproveTicketRequest:
type: object
required: [operator]
properties:
operator:
type: string
modified_args:
type: object
RejectTicketRequest:
type: object
required: [operator]
properties:
operator:
type: string
reason:
type: string
SuccessEnvelope:
type: object
required: [ok, request_id, trace_id, data, error, retry]
properties:
ok:
type: boolean
const: true
request_id:
type: [string, "null"]
trace_id:
type: string
context:
$ref: "#/components/schemas/RequestContext"
retry:
$ref: "#/components/schemas/RetryMetadata"
data: {}
error:
type: "null"
ErrorEnvelope:
type: object
required: [ok, request_id, trace_id, data, error, retry]
properties:
ok:
type: boolean
const: false
request_id:
type: [string, "null"]
trace_id:
type: string
context:
$ref: "#/components/schemas/RequestContext"
retry:
$ref: "#/components/schemas/RetryMetadata"
data:
type: "null"
error:
type: object
required: [code, message, retryable]
properties:
code:
type: string
enum:
- TOOL_NOT_FOUND
- RESOURCE_NOT_FOUND
- PROMPT_NOT_FOUND
- SERVER_UNREACHABLE
- INVALID_ARGS
- UPSTREAM_TIMEOUT
- UPSTREAM_ERROR
- POLICY_DENIED
- APPROVAL_PENDING
- APPROVAL_TIMEOUT
- APPROVAL_REJECTED
- CIRCUIT_OPEN
- OPERATION_CANCELLED
- INTERNAL_ERROR
message:
type: string
retryable:
type: boolean
ResilienceConfig:
type: object
properties:
failureThreshold:
type: integer
default: 3
description: Consecutive failure threshold before tripping circuit to Open
cooldownMs:
type: integer
default: 30000
description: Cooldown duration in milliseconds before testing recovery in HalfOpen
consecutiveSuccesses:
type: integer
default: 2
description: Consecutive successful probes in HalfOpen to reset circuit to Closed
autoRestart:
type: boolean
default: true
description: Automatically restart crashed stdio child processes
maxRestarts:
type: integer
default: 5
description: Maximum restart attempts before giving up
healthCheckIntervalSecs:
type: [integer, "null"]
BatchStep:
type: object
required: [id, capability_id, args]
properties:
id:
type: string
description: Unique step identifier within the batch (e.g. step1)
capability_id:
type: string
description: Capability ID to invoke
args:
type: object
description: Arguments object, supporting $step_id.field reference interpolation
continue_on_error:
type: boolean
default: false
description: Whether to continue executing subsequent steps if this step fails
BatchCallRequest:
type: object
required: [steps]
properties:
steps:
type: array
items:
$ref: "#/components/schemas/BatchStep"
request_id:
type: [string, "null"]
context:
$ref: "#/components/schemas/RequestContext"
BatchStepResult:
type: object
required: [id, capability_id, ok, duration_us]
properties:
id:
type: string
capability_id:
type: string
ok:
type: boolean
data: {}
error:
type: [string, "null"]
duration_us:
type: integer
BatchCallResponse:
type: object
required: [ok, trace_id, results, total_duration_us]
properties:
ok:
type: boolean
request_id:
type: [string, "null"]
trace_id:
type: string
results:
type: array
items:
$ref: "#/components/schemas/BatchStepResult"
total_duration_us:
type: integer