Skip to main content

Minimal agent runtime with MCP integration, declarative tools, and streaming

Project description

agentory

A lightweight Python library for building tool-calling agents.

Installation

pip install agentory

Install only the providers you actually need

pip install "agentory[openai]" # + azure
pip install "agentory[anthropic]"
pip install "agentory[all]"

Requires Python 3.12+.

Quickstart

import asyncio
from llmify import ChatOpenAI
from agentory import Agent, Tools, ToolCallEvent

tools = Tools()

@tools.action("Return the current UTC time as an ISO-8601 string.")
def get_time() -> str:
    from datetime import datetime, timezone
    return datetime.now(timezone.utc).isoformat()

async def main():
    llm = ChatOpenAI(model="gpt-5.4-mini")
    agent = Agent(
        instructions="You are a helpful assistant.",
        llm=llm,
        tools=tools,
    )
    async for event in agent.run("What time is it?"):
        if isinstance(event, ToolCallEvent):
            print(f"[tool] {event.tool_name}: {event.status}")
        else:
            print(event)

asyncio.run(main())

Core API

Agent

Agent(
    instructions: str,
    llm: ChatOpenAI | ChatAzureOpenAI | ChatAnthropic,
    tools: Tools | None = None,
    mcp_servers: list[MCPServer] | None = None,
    skills: list[Skill] | None = None,
    max_iterations: int = 10,
    context: T | None = None,
)

The main agent class. Call agent.run(task) to get an AsyncIterator[StreamEvent] that yields either plain str chunks or ToolCallEvent objects.

context is an arbitrary value (or tuple/list of values) injected into every tool function that declares a matching parameter type. Parameters with non-JSON types (custom classes) are automatically detected and filled from the context.

from agentory import Agent, Tools

class SpotifyClient: ...
class UnsplashClient: ...

tools = Tools()

@tools.action("Search tracks on Spotify.")
async def search_tracks(spotify: SpotifyClient, query: str) -> str:
    ...

@tools.action("Search photos on Unsplash.")
async def search_photos(unsplash: UnsplashClient, query: str) -> str:
    ...

agent = Agent(
    instructions="...",
    llm=llm,
    tools=tools,
    context=(SpotifyClient(), UnsplashClient()),
)

Each tool only receives the context objects whose types match its parameter annotations. Primitive-typed parameters (str, int, bool, float, list, dict) are treated as normal LLM-provided arguments.

Tools

A registry that turns plain functions into LLM-callable tools.

tools = Tools()

@tools.action("Fetch the content of a URL.", status=lambda a: a["url"])
async def fetch(url: str) -> str:
    ...
  • description – shown to the LLM in the tool schema.
  • name – overrides the function name.
  • status – a string or callable producing a human-readable status shown during streaming.

Type hints on parameters are automatically converted to JSON Schema. Use Annotated[str, "description"] to attach per-parameter descriptions.

Tool

Low-level dataclass representing a single tool. Usually created via Tools.action; useful when constructing tools manually or from MCP servers.

Skill

A piece of reusable instructions injected into the system prompt inside a <skill> block.

from pathlib import Path
from agentory import Skill

skill = Skill.from_path(Path("my_skill.md"))
# or load SKILL.md from a directory:
skill = Skill.from_directory(Path("skills/my_skill/"))

agent = Agent(instructions="...", llm=llm, skills=[skill])

Skill files use optional YAML frontmatter for name and description:

---
name: web-search
description: Search the web for information
---

Use the search tool whenever the user asks about recent events...

MCPServerStdio

Connects to any Model Context Protocol server over stdio and exposes its tools to the agent.

from agentory import Agent, MCPServerStdio

server = MCPServerStdio(
    command="npx",
    args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
)

async with server:
    agent = Agent(instructions="...", llm=llm, mcp_servers=[server])
    async for event in agent.run("List files in /tmp"):
        print(event)

Options:

Parameter Default Description
command Executable to spawn
args [] Arguments for the command
env None Extra environment variables (inherits current env when None)
cache_tools_list True Cache tool discovery after first call
allowed_tools None Whitelist of tool names to expose

StreamEvent

type StreamEvent = str | ToolCallEvent

Events yielded by agent.run(). A plain str is a text chunk from the LLM; a ToolCallEvent signals that a tool is being called.

@dataclass
class ToolCallEvent:
    tool_name: str
    status: str | None

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentory-0.1.2.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentory-0.1.2-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file agentory-0.1.2.tar.gz.

File metadata

  • Download URL: agentory-0.1.2.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.2

File hashes

Hashes for agentory-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d5d90018153183ae53774eaa772d937971fdfb17e455f779f6ee9dd6524a5855
MD5 c7c6a0fd43489f0f39b05f6b5df55fe7
BLAKE2b-256 594042dbaef880d95acd50369d5c220df603d6098910697abf96738277ea98f4

See more details on using hashes here.

File details

Details for the file agentory-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: agentory-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.2

File hashes

Hashes for agentory-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 66ba733132eb4ddfdcd2ecf4d4410829b622e0468d4ce545085b872517da9cef
MD5 9173ef0245213ee535cdbb6ff366829a
BLAKE2b-256 f63217119bc74a23a44efa7cfa01c292cb5842c1c0df55d738847e862ca5370b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page