Claude Code, for open source.
Any model, any provider.
A Claude-Code-style agent in your terminal, and Anthropic's claude-agent-sdk surface as a library — on any model you can serve, open or closed. The migration is one import.
↑That's the whole diff. Code written for Anthropic's SDK runs as-is — mantis keeps the surface you know and swaps what's underneath.
The mantis terminal ships in the same install — a Claude-Code-style coding agent driving the open model you choose.
One kwarg between
A terminal to code in, and a library to build with.
The mantis terminal
Point it at any directory. It reads, writes, edits, greps, and runs shell commands — Claude Code's feel, driving your local Ollama, your vLLM box, or a hosted endpoint. The input stays pinned to the bottom; replies render as Markdown; file edits come back as real, line-numbered diffs.
▄▀▄▀
▄█▀
▄██▀▀█▀
▄█ ▄███▀▀
▄▄██▀▀██▀▀▀▀▀
▀▀ █ █▀ ▀▄
▄▄▀ ▄▀ ▀▄The Python library
The same engine, as an SDK. A tool-calling loop is a few lines away — and the exact same script runs against Together, Fireworks, vLLM, or Groq by changing one string.
import asyncio
from mantis_agent import query, MantisAgentOptions, tool, AssistantMessage
@tool
async def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"{city}: 67°F"
async def main():
async for msg in query(
prompt="What's the weather in SF?",
options=MantisAgentOptions(
model="qwen2.5:1.5b", # routes to local Ollama automatically
tools=[get_weather],
max_turns=5,
),
):
if isinstance(msg, AssistantMessage):
for block in msg.content:
if hasattr(block, "text"):
print(block.text)
asyncio.run(main())# same script, three backends — change one line
options = MantisAgentOptions(model="qwen2.5:7b") # → local Ollama
options = MantisAgentOptions(model="Qwen/Qwen2.5-72B-Instruct-Turbo") # → Together
options = MantisAgentOptions(model="llama-3.3-70b-versatile",
backend="https://api.groq.com/openai/v1") # → GroqEverything that makes Claude Code feel finished — on models you choose.
Name the model and go
A local Ollama, your own GPU server, a hosted provider — even closed models like GPT and Gemini. mantis works out where the model lives and speaks its dialect. Moving is a one-line change, not a rewrite.
Write a function. It becomes a tool.
Decorate any Python function and every model can call it — even the ones that never learned function calling. mantis finds a way, and you never think about it.
Plug into the MCP ecosystem
Connect the same MCP servers Claude Code uses — filesystems, browsers, databases — or expose your own tools as one. Your open model gets the whole ecosystem.
Pick up where you left off
Every conversation is saved as it happens. Close the laptop, come back tomorrow, resume — or fork a session and try a different approach. Long chats compact themselves.
Build teams, not monoliths
Hand an agent smaller agents as tools — a researcher, a reviewer, a fixer — and set rules for what each one may touch. Approve, deny, or rewrite any call before it runs.
Spend with a ceiling
Cap any run in dollars or turns. Every response tells you what it cost, and the run stops cleanly before it overspends — no surprise bills from a runaway loop.
Every model gets tool use.
Not every open model knows how to call functions. mantis meets each one where it is — you write the tool once, and it picks the right way in for whatever model is in front of it.
Models that speak function calling — Qwen, Llama 3, gpt-oss — get called directly. The fast path.
Older models never learned the schema, so mantis teaches it in the prompt and parses the reply. Tool use for models that “can't do tools.”
Where the server can enforce a grammar, the model physically cannot produce a malformed call. The strict path.
Pick the highest-ranked model that fits your hardware.
| Model | Runs | model= | Notable |
|---|---|---|---|
| Kimi K2.6 | cloud | moonshotai/Kimi-K2.6-Instruct | #1 open-weights GPQA |
| Qwen3 235B-A22B | cloud · 64 GB+ | Qwen/Qwen3-235B-A22B-Instruct-Turbo | Apache 2.0, broad leader |
| GLM-5 | cloud | zai-org/GLM-5 | Best open Arena Elo |
| MiniMax M2.5 | cloud | minimaxai/MiniMax-M2.5 | 80.2% SWE-bench |
| DeepSeek-V3.2 | cloud · 80 GB+ | deepseek-ai/DeepSeek-V3.2 | Top general-purpose OSS |
| gpt-oss-120b | cloud · 80 GB | gpt-oss:120b | OpenAI open, ~o4-mini class |
| Qwen2.5-Coder 7B | 8 GB local | qwen2.5-coder:7b | Strongest small coder |
| qwen2.5:1.5b | 4 GB local | qwen2.5:1.5b | CPU default, tool-capable |
Full ranked catalog — 20 hosted + 10 CPU-friendly tiers — in Models & backends.
See what every run did — and what it cost.
Every run produces a full trace: each turn, each model call, each tool call, with tokens and dollars totalled at the top. Keep it in memory while you develop, or ship the same trace to Datadog, Honeycomb, or any OpenTelemetry pipeline with one line. And traces record which fields a tool was given — never their values — so nothing sensitive leaves the house.
from mantis_agent import Agent, InMemoryTracer
tracer = InMemoryTracer()
agent = Agent(model="qwen2.5:7b", tools=[...], tracer=tracer)
await agent.run(...)
tracer.summary() # turns / tokens / cost_usd on the root span
tracer.write_jsonl("t.jsonl")
# ship the same spans to Datadog / Honeycomb / Tempo — zero extra code
from mantis_agent import OTelTracer
agent = Agent(model="qwen2.5:7b", tracer=OTelTracer(service_name="my-agent"))On a fresh machine, no GPU. Works on the first try.
pip install mantis-agent-sdk
mantis-agent setup-local # pulls a CPU-friendly model, smoke-tests
python my_agent.py # two tools, a 5-turn task — first tryChange one word — model= — and the same script runs against Together, Fireworks, vLLM, llama.cpp, or Groq.
A new model drops every week. Your code doesn't move a line.
The ecosystem keeps shipping; the loop keeps hunting. Same agent, same tools, same sessions — whatever lands next. pip install mantis-agent-sdk