ClaudeCode.MCP.Server (ClaudeCode v0.20.0)

View Source

Macro for generating Hermes MCP tool modules from a concise DSL.

Each tool block becomes a nested module that implements Hermes.Server.Component with type :tool. The generated modules have proper schema definitions, execute wrappers, and metadata.

Usage

defmodule MyApp.Tools do
  use ClaudeCode.MCP.Server, name: "my-tools"

  tool :add, "Add two numbers" do
    field :x, :integer, required: true
    field :y, :integer, required: true

    def execute(%{x: x, y: y}) do
      {:ok, "#{x + y}"}
    end
  end

  tool :get_time, "Get current UTC time" do
    def execute(_params) do
      {:ok, DateTime.utc_now() |> to_string()}
    end
  end
end

Generated Module Structure

Each tool block generates a nested module (e.g., MyApp.Tools.Add) that:

  • Uses Hermes.Server.Component, type: :tool
  • Has __tool_name__/0 returning the string tool name
  • Has a schema block with the user's field declarations
  • Has __description__/0 returning the tool description (via @moduledoc)
  • Has execute/2 implementing the Hermes tool callback
  • Wraps user return values into proper Hermes responses

Return Value Wrapping

The user's execute function can return:

  • {:ok, binary} - wrapped into a text response
  • {:ok, map | list} - wrapped into a JSON response

  • {:ok, other} - converted to string and wrapped into text response
  • {:error, message} - wrapped into an MCP execution error

Summary

Functions

Checks if the given module was defined using ClaudeCode.MCP.Server.

Defines a tool within a ClaudeCode.MCP.Server module.

Functions

sdk_server?(module)

@spec sdk_server?(module()) :: boolean()

Checks if the given module was defined using ClaudeCode.MCP.Server.

Returns true if the module exports __tool_server__/0, false otherwise.

tool(name, description, list)

(macro)

Defines a tool within a ClaudeCode.MCP.Server module.

Parameters

  • name - atom name for the tool (e.g., :add)
  • description - string description of what the tool does
  • block - the tool body containing optional field declarations and a def execute function

Examples

tool :add, "Add two numbers" do
  field :x, :integer, required: true
  field :y, :integer, required: true

  def execute(%{x: x, y: y}) do
    {:ok, "#{x + y}"}
  end
end