Turns out it’s super easy to do, and it gives you some amazing leverage for tools! For example, I gave my kanban board a MCP server and now I can just say “move the note “whatever” to done” and it works ;-)
It supports stdio MCP servers (nice way to expose a CLI tool to AI agents) and web MCP servers (with kemal at least)
Here is a FULL example of a MCP with a single tool, in stdio mode:
require "mcp"
# A simple tool that returns the answer to any question
class AnswerTool < MCP::AbstractTool
@@tool_name = "get_answer"
@@tool_description = "Returns 42 as the answer to any question you ask"
@@tool_input_schema = {
"type" => "object",
"properties" => {
"question" => {
"type" => "string",
"description" => "The question you want answered",
},
},
"required" => ["question"],
}.to_json
def invoke(params : Hash(String, JSON::Any), env : HTTP::Server::Context? = nil)
question = params["question"]?.try(&.as_s) || "unknown question"
{
"answer" => 42,
"question" => question,
}
end
end
# Start the stdio server - that's it! One line and you have a complete MCP server.
MCP::StdioHandler.start_server
Have fun and let me know if something is not ergnomic, I am trying to make this as boilerplate-free as possible.
When MCP servers started to become popular, I had Claude read the MCP specification and tried creating a Crystal library through vibe coding. I didn’t understand much then, and I still don’t now. But the code quickly grew beyond 10,000 lines, and I felt something wasn’t right, so I stopped. I think something smaller and more imperfect will eventually become widespread.
This implements most of the spec (didn’t implement resources because I don’t use them yet) and is 391 LOC (that includes the Kemal handler)
The spec is super simple.
It’s basically 4 entry points (initialize, list tools, invoke tool, resources) where the “complicated” one is invoke tool, which is jsonrpc, which is pretty simple.
I actually looked through the codebase and confirmed that the implementation is quite simple.
I still have some vague concerns about the future of MCP, but that’s another story.