# atd-server-http

Streamable-HTTP (MCP JSON-RPC) transport for ATD-speaking servers.
Sibling of [`atd-server`](https://crates.io/crates/atd-server) (the
Unix-socket transport); both consume the same
[`atd-runtime`](https://crates.io/crates/atd-runtime) `Registry`, so a single
`Tool` implementation reaches both UDS and HTTP clients without code
duplication.

## What this is

A `POST /mcp` axum router that translates MCP JSON-RPC 2.0
(`initialize` / `tools/list` / `tools/call` / `notifications/initialized`)
into ATD operations and dispatches via `atd_runtime::dispatch::run_tool`.
Bytes returned from `Tool::call` are byte-identical to the UDS path — the
parity test in `tests/e2e_parity.rs` is the regression guard.

Designed for adopters who need **cloud-hosted ATD servers** — i.e. agents
(Claude Desktop, Cursor, browser-based assistants) that speak MCP Streamable
HTTP and cannot open a Unix socket directly.

## Features

- Origin allow-list (mitigates DNS-rebinding attacks)
- Bearer-token auth via the
  [`TokenBroker`](https://docs.rs/atd-runtime/latest/atd_runtime/trait.TokenBroker.html)
  trait
  - Typed `BearerOutcome` with a per-variant HTTP status +
    `WWW-Authenticate` / `Retry-After` headers
  - SSE long-connection bearer-refresh helper (`spawn_bearer_refresh`)
- `/initialize` advertises the broker's `accepted_token_formats()` under
  `capabilities.experimental.atd.acceptedTokenFormats`
- UCAN-lite capability tokens via the additive `Hello.ucan_tokens` field

## Composition

```rust
use atd_runtime::Registry;
use atd_server_http::{HttpServerConfig, Server};

let registry: Registry = my_tools();
let cfg = HttpServerConfig::default();
let (router, server) = Server::builder(registry)
    .config(cfg)
    .build();
// Adopters may extend the router with their own routes here
// (e.g. /chat/stream for SSE).
server.serve(router).await?;
```

## What is NOT in this crate

- TLS termination — operators front with nginx / Caddy / Tauri
- OAuth 2.1 token issuance — bearer is validated, not minted; adopters bring
  their own broker
- `Mcp-Session-Id` sticky sessions / resumability / `Last-Event-ID` — reserved
- SSE inside `tools/call` — single response per request; adopters layer SSE on
  adopter-owned routes

## Adopters in production

- **[celia_phr](https://github.com/downsea/celia_phr)** — a Tauri PHR app
  exposes `/mcp` for its Hermes / Claude assistants; a SQLite-backed consent
  token broker drives bearer auth.

## Part of the ATD reference implementation

This crate is part of
[ATD — Agent Tool Dispatch](https://github.com/downsea/atd). See
[`docs/atd-architecture.md`](https://github.com/downsea/atd/blob/master/docs/atd-architecture.md)
for the full layer model and
[`docs/integrations/`](https://github.com/downsea/atd/tree/master/docs/integrations)
for adopter-side tutorials.

## License

Apache-2.0.
</content>
