serve - 1-3-7/disrobe GitHub Wiki

The daemon: HTTP, gRPC, LSP, MCP

disrobe serve exposes byte classification and envelope operations over HTTP and gRPC, classification and error lookup over LSP, and pass-specific analysis, recovery, and workspace tools over MCP. Requests carry input bytes inline.

The protocol example records MCP initialization and an indicator query, LSP classification, and HTTP/gRPC health and classification requests. All three classification transports agree on the Wasm fixture's byte count, route, and BLAKE3 hash.

disrobe serve
disrobe serve --grpc
disrobe serve --stdio
disrobe serve --mcp

Flags

Flag Default Effect
--bind <ADDR> 127.0.0.1:7373 HTTP bind address.
--stdio off Serve LSP JSON-RPC over stdin/stdout instead of HTTP.
--mcp off Serve the MCP companion over stdio instead of HTTP/LSP.
--grpc off Expose the gRPC surface alongside HTTP (binds to <bind-ip>:<bind-port+1>).
--cors-origin <ORIGIN> (none) Additional CORS origin to allow. Repeatable. With no origins, all origins are allowed.
--max-body-size <N> 52428800 (50 MiB) Maximum request body size in bytes.

HTTP

The default surface. Binds to loopback (127.0.0.1:7373) by default; a non-loopback bind emits a warning at startup.

The API is versioned: /v1/* and /v2/* are aliases. The spec is served at /openapi.json.

Method Path Description
GET /v1/health Server liveness ({ status, version }).
GET /v1/version Tool name, version, and API level ({ name, version, api }).
GET /v1/passes List registered passes ({ passes: [{ name, description }] }).
POST /v1/analyze Classify and route bytes. Body: { bytes_b64, hint? }. Returns: { routed_action, bytes_read, blake3_hash, reason, candidates }.
POST /v1/explain/{code} Look up a DR-* error code. Returns: { code, known, title?, description?, crate_path? }.
POST /v1/envelope/verify Verify a .dr envelope. Body: { bytes_b64 }. Returns: { verified, version, rung, hot_bytes, cold_bytes, root_hash_blake3 }.
POST /v1/envelope/create Wrap raw bytes into a Raw-rung .dr envelope. Body: { bytes_b64, source_label?, produced_by?, detected_format? }. Returns: { envelope_b64, envelope_bytes, bytes_in, root_hash_blake3, source_hash_blake3 }.
WS /v1/stream WebSocket NDJSON stream (upgrade with Sec-WebSocket-Protocol: disrobe-stream.v1). Bytes are sent bytes_b64-only; the server never reads from disk.
GET /openapi.json OpenAPI 3 spec for the HTTP surface.

gRPC

Exposed alongside HTTP with --grpc. The gRPC server binds to the same IP as --bind but at <port> + 1 (default 127.0.0.1:7374). Includes health and reflection services.

LSP over stdio

--stdio speaks JSON-RPC over stdin/stdout using the LSP framing and initialize handshake. It does not implement the standard textDocument surface. It advertises two custom methods under capabilities.experimental.disrobe:

Method Description
disrobe/analyze Params: { bytes_b64, label? }. Returns the same classification payload as POST /v1/analyze.
disrobe/explain Params: { code }. Returns the error-code lookup payload.

Unknown fields in params are rejected (hard error). A path field is specifically rejected; all bytes are transmitted inline.

MCP companion

--mcp runs the rmcp-based Model Context Protocol companion, exposing disrobe's analysis, workspace, and navigation capabilities as MCP tools. Navigation includes call_graph, xrefs, function_summary, and neighborhood over content-bound function ids and bounded paginated responses. The standalone disrobe-mcp binary is equivalent. See the dedicated MCP server integration page for the full tool catalog and client registration.

Security posture

HTTP, gRPC, LSP, and WebSocket analysis requests carry sample bytes inline and do not accept a sample path. The MCP server also reads files by path, but only inside its workspace roots: the directory it starts in, each --root directory, and each directory in DISROBE_MCP_ROOTS. A path is canonicalized before the check, so .. segments and symbolic links that lead outside every root are refused. The file is read, never executed. Its workspace tools are also path-aware: annot reads a client-selected target only after resolving it beneath the current workspace, then writes its sidecar under .disrobe/annotations/; rename reads and writes the fixed .disrobe/notes/renames.json file. JSON request structs reject unknown fields via deny_unknown_fields. Reading a file outside the MCP roots, escaping those workspace bounds, or making an HTTP, gRPC, LSP or WebSocket analysis surface read a client-selected path is a high-severity vulnerability under the security policy. Run the daemon on loopback unless you have a specific reason not to.

⚠️ **GitHub.com Fallback** ⚠️