A generic, reusable Model Context Protocol (MCP) client library for Crystal that enables Crystal applications to connect to MCP servers and use their capabilities.
Add this to your application's shard.yml:
dependencies:
mcp-client:
github: ralsina/mcp-clientrequire "mcp-client"
# Create a client with STDIO transport
client = MCP::Client.new("npx", ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/directory"])
# Connect to the server
server_info = client.connect
puts "Connected to #{server_info.name} v#{server_info.version}"
# List available tools
tools = client.list_tools
tools.each do |tool|
puts "#{tool.name}: #{tool.description}"
end
# Call a tool
result = client.call_tool("read_file", {"path" => JSON::Any.new("/path/to/file.txt")})
puts result.content.first["text"]?.try(&.as_s)
# Disconnect when done
client.disconnectrequire "mcp-client"
# Create a custom transport
class MyTransport < MCP::Transport
def connect : Nil
# Your connection logic
end
def disconnect : Nil
# Your disconnect logic
end
def send_message(message : String) : Nil
# Your send logic
end
def receive_message : String?
# Your receive logic
end
def connected? : Bool
# Your connection status
end
end
# Use custom transport
transport = MyTransport.new
client_info = MCP::ClientInfo.new("my-client", "1.0.0")
client = MCP::Client.new(transport, client_info)client = MCP::Client.new("npx", ["-y", "@modelcontextprotocol/server-example"])
client.connect
# Check what the server supports
if client.supports_tools?
puts "Server supports tools"
end
if client.supports_resources?
puts "Server supports resources"
end
# Get full capabilities object
caps = client.server_capabilitiesThe main client class for communicating with MCP servers.
new(command : String, args : Array(String))- Create client with STDIO transportnew(transport : Transport, client_info : ClientInfo)- Create client with custom transport
connect : ServerInfo- Connect and perform initialization handshakedisconnect : Nil- Disconnect from the serverconnected? : Bool- Check if currently connectedlist_tools : Array(Tool)- List available toolscall_tool(name, arguments) : ToolCallResult- Call a tool with argumentsping : Bool- Ping the server to check connectivityserver_capabilities : ServerCapabilities?- Get server capabilitiessupports_tools? : Bool- Check if server supports toolssupports_resources? : Bool- Check if server supports resourcessupports_prompts? : Bool- Check if server supports prompts
MCP::ClientInfo- Client identification (name, version)MCP::ServerInfo- Server information (name, version)MCP::Tool- Tool definition (name, description, input_schema)MCP::ToolCallResult- Result of calling a toolMCP::Error- Error response from serverMCP::ServerCapabilities- Server capabilities
MCP::MCPError- Base exception for MCP errorsMCP::MCPConnectionError- Connection-related errorsMCP::MCPProtocolError- Protocol-related errorsMCP::MCPToolError- Tool call errors
crystal specshards build# Basic example
./bin/basic_tool_client /tmp
# Advanced example
./bin/advanced_usage /tmpThis is currently in development. The initial version supports:
- STDIO transport
- Tool listing and calling
- Basic capability negotiation
- Error handling
Planned for future versions:
- HTTP/SSE transport
- Resources support
- Prompts support
- Logging configuration
- Progress token support
- Request cancellation
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
MIT License - see LICENSE file for details.