Sake.Context (Sake v0.4.3)

Copy Markdown View Source

What a component learns about the request it serves.

scope is the host's principal (the current user, organization, or anything the host puts there); token and scopes are set when the endpoint has authorization; inputs holds the client's answers (elicitation, sampling, roots) on a retry; progress reports progress to the client when it asked for it; task is the task ID when the component runs as a task (see Sake.Tasks); assigns holds what the server's middleware decided for this request (see Sake.Middleware).

base_url is the URL of the MCP endpoint the request reached, as the client reaches it: scheme, host, the port when it is not the scheme's default, and the endpoint's path, without a query or a trailing slash ("https://example.com/acme/mcp"). A tool builds absolute URLs to its own host from it, such as a link the person opens or a one-time upload URL:

def execute(%{name: name}, ctx) do
  uri = URI.parse(ctx.base_url)
  token = MyApp.Uploads.grant(ctx.scope, name)
  {:ok, %{upload_url: URI.to_string(%{uri | path: "/uploads/" <> token})}}
end

Sake.Plug sets it from the request; on an endpoint with auth: true its origin is the issuer's, as for the token's audience, and on an external authorization server with url:, that url:'s (see Sake.Auth.External). Behind a proxy that does not rewrite the request, put Plug.RewriteOn before the endpoint (see "Behind a proxy" in the security guide). It is nil where there is no HTTP request: over stdio (Sake.Stdio) and in Sake.Test's in-memory client unless the test passes base_url:, so a tool that needs it should say so when it is missing.

Summary

Types

t()

@type t() :: %Sake.Context{
  assigns: term(),
  base_url: term(),
  client_capabilities: term(),
  client_info: term(),
  conn_assigns: term(),
  era: term(),
  inputs: term(),
  log_level: term(),
  method: term(),
  progress: term(),
  protocol_version: term(),
  request_id: term(),
  reraise: term(),
  scope: term(),
  scopes: term(),
  secret: term(),
  server: term(),
  task: term(),
  token: term(),
  trace: term(),
  transport: term()
}

Functions

new(opts \\ [])

@spec new(keyword()) :: t()