Skip to main content

minmo

CI PyPI License: MIT Python

Boilerplate-free SDK for building voice agents, with a single API across AssemblyAI (default), Hume, and ElevenLabs.

Define a prompt, register Python functions as tools, deploy. minmo handles JSON-Schema generation, local tool hosting + tunneling, and talking to each provider's REST API — so you write the assistant, not the plumbing.

  • One decorator, real tools@agent.tool turns a typed Python function into a JSON-Schema tool, inferred from its signature and docstring.
  • No server to writedeploy(local=True) spins up a local tool server and tunnels it publicly for you.
  • Provider-agnostic — swap AssemblyAI, Hume, or ElevenLabs by changing one argument; minmo normalizes what each API needs.
  • Test without burning session minutessimulate() runs your tools against any OpenAI-compatible LLM, no live voice session required.

Install

pip install minmo

(Contributing or want an editable checkout instead? pip install -e ".[dev]" after cloning.)

(Set NGROK_AUTHTOKEN in your environment if you plan to use local=True — see pyngrok's docs for how to get one.)

Quickstart

from minmo import VoiceAgent

agent = VoiceAgent(
    prompt="You are a friendly voice assistant. Keep answers short.",
    api_key="YOUR_ASSEMBLYAI_API_KEY",
)


@agent.tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"It's sunny in {city}."


result = agent.deploy(local=True)
print(result)  # the created AssemblyAI agent record, including its id

That's it — deploy(local=True) starts a local tool server, tunnels it publicly, and registers get_weather as a real tool your live voice agent can call.

result always includes an "info" field — a plain-language paragraph telling you whether the agent is hosted on the provider's servers or only exists locally, and how to actually connect to it (usually via mint_token()). Worth printing after every deploy, especially since this differs per provider — see below.

Testing tool logic without burning session minutes

from minmo import VoiceAgent
from minmo.testing import simulate

agent = VoiceAgent(
    prompt="You are a friendly voice assistant.",
    api_key="YOUR_ASSEMBLYAI_API_KEY",
    llm={"base_url": "https://api.openai.com/v1", "model": "gpt-4o-mini", "api_key": "YOUR_OPENAI_KEY"},
)


@agent.tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"It's sunny in {city}."


result = simulate(agent, transcript=["What's the weather in Paris?"])
print(result["tool_calls"])

simulate() calls the llm you configured directly (any OpenAI-compatible endpoint) and runs tool calls against your local Python functions — no AssemblyAI session, no phone call.

Client-side tools (no server, no tunnel)

@agent.tool defaults to transport="http" — minmo hosts the function behind a URL AssemblyAI calls. Pass transport="client" instead to declare a client-side/function tool: no server, no tunnel, no host_url needed for that tool.

@agent.tool(transport="client")
def get_account_balance(account_id: str) -> str:
    """Look up an account's balance."""
    return "$42.00"

minmo only builds the correct agent config for this — declaring the tool as client-side. Running the actual session (the WebSocket connection that receives tool.call and sends back tool.result) is your own code's job: a browser app, a Twilio bridge, whatever already holds that live connection. If every registered tool is transport="client", deploy() skips the local server and tunnel (or host_url requirement) entirely — nothing to host.

Providers

minmo supports AssemblyAI (default), Hume, and ElevenLabs. They don't all host your agent the same way:

Provider Hosted on their servers? How you use it
AssemblyAI Yes — deploy() creates a persistent agent record mint_token() for a client token, connect a voice session with it
Hume Yes — deploy() creates/versions a config resource mint_token() for an access token, start an EVI session with it
ElevenLabs Yes — deploy() creates a persistent agent record mint_token() for a signed WebSocket URL, connect a conversation with it

Pass a different provider via VoiceAgent(provider=..., provider_options=...); see each provider's docstring in minmo/providers/ for required options.

CLI

minmo init     # scaffold main.py, .env.example, requirements.txt
minmo deploy   # import main.py, find the VoiceAgent, deploy it
minmo logs     # print the most recent session log

Deploying to a real server (not local=True)

agent.deploy(local=False, host_url="https://your-deployed-tool-server.example.com")
# or set MINMO_HOST_URL in the environment instead of passing host_url

Your host must already be running the tool server — local=True is for development; production tool hosting is up to you (minmo's local server factory, minmo.server.create_tool_server, is reusable if you want to deploy it yourself behind a real domain).

Development

pip install -e ".[dev]"
pytest -q

Pushes are auto-formatted with Black via GitHub Actions, and every push/PR runs the test suite across Python 3.10–3.12.

scripts/smoke_test.py is a live smoke test — it calls deploy() and mint_token() against real provider APIs (reading credentials from a gitignored .env) and skips any provider whose env vars aren't set. It makes real network calls, so it's run manually, not in CI:

python scripts/smoke_test.py

Contributing

Issues and PRs welcome. Keep changes small and covered by a test.

License

MIT © Anas Abuelhaag

Download files

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

Source Distribution

minmo-0.3.0.tar.gz (212.9 kB view details)

Uploaded Source

Built Distribution

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

minmo-0.3.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

File details

Details for the file minmo-0.3.0.tar.gz.

File metadata

  • Download URL: minmo-0.3.0.tar.gz
  • Upload date:
  • Size: 212.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for minmo-0.3.0.tar.gz
Algorithm Hash digest
SHA256 241801e4febcc6285f9140ecf063a975131d78760793160127a6010040a023b4
MD5 412d191ad24ef98d2bb1d1a16e12de95
BLAKE2b-256 7096c0922e72fe7eb2b2cd573beb7d18784c895dca26c639dd98eb12c91a2f68

See more details on using hashes here.

Provenance

The following attestation bundles were made for minmo-0.3.0.tar.gz:

Publisher: publish.yml on a-elhaag/minmo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file minmo-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: minmo-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 19.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for minmo-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 686ab7c41738f33b241fdba9a0be10d66b3c7ba69136b8c18f7b9e2a7778dfb5
MD5 6a6cb787bde22ab0c994db4708075596
BLAKE2b-256 b60c355ea63d23b2568773bd0212dffaada2c946dbd328b07013929d54587f14

See more details on using hashes here.

Provenance

The following attestation bundles were made for minmo-0.3.0-py3-none-any.whl:

Publisher: publish.yml on a-elhaag/minmo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page