agentropic
A small, hackable agentic framework in ~500 lines you fully own and can read top to bottom in an afternoon:
- LLM calls go through litellm, so you get every provider (OpenAI, Anthropic, Gemini, Ollama, Bedrock, 100+ more) for free.
@tooldecorator turns any python function into an LLM-callable tool with an auto-generated JSON schema (from type hints + docstring).- MCP support — connect to any Model Context Protocol server (stdio or SSE) and its tools show up in your agent automatically, indistinguishable from local tools.
- Agent loop handles the call → tool-call → tool-result → call cycle for you, with memory, streaming, and a max-iteration safety valve.
Install (once published)
pip install agentropic
Quick start
import asyncio
from agentropic import Agent, tool
@tool()
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"It's sunny in {city}."
async def main():
agent = Agent(
name="assistant",
model="gpt-4o-mini", # any litellm model string
instructions="You are helpful and concise.",
tools=[get_weather],
)
print(await agent.arun("What's the weather in Paris?"))
asyncio.run(main())
Sync usage: agent.run("...") (wraps arun in asyncio.run for you).
Streaming (stream=True)
Same shape as the OpenAI / Anthropic SDKs. Tool calls work while streaming.
async for event in await agent.arun("Weather in Tokyo?", stream=True):
if event.type == "text":
print(event.text, end="", flush=True)
elif event.type == "tool_call":
print(f"\n[calling {event.tool_call.name}({event.tool_call.arguments})]")
elif event.type == "tool_result":
print(f"[-> {event.tool_call.result}]")
elif event.type == "done":
result = event.result # full AgentRunResult (usage, tool_calls, ...)
With verbose=True (the default) the colourful terminal tracer already prints
tokens live, so only print event.text yourself when using verbose=False
(e.g. rendering into your own UI).
Sync: for event in agent.run("...", stream=True): ...
Text only: async for token in agent.astream("..."): ...
Using MCP servers
from agentropic import Agent
from agentropic.mcp import StdioServer, HTTPServer
agent = Agent(
name="fs-agent",
model="gpt-4o-mini",
mcp_servers=[
StdioServer(command="npx", args=["-y", "@modelcontextprotocol/server-filesystem", "."]),
# HTTPServer(url="https://example.com/mcp", headers={"Authorization": "Bearer ..."}),
],
)
# Option A: connect once, keep servers alive across turns (recommended)
async with agent:
print(await agent.arun("List the files in the current directory."))
print(await agent.arun("Now read README.md"))
# Option B: no context manager — servers connect/disconnect around each run
print(await agent.arun("List the files in the current directory."))
Requires the optional MCP dependency: pip install "agentropic[mcp]", plus whatever
the server itself needs (e.g. Node.js for npx servers). Transports: StdioServer,
HTTPServer (streamable HTTP), SSEServer (legacy SSE).
Architecture
src/agentropic/
├── __init__.py # public API surface
├── agent.py # the run loop: LLM <-> tools <-> memory
├── llm.py # thin litellm wrapper (swap providers here)
├── tools.py # @tool decorator, Tool, ToolRegistry, schema generation
├── memory.py # in-memory conversation history (swap for your own store)
└── mcp/
└── client.py # MCP stdio/SSE client -> Tool adapter
Everything is a plain, editable python file — no hidden magic, no plugin
registry you can't inspect. Read agent.py first; that's the whole loop.
Extending it
- Custom memory / persistence: implement
.add(),.get(),.clear()matchingMemoryand passmemory=YourMemory()toAgent. - Multi-agent handoff: compose multiple
Agentinstances and route between them yourself, or wrap one agent'sarunas a tool for another.
Metadata
Release files for agentropic 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| agentropic-0.3.1.tar.gz | 49.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agentropic-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.9 kB
Release files / agentropic-0.3.1.tar.gz
| Download URL | agentropic-0.3.1.tar.gz |
|---|---|
| Size | 49.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ab589b61b385fefea1449623805311d9e6a574642e7daf580fe64544b0625088
|
|
BLAKE2b-256 checksum How to use checksums |
92411fcebc7659698766784a0eb66e50b77794ad8328cd731337fbfbe3526e9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.5
|
Release files / agentropic-0.3.1-py3-none-any.whl
| Download URL | agentropic-0.3.1-py3-none-any.whl |
|---|---|
| Size | 21.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9d18dac6fd4fb311c046bbec639be9dfee118d91b5c04028f6c89084fa79e737
|
|
BLAKE2b-256 checksum How to use checksums |
30682031d8163d79a19ac24f3cebbc4cf1a352db460ed9880904d05e9905b51e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.5
|
Security for agentropic 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.