This guide shows the smallest complete host integration for mcp_kit.
Install
def deps do
[
{:mcp_kit, "~> 0.2.4"}
]
endDefine the MCP host contract
defmodule MyApp.MCP.Definition do
@behaviour MCPKit.Definition
@impl true
def server_info, do: %{"name" => "my-app", "version" => "0.1.0"}
@impl true
def session_store, do: MyApp.MCP.SessionStore
@impl true
def policy, do: MyApp.MCP.Policy
endmcp_kit owns the MCP transport version and advertises its built-in current
protocol version automatically. Host apps do not configure this.
Implement durable sessions
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: {:error, :not_found}
@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}
endStart the runtime
children = [
{MCPKit.Runtime, definition: MyApp.MCP.Definition}
]Add a basic policy
defmodule MyApp.MCP.Policy do
@behaviour MCPKit.Policy
@impl true
def authorize(_action, _context), do: :allow
endAuthor 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
endMount the MCP route
defmodule MyAppWeb.Router do
use MyAppWeb, :router
import MCPKit.Router
mcp_scope "/mcp", MyApp.MCP do
tool "ping", Tools.Ping
end
endLike a normal Phoenix scope, Tools.Ping resolves to
MyApp.MCP.Tools.Ping inside mcp_scope.
Next steps
- add
MCPKit.Promptmodules for prompt authoring - add
MCPKit.Resourcemodules for resources and templates - tighten access with
MCPKit.Policy - review Supported MCP Surface