
pjullrich/emcp
Developer toolsこのページは AI により自動翻訳されています。技術的な詳細は原文をご確認ください。 原文を見る
Elixir のモデルコンテキストプロトコル (MCP) サーバー
概要
最小限の Elixir MCP (モデルコンテキストプロトコル) サーバー。 セッションストアの初期化をアプリケーションの start/2 に追加します。 EMCPを実装することでカスタムセッションストアを使うことができます。 セッションストアの動作。 フェニックスルーターに StreamableHTTP トランスポートを追加します。 EMCP はコンテンツの交渉自体を扱うのでパイプラインの外にそれを押して下さい: プロンプトは構造化されたメッセージを返す再使用可能なテンプレートです。 リソースは、クライアントが読むことができるデータを公開します。 静的リソースは、固定URIを持っています。 リソーステンプレートは URI パターンを使用しており、クライアントは動的コンテンツをリクエストできます。 クライアントがresource/readを呼び出すと、サーバーは最初に静的リソースに対する正確なURIマッチを試みます。 どれもマッチしない場合は、各リソーステンプレートを1つが URI を処理するまで試します.
概要(AI 翻訳)
最小限の Elixir MCP (モデルコンテキストプロトコル) サーバー。
セットアップ
##1. セッションストアの初期化
セッションストアの初期化をアプリケーションの start/2 に追加します。
EMCP.SessionStoreの動作を実装することで、カスタムセッションストアを使うことができます。
##2. サーバーを定義する
##3。 輸送をマウントする
フェニックスルーターに StreamableHTTP トランスポートを追加します。 EMCP はコンテンツの交渉自体を扱うのでパイプラインの外にそれを押して下さい:
#4. サーバーにツールを追加する
プロンプト
プロンプトは構造化されたメッセージを返す再使用可能なテンプレートです。
リソース
リソースは、クライアントが読むことができるデータを公開します。 静的リソースは、固定URIを持っています。
リソーステンプレートは URI パターンを使用しており、クライアントは動的コンテンツをリクエストできます。
クライアントが resources/read を呼び出すと、サーバーは最初に静的リソースに対する正確な URI マッチを試みます。 どれもマッチしない場合は、各リソーステンプレートを1つが URI を処理するまで試します。
オリジン検証
DNS のリバインド攻撃を防ぐため、トランスポートのオリジン検証を有効にできます。 有効にすると、[Origin]ヘッダーのリクエストのみが許可されたリストに一致します。 [Origin ヘッダーなしのリクエスト(例: CLI ツール)は常に許可されます.
このページは AI により自動翻訳されています。技術的な詳細は原文をご確認ください。
README
以下は原文 README の抜粋です。原文を見る。
EMCP
A minimal Elixir MCP (Model Context Protocol) server.
Setup
1. Initialize the session store
Add the session store initialization to your application’s start/2:
defmodule MyApp.Application do
use Application
def start(_type, _args) do
EMCP.SessionStore.ETS.init()
children = [
# ...
]
Supervisor.start_link(children, strategy: :one_for_one)
end
end
You can use a custom session store by implementing the EMCP.SessionStore behaviour.
2. Define a server
defmodule MyApp.MCPServer do
use EMCP.Server,
name: "my-app",
version: "1.0.0",
tools: [MyApp.Tools.Echo],
prompts: [MyApp.Prompts.CodeReview],
resources: [MyApp.Resources.Readme],
resource_templates: [MyApp.ResourceTemplates.UserProfile],
# You can optionally add these meta fields as well:
title: "My App",
description: "MCP server for My App",
instructions: "Use the tools to interact with My App.",
end
3. Mount the transport
Add the StreamableHTTP transport to your Phoenix router. Mount it outside any pipeline since EMCP handles content negotiation itself:
scope "/mcp" do
forward "/", EMCP.Transport.StreamableHTTP, server: MyApp.MCPServer
end
4. Add tools to your server
defmodule MyApp.Tools.Echo do
@behaviour EMCP.Tool
@impl EMCP.Tool
def name, do: "echo"
@impl EMCP.Tool
def description, do: "Echoes back the provided message"
@impl EMCP.Tool
def input_schema do
%{
type: :object,
properties: %{
message: %{type: :string}
},
required: [:message]
}
end
@impl EMCP.Tool
def call(_conn, %{"message" => message}) do
EMCP.Tool.response([%{"type" => "text", "text" => message}])
end
# Return errors with:
# EMCP.Tool.error("something went wrong")
end
Prompts
Prompts are reusable templates that return structured messages:
defmodule MyApp.Prompts.CodeReview do
@behaviour EMCP.Prompt
@impl EMCP.Prompt
def name, do: "code_review"
@impl EMCP.Prompt
def description, do: "Reviews code with optional focus area"
@impl EMCP.Prompt
def arguments do
[
%{name: "code", description: "The code to review", required: true},
%{name: "focus", description: "Optional area to focus on"}
]
end
@impl EMCP.Prompt
def template(_conn, %{"code" => code} = args) do
focus = args["focus"]
user_text =
if focus,
do: "Review this code, focusing on #{focus}:\n\n#{code}",
else: "Review this code:\n\n#{code}"
%{
"description" => "Code review prompt",
"messages" => [
%{"role" => "user", "content" => %{"type" => "text", "text" => user_text}},
%{"role" => "assistant", "content" => %{"type" => "text", "text" => "I'll review the code you've provided."}}
]
}
end
end
Resources
Resources expose data that clients can read. A static resource has a fixed URI:
インストール
This server does not publish a one-line install command.
Open the repository installation guide MCP 初心者?mcpskill.org のガイドから始めましょう →設定
{
"mcpServers": {
"my-app": {
"command": "mix",
"args": ["run", "--no-halt"],
"cwd": "/path/to/your/elixir/project"
}
}
}