FastestMCP aims for MCP server compatibility while keeping runtime ownership, failure handling, and integration native to Elixir and OTP.

Design Rules

  • compatibility is the default
  • divergence is allowed when a convention would fight OTP, explicit failure semantics, or normal Elixir application structure
  • public Elixir APIs stay idiomatic while preserving the underlying MCP contract
  • runtime ownership stays inside supervised Elixir processes

Runtime Choices

TopicFastestMCP shape
Server startupuse FastestMCP.ServerModule with generated child_spec/1, start_link/1, and base_server/1
Runtime modelOTP-first with per-server runtime trees, supervised workers, and crash isolation
Context accessexplicit %FastestMCP.Context{} passed to handlers
HTTP integrationPlug-first via FastestMCP.http_app/2 and transport child specs
Client shapeconnected FastestMCP.Client GenServer with negotiated session ownership
Dynamic componentsinternal FastestMCP.ComponentManager GenServer provider
Streamingstreamable HTTP only; no standalone SSE transport

The Core Decisions

Module-owned servers

Application-owned servers should look like application-owned Elixir code. A module gives you a stable server identity, supervised startup, and config resolution without inventing a second app container inside the app you already have.

Explicit context

Request state, session state, principal data, auth details, and task metadata all live on FastestMCP.Context, which makes lifetimes and failure modes visible.

One operation pipeline

Tools, resources, templates, prompts, middleware, providers, auth, and transforms all run through one shared execution pipeline. HTTP, stdio, and in-process calls use the same behavior instead of growing separate seams that drift over time.

Runtime mutation stays in the runtime

Dynamic component changes go through FastestMCP.ComponentManager. There is no separate REST management API pretending to be the source of truth while the OTP system does the real work somewhere else.

Why This Shape

The goal is not novelty. The goal is to preserve the MCP contract while making the runtime feel native to Elixir. Protocol behavior stays stable while runtime ownership follows OTP conventions.