# car-server-core
Transport-neutral library for the [Common Agent Runtime](https://github.com/Parslee-ai/car) JSON-RPC dispatcher.
## What it does
Holds the JSON-RPC dispatcher, per-client session state, and the WebSocket channel plumbing. Used by `car-server` (the standalone WebSocket binary) and by any future embedder that wants to expose CAR's protocol over a different transport (e.g. `tokhn-daemon`).
The standalone `car-server` binary is a thin wrapper that loads `~/.car/env`, initializes telemetry, spawns the dream loop, binds a TCP listener, and on each connection calls `run_dispatch`.
## Library boundary contract
This library MUST NOT:
- spawn the dream loop (caller decides),
- initialize telemetry (caller decides),
- load `~/.car/env` (caller decides).
Those bootstraps stay in the embedder's `main`. The contract prevents the dual-memgine bug: if the library silently spawned its own dream loop, embedded users would end up with two memgine engines (the embedder's plus the library's).
## Lock primitive
`ClientSession.memgine` uses `Arc<tokio::sync::Mutex<MemgineEngine>>` per the "one-wrapper rule" — dispatcher handlers can hold the lock across `.await` points without risking poisoning, and tokio's `Mutex` does not poison so a panicking handler does not poison the engine for sibling connections.
## Embedder usage
```rust,ignore
use car_server_core::{ServerState, ServerStateConfig, run_dispatch};
// Build the shared server state.
let state = ServerState::embedded(ServerStateConfig::default()).await?;
// On each accepted WebSocket connection:
tokio::spawn(async move {
run_dispatch(ws, state.clone()).await;
});
```
## Where it fits
The full method reference is in [`docs/websocket-protocol.md`](../../../docs/websocket-protocol.md) — that document describes the wire format produced by this crate's dispatcher.