PE

pjullrich/emcp

Developer tools

このページは AI により自動翻訳されています。技術的な詳細は原文をご確認ください。 原文を見る

36 stars 4 forks 品質 58 トレンド 12MIT

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:

GitHub で README 全文を見る

インストール

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" } } }