Modules
Sake is MCP for Elixir and Phoenix.
Authorization for a Sake endpoint: the host app is the OAuth 2.1 authorization server, and the endpoint is the resource server.
The authorization endpoint: GET validates the request and shows the
consent page (or redirects at once when consent is remembered); POST
records the decision. Mount it inside the pipeline that requires a
signed-in person; Sake reads the person through Sake.Auth.Subject.
Client ID Metadata Documents: a client identifies itself with an HTTPS URL, and the authorization server fetches the JSON document there.
An OAuth client: from a Client ID Metadata Document, dynamically registered, or registered by the host.
Clients the host registers itself (for its own CLIs or partners).
An authorization code (stored hashed).
The authorization configuration given to {Sake, auth: [...]}.
Renders the consent page and the authorization error page. The default,
Sake.Auth.Consent.Default, ships its own small style sheet. A host
replaces it with consent: MyAppWeb.MCPConsent in the auth config.
The consent and error pages that ship with Sake.
Dynamic Client Registration (RFC 7591) for clients that do not use Client ID Metadata Documents. Public clients only; no authentication. Put a rate limit in front of it.
The tables of Sake.Auth.Store.Ecto. In your app
The revocation endpoint (RFC 7009). Revoking a refresh token revokes its whole family. Revoking any token of a client also forgets the consents that person gave that client, so the next connection asks again.
The token, registration and revocation endpoints as one Plug router for hosts without Phoenix
Where clients, codes, tokens and consents live. Implemented by Sake.Auth.Store.ETS and Sake.Auth.Store.Ecto.
An in-memory store for development and tests on one node. Everything is lost on restart.
The Ecto store: store: {Sake.Auth.Store.Ecto, repo: MyApp.Repo} with
the tables from Sake.Auth.Migration. Tested on Postgres.
How Sake finds the person behind a request. The host implements it
The token endpoint: the authorization code grant with PKCE, and refresh token rotation with reuse detection.
An access or refresh token (stored hashed). family_id groups the tokens born from one authorization code.
Serves /.well-known/oauth-protected-resource (also under the endpoint's
path) and /.well-known/oauth-authorization-server. Mount at the root
A client for MCP servers over Streamable HTTP, on both protocol eras.
A parsed WWW-Authenticate challenge.
The state of a client connection; every Sake.Client call returns an updated one.
The result of Sake.Client.call_tool/3.
A content block of a tool result, a resource read, or a prompt message.
What a component learns about the request it serves.
Asks the person for input from inside a component.
JSON-RPC 2.0 messages as MCP uses them: requests with a string or integer id, notifications without one, results, errors, and batches (legacy revision 2025-03-26 only).
The MCP endpoint. Mount it once per server
The request headers that mirror the body on the modern Streamable HTTP
transport: Mcp-Method, Mcp-Name and Mcp-Param-*, with the Base64
sentinel encoding for values that are not plain ASCII.
The registry of open streams on this node: subscriptions/listen
streams, legacy GET streams, and handlers waiting for a legacy
elicitation answer. Started by the Sake supervisor. With a pubsub:
option (a Phoenix.PubSub name) notifications reach every node.
Progress and log notifications from inside a component.
A prompt template: arg lines (strings only) and get/2, which returns
messages as {:user | :assistant, text | %Sake.Content{}}.
The compiled definition of a prompt.
The protocol revisions Sake speaks and the _meta keys the protocol reserves.
A resource: a fixed uri: or a template with {name} placeholders, and
read/2. A template resource may implement list/1 to enumerate concrete
resources. subscribe: true lets clients subscribe to updates, which the
host announces with Sake.Server.resource_updated/2.
The compiled definition of a resource.
Router macros for Phoenix hosts
Builds JSON Schema 2020-12 from arg declarations and validates arguments
against it.
The server module lists the components and their scopes.
Legacy session IDs are signed tokens that carry the negotiated revision,
the client capabilities, the log level logging/setLevel last set, and
a random nonce. The server stores nothing per session.
A tool: use Sake.Tool with options, arg lines, an optional output
block, and execute/2.
The compiled definition of a tool.
The example server of the development server and the tests.