mycode-sdk
Lightweight Python SDK for building AI agents. Multi-turn conversations, tool calling, session persistence, and streaming events. Provider adapters for Anthropic, OpenAI, Google, and more.
Install
uv add mycode-sdk
# or
pip install mycode-sdk
Quick start
import asyncio
from mycode import Agent, bash_tool, read_tool
async def main() -> None:
agent = Agent(
model="claude-sonnet-4-6",
api_key="YOUR_API_KEY",
tools=[read_tool, bash_tool],
)
async for event in agent.achat("Read pyproject.toml and tell me the project name."):
if event.type == "text":
print(event.data["delta"], end="", flush=True)
asyncio.run(main())
Agent(...) infers the provider from the model id. No tools are registered unless you pass tools=[...].
For a synchronous call, use run():
result = agent.run("Read pyproject.toml and tell me the project name.")
print(result.text)
Providers
The SDK infers the provider from the model string (claude-* to Anthropic, gpt-* to OpenAI, etc.). API keys are auto-discovered from environment variables:
| Provider | id | Env var |
|---|---|---|
| Anthropic | anthropic |
ANTHROPIC_API_KEY |
| OpenAI | openai |
OPENAI_API_KEY |
| Google Gemini | google |
GEMINI_API_KEY |
| Moonshot | moonshotai |
MOONSHOT_API_KEY |
| MiniMax | minimax |
MINIMAX_API_KEY |
| DeepSeek | deepseek |
DEEPSEEK_API_KEY |
| Z.AI | zai |
ZAI_API_KEY |
| OpenRouter | openrouter |
OPENROUTER_API_KEY |
| Alibaba Cloud | alibaba |
DASHSCOPE_API_KEY |
| xAI | xai |
XAI_API_KEY |
| OpenAI-compatible | openai_chat |
- |
Pass api_key= to override the env var, api_base= for a custom endpoint. Model metadata is bundled from models.dev; pass context_window, supports_reasoning, supports_image_input, or supports_pdf_input to override.
Multi-turn conversations
Call achat() or run() again on the same Agent to continue:
agent = Agent(model="claude-sonnet-4-6", api_key="...")
agent.run("What is 2 + 2?")
agent.run("Now multiply that by 10.") # remembers the earlier answer
agent.clear() drops in-memory history. agent.messages accumulates across calls.
Attachments
Pass attachments to achat() or run() to add files alongside the prompt:
from mycode import Attachment
agent.run("Describe these.", attachments=["diagram.png", "report.pdf", "notes.txt"])
# Or build them explicitly:
agent.run(
"Review.",
attachments=[
Attachment.path("diagram.png"),
Attachment.bytes(png_data, media_type="image/png"),
Attachment.text("TODO: ship it", name="note.md"),
],
)
Images support image/png, image/jpeg, image/gif, image/webp; documents support application/pdf. Sending an image or PDF to a model without that capability yields an error event. A bad path or unsupported type raises ValueError before the provider is called.
Saving sessions
Pass session_dir to persist the conversation to disk. Each session lives in a subdirectory named by session_id:
from pathlib import Path
agent = Agent(
model="claude-sonnet-4-6",
api_key="...",
session_dir=Path("./chats"),
session_id="my-chat",
)
Construct another Agent with the same (session_dir, session_id) to load the conversation history.
Built-in tools
from mycode import read_tool, write_tool, edit_tool, bash_tool
Four tools for reading, writing, editing files, and running shell commands. Opt in by passing them to tools=[...].
Custom tools
Decorate a typed function with @tool:
from mycode import Agent, tool
@tool
def greet(name: str) -> str:
"""Return a friendly greeting.
Args:
name: Person name.
"""
return f"hello, {name}"
agent = Agent(
model="claude-sonnet-4-6",
api_key="...",
tools=[greet],
)
To call a built-in tool from inside your own tool, type the first parameter as ToolContext:
from mycode import ToolContext, tool
@tool
def summarize_file(ctx: ToolContext, path: str) -> str:
"""Return the first line of a text file."""
result = ctx.read(path)
return result.output.splitlines()[0] if result.output else ""
Async tools use await ctx.aread(), await ctx.awrite(), await ctx.aedit(), and await ctx.abash(). Use await ctx.acall(name, args) to call another registered tool by name.
Tool hooks
Inspect or replace tool calls before they run. Return None from before_tool to let the tool execute, or a ToolExecutionResult to skip it:
from mycode import Agent, Hooks, ToolExecutionResult, bash_tool
hooks = Hooks()
@hooks.before_tool
async def block_rm(ctx):
cmd = str(ctx.tool_input.get("command") or "")
if ctx.tool_name == "bash" and "rm -rf" in cmd:
return ToolExecutionResult(output="error: blocked", is_error=True)
return None
agent = Agent(
model="claude-sonnet-4-6",
api_key="...",
tools=[bash_tool],
hooks=hooks,
)
@hooks.after_tool runs after the tool and can replace the result (audit, redact, etc.).
Further reading
See docs/sdk.md for the streaming event API, cancellation, retries, compaction, session internals, and the full Agent / @tool reference.
Release files for mycode-sdk 0.12.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mycode_sdk-0.12.0.tar.gz | 65.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mycode_sdk-0.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 140.5 kB
Release files / mycode_sdk-0.12.0.tar.gz
| Download URL | mycode_sdk-0.12.0.tar.gz |
|---|---|
| Size | 65.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c961dc0ea1eb8a0787801a1a598e760c4c86f4a9276999d3f8b59c92ef9fe6f3
|
|
BLAKE2b-256 checksum How to use checksums |
710593beec7f21a22f3cb15edc713f12dbf2b15d33de60d9c2b79c93bc78bd83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / mycode_sdk-0.12.0-py3-none-any.whl
| Download URL | mycode_sdk-0.12.0-py3-none-any.whl |
|---|---|
| Size | 75.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e75c8d8724c52257a84f2748a20864066bce29a332b9f3bbb91ce51559ba0d7
|
|
BLAKE2b-256 checksum How to use checksums |
95ea551712759a007d8372768f8d817a457e37453293c8a729fec221f387045a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|