ExMCP.Native (ex_mcp v0.9.0)
View SourceNative BEAM service dispatcher for direct process communication within Elixir clusters.
This module provides ultra-fast, direct process communication leveraging OTP's built-in features:
- Direct GenServer.call between processes
- Pluggable service registry (local
Registryby default,Hordefor distribution) - Automatic distribution across BEAM nodes (with Horde adapter)
- Built-in fault tolerance and monitoring
- Zero serialization overhead for local calls
Use Cases
- Trusted Elixir services within the same cluster
- High-performance internal communication (~15μs local, ~50μs cross-node)
- Services that need to be supervised and monitored by OTP
Future API Direction
In future versions, native BEAM communication will be available as a transport
option for ExMCP.Client, providing a unified API across all communication methods.
The current ExMCP.Native API will remain supported but may be superseded.
Performance Characteristics
- Local calls: ~15μs latency
- Cross-node calls: ~50μs latency
- Memory overhead: Single registry entry per service
- Throughput: Limited only by service processing speed
Examples
# Service registration (typically in init/1)
ExMCP.Native.register_service(:my_tool_service)
# Direct service calls
{:ok, result} = ExMCP.Native.call(:my_service, "list_tools", %{})
# Cross-node calls (automatic)
{:ok, result} = ExMCP.Native.call({:my_service, :"node@host"}, "method", params)
# Fire-and-forget notifications
:ok = ExMCP.Native.notify(:event_service, "resource_updated", %{
"uri" => "file:///config.json",
"type" => "modified"
})Service Discovery
# List all available services across the cluster
services = ExMCP.Native.list_services()
# Check if a service is available
available? = ExMCP.Native.service_available?(:my_service)
Summary
Functions
Calls a service method with the given parameters.
Lists all services registered in the distributed registry.
Sends a notification to a service (fire-and-forget).
Registers a service with the distributed registry.
Checks if a service is available in the distributed registry.
Unregisters a service from the distributed registry.
Types
Functions
Calls a service method with the given parameters.
Supports both local and cross-node calls transparently through the configured registry adapter.
Options
:timeout- Call timeout in milliseconds (default: 5000):progress_token- Progress token for long-running operations:meta- Additional metadata map
Examples
# Simple call
{:ok, tools} = ExMCP.Native.call(:my_tools, "list_tools", %{})
# Call with timeout and metadata
{:ok, result} = ExMCP.Native.call(
:my_tools,
"process_data",
%{"dataset" => "large_data"},
timeout: 30_000,
meta: %{"trace_id" => "abc", "user_id" => "user1"}
)
Lists all services registered in the distributed registry.
Returns a list of tuples containing {service_name, pid, metadata}.
@spec notify(service_id(), method(), params()) :: :ok | {:error, term()}
Sends a notification to a service (fire-and-forget).
Notifications do not expect a response and are sent asynchronously.
Examples
:ok = ExMCP.Native.notify(:event_service, "resource_updated", %{
"uri" => "file:///config.json",
"type" => "modified"
})
@spec register_service(atom()) :: :ok
Registers a service with the distributed registry.
This should typically be called in a GenServer's init/1 callback.
Examples
def init(_) do
ExMCP.Native.register_service(:my_tools)
{:ok, %{}}
end
Checks if a service is available in the distributed registry.
@spec unregister_service(atom()) :: :ok
Unregisters a service from the distributed registry.
This should typically be called in a GenServer's terminate/2 callback.