barrel_mcp_stdio (barrel_mcp v2.0.2)
View Sourcestdio transport for MCP protocol.
This module implements the stdio transport for the Model Context Protocol, enabling communication with MCP clients like Claude Desktop that use stdin/stdout for message passing.
Usage Modes
- Blocking mode - Call
start/0to run the server in the current process. The function blocks until stdin closes. - Supervised mode - Call
start_link/0to start as a gen_server that can be supervised.
Protocol
The stdio transport uses newline-delimited JSON-RPC 2.0 messages:
- Each message is a single line of JSON
- Messages are terminated by newline (
\n) - Responses are written to stdout in the same format
Example: Blocking Mode
%% In your escript or application main function:
main(_Args) ->
application:ensure_all_started(barrel_mcp),
barrel_mcp_registry:wait_for_ready(),
%% Register your tools
barrel_mcp:reg_tool(<<"my_tool">>, my_module, my_function, #{
description => <<"My tool description">>
}),
%% Start stdio server (blocks until stdin closes)
barrel_mcp_stdio:start().Example: Supervised Mode
%% In your supervisor init/1:
init(_Args) ->
Children = [
#{id => mcp_stdio,
start => {barrel_mcp_stdio, start_link, []},
restart => permanent,
type => worker}
],
{ok, {#{strategy => one_for_one}, Children}}.Claude Desktop Integration
To use with Claude Desktop, configure claude_desktop_config.json:
{
"mcpServers": {
"my-erlang-server": {
"command": "/path/to/your/escript",
"args": []
}
}
}The config file is located at:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/claude/claude_desktop_config.json
See also: barrel_mcp, barrel_mcp_protocol.
Summary
Functions
Start the stdio server in blocking mode.
Start the stdio server as a supervised gen_server.
Functions
-spec start() -> ok.
Start the stdio server in blocking mode.
This function starts the MCP stdio server in the current process. It reads JSON-RPC messages from stdin, processes them through the MCP protocol handler, and writes responses to stdout.
Important: This function blocks until stdin is closed (EOF). It is typically called as the last line of an escript main function or from a dedicated process.
Example
-module(my_mcp_server).
-export([main/1]).
main(_Args) ->
application:ensure_all_started(barrel_mcp),
barrel_mcp_registry:wait_for_ready(),
%% Register tools before starting
barrel_mcp:reg_tool(<<"echo">>, ?MODULE, echo, #{
description => <<"Echo back the input">>
}),
%% This blocks until stdin closes
barrel_mcp_stdio:start().
echo(Args) ->
maps:get(<<"message">>, Args, <<>>).
Start the stdio server as a supervised gen_server.
This function starts the MCP stdio server as a gen_server process that can be supervised. Unlike start/0, this returns immediately after spawning the server process.
The server registers locally as barrel_mcp_stdio.
Example
%% In your supervisor:
init([]) ->
SupFlags = #{strategy => one_for_one, intensity => 5, period => 10},
Children = [
#{id => mcp_stdio,
start => {barrel_mcp_stdio, start_link, []},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [barrel_mcp_stdio]}
],
{ok, {SupFlags, Children}}.