# `Mead.MCP.Server.Plug`
[🔗](https://github.com/albertosca/mead/blob/main/lib/mead/mcp/server/plug.ex#L1)

The HTTP side of the MCP server: `POST /mcp`, one JSON-RPC message per request.

Each check runs only if the previous ones passed, and the first failure answers and halts:

  1. the route: any path but `/mcp` is 404, any method but POST is 405 with `allow: POST`
     (the server has no event stream to offer);
  2. the bearer token (401, `www-authenticate: Bearer`), compared in constant time and checked
     before the body is read, so an unauthenticated client makes the server read nothing;
  3. the `Origin` header, when present: loopback or listed in `allowed_origins`, else 403.
     This is the protection against DNS rebinding that the MCP specification asks for;
  4. the content type: `application/json`, else 415;
  5. the body: at most 1 MiB, else 413;
  6. decoding: text that is not JSON is 400 with `-32700`; JSON that is not a request,
     notification, or response (a batch included) is 400 with `-32600`.

Every refusal is a JSON-RPC error with `"id": null`. A message that decodes is handed to the
dispatcher: a reply is 200 with one JSON object, no reply is 202 with an empty body. A bug in
the dispatcher becomes a generic 500; only the exception module is logged, because a crash
report of a request process can print the whole connection, `Authorization` header included.

No cookies and no CORS headers are ever set.

## Options

  * `:configuration` - the `Mead.MCP.Server.Configuration` (required).
  * `:dispatcher` - a module with `dispatch/2`; defaults to `Mead.MCP.Server.Dispatcher`, and is
    only replaced by tests.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
