Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.scomp.dev/llms.txt

Use this file to discover all available pages before exploring further.

The scomp protocol governs one wire: the messages exchanged between a client peer (typically an agent’s harness) and a server peer (typically a runtime host). It’s a thin layer on top of JSON-RPC 2.0 and a bidirectional transport. This page is the 30,000-foot view. The pages that follow drill in.

What scomp does

The protocol does two things, and only two:
1

Negotiates a session

The client opens a transport connection and sends a handshake request declaring its protocol version, its client-declared bindings, and optional metadata (auth, identity). The server responds with its protocol version, its server-declared bindings, and a sessionId. Sessions outlive connections.
2

Carries eval and invoke

After the handshake, the client can submit code for evaluation. Either peer can invoke the other’s bindings or function references, at any time, in any direction. That’s the entire steady-state vocabulary.
Everything above that — agent loops, prompt construction, tool selection, persistent-state conventions, multi-agent orchestration, UI patterns — lives in harnesses and SDKs, not the protocol.

What scomp doesn’t do

Equally important: the things the protocol deliberately stays out of.

Not a tool-calling protocol

Complementary to MCP. MCP exposes individually-callable tools to a stateless loop; scomp projects an agent into a stateful programmable environment. The two compose.

No runtime spec

QuickJS is the reference runtime, but Lua, Rhai, Wasm, or anything else that accepts code and produces JSON-serializable results conforms equally.

No transport spec

WebSocket is blessed for v0.1 interoperability. Any bidirectional, message-oriented, in-order transport satisfies the abstract contract.

No harness opinions

How agents author code, how harnesses build prompts, how application logic is organized — all out of scope. The protocol is the wire; opinions go above it.

The stack

Scomp distinguishes five layers. Two of them are protocol-bearing; the other three are implementation-defined. The dashed line is the protocol. Everything else is convention between the layers a single implementation owns. An SDK can be thin (a transport binding + types) or fat (a full harness loop), and either conforms.

Why this shape

Three design choices shape almost everything else. JSON-RPC 2.0 as the framing layer. Universal library support, standardized error model, bidirectional symmetry, unambiguous wire. The cost is essentially zero; the benefit is that any language can implement scomp with off-the-shelf parsing. Protocol-symmetric peers. Both sides declare bindings using the same metadata shape. Either side can invoke by name. The asymmetry is in who calls what, not in what is described. SDKs share types between client and server; spec stays small. Runtime-agnostic at the wire. A C→S invoke routes at the JSON-RPC layer, not by building runtime-specific source strings (await binding({...}) for JS, different syntax for Lua, …). The protocol layer is the abstraction point; the runtime is interchangeable.

Sub-pages

Architecture

The five-layer model in depth, plus the rationale for runtime-agnosticism.

Wire format

JSON-RPC framing, transport requirements, worked req/resp examples.

Lifecycle

Connection → handshake → steady state → close. Concurrency rules.

Bindings

Binding metadata, JSON Schema requirements, effects, hints.

Function references

Passing callables across the wire — the $scomp.fn sentinel and its lifecycle.

Sessions

What persists across reconnects, and what doesn’t.

Errors

JSON-RPC codes, scomp-specific codes, structured error data.
The canonical, normative spec lives at PROTOCOL.md in the repo. These pages are docs-site reading material — narrative, worked examples, diagrams. When wording matters (MUST vs SHOULD), PROTOCOL.md is the source of truth.