Agent MCP Runtime
One binary pulls skill packs from Git repos, feeds them to any LLM you choose, and runs tools over MCP — all auto-composed for your project's framework.
Gemini • OpenAI • Claude • Groq • Rails • Hanami auto-detection
Why this exists
AI agent skills live in separate Git repos — Ruby patterns, Rails workflows, Hanami idioms, planning disciplines. Each project needs a different combination. Manually composing them means copy-pasting prompts, remembering which skills overlap, and wiring tools by hand.
The runtime solves this: it auto-detects your framework, resolves skill conflicts, caches packs locally, and exposes everything to your LLM through one command.
The big picture
Think of the runtime as a conductor. Four skill packs are the sheet music: each one is a Git repo full of Markdown files that teach an LLM how to perform specific tasks. The runtime reads them all, resolves overlaps, and hands a clean catalog to the LLM.
How it works
The runtime does three things every time you invoke it. Understanding each one reveals how the whole system composes itself around your project.
Skill packs are resolved in layers. Higher layers override lower ones for same-named skills. This lets framework-specific packs specialize core skills while local development overrides everything.
The core execution engine. The LLM alternates between choosing a tool to call and observing its result. It keeps going until it has enough information for a final answer — or hits the step limit.
Every capability the agent can use — built-in skills, external MCP tools, project context — implements the same Tool trait. The runner treats them all uniformly.
Why a trait and not an enum?
Traits enable compile-time verification that every tool satisfies the contract. They also make testing trivial: swap in a MockTool that returns canned responses, and the entire ReAct loop becomes testable without networking.
Walkthrough
Here's what happens step-by-step when you ask the runtime to add a database column to a Rails model.
Why it's built this way
Skills change independently of the runtime. Embedding them requires recompilation on every update. Git repos let packs version independently, accept PRs, and stay fresh with a pull.
stdin/stdout pipes have zero network overhead, no port conflicts, and a simpler lifecycle (spawn → communicate → kill). HTTP MCP is still used for context providers where the data source is remote.
The ask_llm(prompt) interface keeps providers swappable. The tradeoff: provider-specific features like function calling and structured output are unavailable. LLM latency dominates anyway.
Every I/O boundary — LLM, git, MCP subprocess — has a mockable trait. This makes the entire runtime testable without network access, a Git remote, or an API key.
Skills are Markdown files with YAML frontmatter (like Jekyll/Hugo). Self-contained, human-readable, no separate metadata files. The cost: schema errors surface at runtime, not at parse time.
unsafe_code = "deny" at the compiler level. Strict clippy gates, no .unwrap() in non-test code. Memory safety is enforced by the compiler, not by convention.
Guardrails
Get started
curl -fsSL https://raw.githubusercontent.com/igmarin/agent-mcp-runtime/main/install.sh | bash
agent-mcp-runtime --task "Add full_name to the User model"
agent-mcp-runtime --provider openai --model gpt-4o --task "Refactor the service layer"
agent-mcp-runtime --mcp-command npx --mcp-args -y @modelcontextprotocol/server-filesystem --mcp-args /tmp --task "List files"
agent-mcp-runtime --registry ./my-pack --task "Test my new skill"