mAIvn Python SDK for building agentic systems with typed tools and dependencies
Project description
maivn
Python SDK for building agentic systems with typed tools and dependencies.
The maivn SDK provides a clean, declarative interface for creating AI agents with:
- Typed tool definitions using decorators and Pydantic models
- Dependency injection between tools, agents, and external data
- Structured outputs with guaranteed schema conformance
- Multi-agent orchestration via Swarms
- Concurrent batch invocation for independent Agent and Swarm requests
- MCP integration for external tool servers
Features
- Declarative Tools: Define tools with
@agent.toolify(),agent.add_tool(...), orAgent(..., tools=[...])- functions or Pydantic models - Dependency Graph: Chain tools with
@depends_on_tool, inject secrets with@depends_on_private_data - Structured Output: Use
final_tool=Truefor guaranteed typed responses - Multi-Agent: Coordinate agents with
Swarmand@depends_on_agent - Batch Invocation: Run multiple independent
invoke()calls withbatch()orabatch() - Scheduled Invocation: Run any agent or swarm on a
cron(...),every(...), orat(...)schedule with bounded jitter, retry/backoff, misfire and overlap policies - Async Surface:
ainvoke()/astream()mirrorinvoke()/stream()for native asyncio code - MCP Support: Connect external MCP servers (stdio/HTTP) as tool providers
- Interrupts: Collect user input mid-execution with
@depends_on_interrupt - System Tools: Built-in
web_search,repl,think
Requirements
- Python 3.10+
Installation
pip install maivn
maivn depends on the public maivn-shared package and will install it automatically
from PyPI.
To install the public Studio companion and enable maivn studio from a normal shell:
pip install "maivn[studio]"
If you prefer to install the companion package directly, pip install maivn-studio also works.
Quick Start
Basic Agent with Tools
from maivn import Agent
from maivn.messages import HumanMessage
agent = Agent(
name='weather_agent',
description='Provides weather information',
system_prompt='You are a helpful weather assistant.',
api_key='your-api-key', # or set MAIVN_API_KEY env var
)
@agent.toolify(description='Get current weather for a city')
def get_weather(city: str) -> dict:
return {'city': city, 'temp': 72, 'condition': 'sunny'}
response = agent.invoke([HumanMessage(content='What is the weather in Austin?')])
print(response.content)
You can also register tools without decorators:
def get_weather(city: str) -> dict:
"""Get current weather for a city."""
return {'city': city, 'temp': 72, 'condition': 'sunny'}
agent = Agent(
name='weather_agent',
description='Provides weather information',
system_prompt='You are a helpful weather assistant.',
api_key='your-api-key',
tools=[get_weather],
)
# Or add tools after construction.
agent.add_tool(get_weather)
Fast Structured Output
Use .structured_output() to bypass the orchestrator for faster responses:
from pydantic import BaseModel, Field
class SentimentAnalysis(BaseModel):
sentiment: str = Field(..., description='positive, negative, or neutral')
confidence: float = Field(..., ge=0, le=1)
# Fast path - bypasses orchestrator, tools still execute as needed
response = agent.structured_output(SentimentAnalysis).invoke(
[HumanMessage(content='Analyze: "I love this product!"')]
)
Structured Output with Full Orchestration
Use final_tool pattern when you need full orchestration for complex workflows:
from pydantic import BaseModel, Field
@agent.toolify(final_tool=True)
class WeatherReport(BaseModel):
"""Structured weather report."""
city: str = Field(..., description='City name')
temperature: int = Field(..., description='Temperature in Fahrenheit')
summary: str = Field(..., description='Human-readable weather summary')
# Full orchestration for complex workflows
response = agent.invoke(
[HumanMessage(content='Weather report for Austin')],
force_final_tool=True,
)
Concurrent Batch Invocation
Use batch() when you have multiple independent requests for the same agent or
swarm. The SDK runs the underlying invoke() calls concurrently and returns
responses in the same order as the inputs.
batch_inputs = [
[HumanMessage(content='Summarize ticket A')],
[HumanMessage(content='Summarize ticket B')],
[HumanMessage(content='Summarize ticket C')],
]
responses = agent.batch(
batch_inputs,
max_concurrency=3,
force_final_tool=True,
)
# Async variant
responses = await agent.abatch(batch_inputs, max_concurrency=3)
Scheduled Invocation
Run any agent or swarm on a cadence with optional jitter and retry. The
builder mirrors invoke / stream / batch and the async variants:
from datetime import timedelta
from maivn import JitterSpec, Retry
job = agent.cron(
'0 9 * * MON-FRI', # weekdays at 09:00
tz='America/New_York',
jitter=JitterSpec.symmetric(timedelta(minutes=10)), # ±10 min uniform
retry=Retry(max_attempts=3, backoff='exponential', base=timedelta(seconds=30)),
).invoke([HumanMessage(content='Compose the daily ops briefing.')])
job.on_fire(lambda r: print(f'fired at {r.fired_at}, jitter={r.jitter_offset}'))
job.on_error(lambda r: alert(r.error))
# ... later
job.stop(drain=True)
scope.every(timedelta(minutes=15)) and scope.at(when) are also
available. See the Scheduled Invocation guide
and Scheduling reference for the full surface.
Tool Dependencies
from maivn import depends_on_tool
@agent.toolify(description='Fetch raw sensor data')
def fetch_sensor_data(sensor_id: str) -> dict:
return {'sensor_id': sensor_id, 'readings': [72, 73, 71]}
@agent.toolify(description='Analyze sensor readings')
@depends_on_tool(fetch_sensor_data, arg_name='sensor_data')
def analyze_readings(sensor_data: dict) -> dict:
readings = sensor_data['readings']
return {'average': sum(readings) / len(readings)}
Private Data Injection
from maivn import depends_on_private_data
@agent.toolify(description='Call external API')
@depends_on_private_data(data_key='api_secret', arg_name='secret')
def call_api(query: str, secret: str) -> dict:
# 'secret' is injected server-side, never exposed to LLM
return {'result': f'Called API with query: {query}'}
# Set private data (stays server-side)
agent.private_data = {'api_secret': 'sk-xxx'}
Multi-Agent with Swarm
from maivn import Agent, Swarm, depends_on_agent
researcher = Agent(
name='researcher',
description='Research specialist',
system_prompt='You research topics thoroughly.',
api_key='your-api-key',
)
writer = Agent(
name='writer',
description='Content writer',
system_prompt='You write clear, engaging content.',
api_key='your-api-key',
use_as_final_output=True, # This agent produces final output
included_nested_synthesis='auto', # default: orchestrator/runtime decides
)
@researcher.toolify(description='Research a topic')
def research_topic(topic: str) -> dict:
return {'findings': f'Research findings about {topic}'}
@writer.toolify(description='Write article')
@depends_on_agent(researcher, arg_name='research')
def write_article(research: dict) -> dict:
return {'article': f'Article based on: {research["findings"]}'}
swarm = Swarm(
name='content_team',
agents=[researcher, writer],
)
response = swarm.invoke(
HumanMessage(content='Write about AI agents'),
force_final_tool=True,
)
Security
Your code stays local. All function tools and MCP tools execute in your environment - code is never transferred to or executed on maivn servers.
The maivn server only receives tool schemas (names, descriptions, parameters) and orchestrates execution. The actual tool code runs locally in your environment, ensuring:
- Your business logic remains private
- Sensitive data processed by tools stays local
- You have full control over tool access and permissions
Scalability
Thousands of tools, no problem. The maivn system provides high-performance tool management for agents and swarms with large tool catalogs. Tool selection and orchestration remain fast and accurate regardless of how many tools you register.
Core Concepts
| Concept | Description |
|---|---|
| Agent | Container for tools, configuration, and invocation logic |
| Swarm | Coordinates multiple agents with shared tool access |
| Tool | Function or Pydantic model exposed to the LLM |
| Dependency | Declares data flow between tools/agents |
| Final Tool | Marked tool that produces the structured output |
| Private Data | Server-side secrets injected at execution time |
Public API
Core Classes
| Class | Description |
|---|---|
Agent |
Main agent class with tools and invocation |
Swarm |
Multi-agent orchestration container |
Client |
HTTP connection manager (usually auto-created) |
ClientBuilder |
Factory for creating Client instances |
BaseScope |
Base class for Agent/Swarm |
MCPServer |
MCP server configuration |
MCPAutoSetup |
Auto-setup for uvx-based MCP servers |
ScheduledJob |
Lifecycle handle returned by cron/every/at |
JitterSpec |
Bounded randomness for scheduled fires |
Retry |
Retry policy with constant/linear/exp backoff |
RunRecord |
Outcome of a single scheduled fire |
Decorators
| Decorator | Description |
|---|---|
@agent.toolify() |
Register a function/model as a tool |
@depends_on_tool(tool, arg) |
Inject output from another tool |
@depends_on_agent(agent, arg) |
Inject output from another agent |
@depends_on_private_data(key, arg) |
Inject server-side secret |
@depends_on_interrupt(arg, prompt, handler) |
Collect user input |
Configuration
| Function | Description |
|---|---|
ConfigurationBuilder.from_environment() |
Load config from env vars |
get_configuration() |
Get current configuration |
MaivnConfiguration |
Configuration model |
Logging
| Function | Description |
|---|---|
configure_logging(log_file) |
Initialize SDK logging |
get_logger() |
Get SDK logger instance |
Messages
Import from maivn.messages:
| Class | Description |
|---|---|
HumanMessage |
User input message |
AIMessage |
Assistant response |
SystemMessage |
System prompt |
RedactedMessage |
Message with sensitive data redacted |
Environment Variables
| Variable | Description | Default |
|---|---|---|
MAIVN_API_KEY |
API key for authentication | Required |
MAIVN_TIMEOUT |
HTTP request timeout (seconds) | 600 |
MAIVN_TOOL_EXECUTION_TIMEOUT |
Per-tool timeout (seconds) | 900 |
MAIVN_DEPENDENCY_WAIT_TIMEOUT |
Dependency resolution timeout | 300 |
MAIVN_TOTAL_EXECUTION_TIMEOUT |
Total session timeout | 7200 |
MAIVN_ENABLE_BACKGROUND_EXECUTION |
Background tool execution | True |
MAIVN_LOG_LEVEL |
Logging level | INFO |
MAIVN_DEPLOYMENT_TIMEZONE |
Server timezone | UTC |
MAIVN_ENABLE_BACKGROUND_EXECUTION controls whether tool calls are dispatched
via a background thread pool. Set it to false to force inline, sequential
execution for more deterministic runs.
Documentation
API Reference
- API Reference Index
- Agent - Agent class reference
- Swarm - Swarm class reference
- Client - Client class reference
- Decorators - Dependency decorators
- Configuration - Configuration system
- MCP - MCP server integration
- Messages - Message types
- Logging - Logging system
- Scheduling -
cron/every/at, jitter, retry,ScheduledJob
Guides
- Getting Started - First steps
- Tools - Tool definition patterns
- Dependencies - Dependency management
- Structured Output - Final tool pattern
- Multi-Agent - Swarm orchestration
- Private Data - Security and secrets
- System Tools - Built-in tools
- Scheduled Invocation - Cron, jitter, retry, lifecycle
- mAIvn Studio - Studio UI + API reference
Reference
- Troubleshooting - Common errors and debugging
- Best Practices - Production patterns
Development
Setup
cd libraries/maivn
uv sync
Testing
uv run pytest
uv run pytest --cov=maivn --cov-report=term-missing
Coverage gate: 80% line coverage, excluding terminal reporter UI modules and MCP integration
modules as defined in pyproject.toml under tool.coverage.
Linting
uv run ruff check .
uv run ruff format .
uv run pyright
Releases
CIruns on pull requests and pushes to the default branch (mastertoday).Publish PyPIruns on version tags that matchv*.- Configure PyPI Trusted Publishing for this repository before the first release.
- See
DEPLOYMENT.mdfor the full GitHub and PyPI release procedure.
For standalone repo verification before maivn-shared is published, use a local checkout of
maivn-shared. The GitHub Actions workflow injects that temporary uv source override
automatically.
License
See LICENSE for details.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maivn-0.2.1.tar.gz.
File metadata
- Download URL: maivn-0.2.1.tar.gz
- Upload date:
- Size: 549.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a77b9b84c59b77d52c0f50e86cc882ac6e12584594037926c5ba157ec87f8f87
|
|
| MD5 |
d0d0a6f52c2819fbf7e1eb522c9ed0dd
|
|
| BLAKE2b-256 |
22cf9dbebc02859cddf181b4421de33c25c97b68e00ddadc2cda93673464e638
|
Provenance
The following attestation bundles were made for maivn-0.2.1.tar.gz:
Publisher:
publish-pypi.yml on mAIvn-developer/maivn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maivn-0.2.1.tar.gz -
Subject digest:
a77b9b84c59b77d52c0f50e86cc882ac6e12584594037926c5ba157ec87f8f87 - Sigstore transparency entry: 1437666884
- Sigstore integration time:
-
Permalink:
mAIvn-developer/maivn@8d63220ab85c8060f56cdecaeec42dc6d3ff85a0 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/mAIvn-developer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@8d63220ab85c8060f56cdecaeec42dc6d3ff85a0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file maivn-0.2.1-py3-none-any.whl.
File metadata
- Download URL: maivn-0.2.1-py3-none-any.whl
- Upload date:
- Size: 372.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d22fe80927a1f45ff014dd0ddbfed4b06cdc89205c5469d4603b6c11ecc683c
|
|
| MD5 |
ee63874a984c1c5bad0e694433113078
|
|
| BLAKE2b-256 |
06ec49cd58452869b9524b34d6a9ce20b6823fc6e14923aff618c1e01d2741b4
|
Provenance
The following attestation bundles were made for maivn-0.2.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on mAIvn-developer/maivn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maivn-0.2.1-py3-none-any.whl -
Subject digest:
6d22fe80927a1f45ff014dd0ddbfed4b06cdc89205c5469d4603b6c11ecc683c - Sigstore transparency entry: 1437666887
- Sigstore integration time:
-
Permalink:
mAIvn-developer/maivn@8d63220ab85c8060f56cdecaeec42dc6d3ff85a0 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/mAIvn-developer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@8d63220ab85c8060f56cdecaeec42dc6d3ff85a0 -
Trigger Event:
push
-
Statement type: