MCPKit
MCPKit is a reusable MCP server runtime for Phoenix applications.
It gives host applications a small set of host-facing contracts for building policy-aware MCP servers over Streamable HTTP, with support for tools, prompts, resources, completions, persistent sessions, and a host-started runtime for active sessions.
What It Supports
-
Streamable HTTP transport with
POST,GETSSE, andDELETE initialize,ping, andnotifications/initializedtools/listandtools/callprompts/listandprompts/getresources/list,resources/read, andresources/templates/listcompletion/completefor prompt arguments and resource templates-
request-time policy enforcement through
MCPKit.Policy
Current Limitations
- resource subscriptions and resource update notifications are not implemented
- runtime-initiated client requests are internal plumbing, not a public host API
- logging, progress notifications, and list-changed notifications are not implemented yet
Installation
def deps do
[
{:mcp_kit, "~> 0.2.0"}
]
endQuickstart
1. Define the host contract
defmodule MyApp.MCP.Definition do
@behaviour MCPKit.Definition
@impl true
def protocol_version, do: "2025-06-18"
@impl true
def server_info do
%{"name" => "my-app", "version" => "0.1.0"}
end
@impl true
def session_store, do: MyApp.MCP.SessionStore
@impl true
def policy, do: MyApp.MCP.Policy
end2. Implement persistent session storage
defmodule MyApp.MCP.SessionStore do
@behaviour MCPKit.SessionStore
@impl true
def create_session(attrs) do
{:ok,
%{
id: Ecto.UUID.generate(),
initialized: false,
protocol_version: attrs.protocol_version,
client_info: attrs.client_info,
client_capabilities: attrs.client_capabilities
}}
end
@impl true
def fetch_session(session_id) do
# Load from your database or cache.
{:error, :not_found}
end
@impl true
def touch_session(session), do: {:ok, session}
@impl true
def mark_initialized(session), do: {:ok, %{session | initialized: true}}
@impl true
def delete_session(_session_id), do: {:error, :not_found}
end3. Start the runtime
children = [
{MCPKit.Runtime, definition: MyApp.MCP.Definition}
]4. Add a policy
defmodule MyApp.MCP.Policy do
@behaviour MCPKit.Policy
@impl true
def authorize(_action, _context), do: :allow
end5. Define a tool
defmodule MyApp.MCP.Tools.Ping do
use MCPKit.Tool
alias MCPKit.Response
schema do
field :message, :string, required: true
end
@impl true
def execute(arguments, context) do
{:reply, Response.tool() |> Response.structured(arguments), context}
end
end6. Mount the MCP route
defmodule MyAppWeb.Router do
use MyAppWeb, :router
import MCPKit.Router
mcp_scope "/mcp", MyApp.MCP do
tool "ping", Tools.Ping
end
endmcp_scope/2 infers the definition module as MyApp.MCP.Definition and the
runtime name as MyApp.MCP.Runtime. Override them with definition: and
runtime: if needed.
Host Contracts
The host application is responsible for:
MCPKit.Definition: protocol version, server info, session store, and optional policyMCPKit.SessionStore: durable session lifecycleMCPKit.Runtime: active in-memory session coordinationMCPKit.Policy: request-time authorization and visibility decisions
See the guides for fuller examples:
Router DSL
Use MCPKit.Router.mcp_scope/2 or mcp_scope/3 inside a Phoenix router scope.
mcp_scope "/mcp", MyApp.MCP do
tool "project_create", Tools.ProjectCreate
prompt "draft_release_notes", Prompts.DraftReleaseNotes
resource "project", Resources.Project
end
Inside mcp_scope, you can declare:
tool/2prompt/2resource/2
Policy
MCPKit.Policy is evaluated on every request. It supports these decisions:
:allow{:deny, :not_found}{:deny, :forbidden}
Lists are filtered item-by-item, while direct calls, prompt gets, resource reads, and completions are enforced separately.
completion/complete is also policy-aware and only returns suggestions for
visible prompt arguments and resource templates.
Authoring APIs
Tools
Tool modules use MCPKit.Tool to declare input schemas and return
MCPKit.Response values.
Prompts
Prompt modules use MCPKit.Prompt to declare argument schemas, render MCP
messages, and optionally implement complete/3 for argument suggestions.
Resources
Resource modules use MCPKit.Resource to declare concrete resource entries,
URI templates, URI reads, and optionally implement complete/3 for template
variable suggestions.
Supported MCP Surface
Currently implemented methods:
initializepingcompletion/completeprompts/listprompts/getresources/listresources/readresources/templates/listtools/listtools/callnotifications/initializednotifications/cancelledDELETEsession terminationGETSSE session stream
For one canonical compatibility summary, see Supported MCP Surface.
Publishing Checklist
-
update version in
mix.exs - confirm package links and source URL
-
run
mix test -
run
mix docs -
run
mix hex.build