Ruby Drop a .rb file.
Drop a .rb file.
517 lines. No gems.
zeromcp vs mcp gem — side by side.
Dependencies
0 ZeroMCP
vs. 90 Official SDK
Throughput
4.26K req/s ZeroMCP
vs. 2.16K req/s Official SDK
Memory
26 MB ZeroMCP
vs. 56 MB Official SDK
This is a hello world
Require, server instantiation, class-based registration, schema definition, and transport setup. 12 lines before your tool does anything.
mcp gem 12 lines
require 'mcp'
server = MCP::Server.new(
name: "test", version: "1.0.0")
server.register_tool("hello",
description: "Say hello",
input_schema: {
name: { type: "string" }
}) do |args|
"Hello, #{args['name']}!"
end
server.run_stdio This is the whole server
No require. No server class. No registration blocks.
Drop it in a folder and run zeromcp serve.
ZeroMCP 8 lines
# tools/hello.rb
TOOL = {
description: "Say hello",
input: { name: "string" }
}
def execute(args, ctx)
"Hello, #{args['name']}!"
end HTTP Performance — Head to Head
Mixed workload across all 7 MCP method types. 5-minute sustained load in Docker. Rack+Puma for ZeroMCP, stdio proxy for the official SDK.
req/s CPU Memory Ratio
ZeroMCP (Rack+Puma) 4.26K 0.06% 26 MB 2.0x
Official SDK 2.16K 0.04% 56 MB
The tradeoff
Choose the mcp gem
If you want the canonical Ruby MCP interface and are willing to work through the documentation gaps.
- Block DSL — registration pattern familiar to Ruby devs
- Spec parity — tracks every spec change immediately
- Enterprise support — maintained by the MCP specification team at Anthropic
Choose ZeroMCP
If you want it working on the first try. Drop a .rb file, zero gems, 517 lines.
- 0 gems
- File-based tools — drop a .rb file, it's live
- Rack+Puma + Sinatra
- Built-in sandbox with enforced permissions
- 4.26K req/s on Rack+Puma