Agent API Launch
Deploy AI agents as HTTP APIs or MCP servers for integration with external applications.
PraisonAI Agents can be deployed as HTTP APIs or MCP (Model Context Protocol) servers, enabling seamless integration with web applications, microservices, and other systems.
from praisonaiagents import Agent
agent = Agent(name="api-agent", instructions="Answer HTTP API requests.")
agent.launch(port=8000)The user deploys an agent as an HTTP or MCP service; external apps call the API instead of importing the SDK directly.
How It Works
An external client calls the launched endpoint, and the agent runs the request before returning the response.
Choose a Protocol
Pick the launch protocol that matches the caller.
Authentication
.launch() binds to 127.0.0.1 by default and enforces a bearer token the moment you expose it beyond localhost.
.launch() has three authentication states:
| State | Trigger | Behaviour |
|---|---|---|
| Keyless dev | No token + loopback host | No auth needed. agent.launch(port=8000) just works locally. |
| Enforced | PRAISONAI_LAUNCH_AUTH_TOKEN set | Every request must send the token or gets 401 Unauthorized. |
| Fail-closed | No token + non-loopback host | The SDK auto-generates a one-time bearer token, prints it once to stdout, and enforces it. |
Loopback hosts are 127.0.0.1, ::1, and localhost. Anything else (0.0.0.0, a LAN IP) is treated as non-loopback.
Local dev (keyless)
Loopback is the default, so no token is needed:
from praisonaiagents import Agent
agent = Agent(name="dev", instructions="Answer.")
agent.launch(port=8000) # binds 127.0.0.1, no token neededcurl -X POST http://localhost:8000/ \
-H "Content-Type: application/json" \
-d '{"message": "hi"}'Public bind (preset token)
Set a token before binding to a public host:
export PRAISONAI_LAUNCH_AUTH_TOKEN=$(openssl rand -base64 32)from praisonaiagents import Agent
agent = Agent(name="public", instructions="Answer.")
agent.launch(host="0.0.0.0", port=8000) # enforces the token abovecurl -X POST http://SERVER:8000/ \
-H "Authorization: Bearer $PRAISONAI_LAUNCH_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "hi"}'Public bind (auto-token)
Bind publicly without a preset token and the SDK prints a one-time token:
from praisonaiagents import Agent
agent = Agent(name="public", instructions="Answer.")
agent.launch(host="0.0.0.0", port=8000)
# Prints once to stdout:
# \U0001F510 launch() bound to non-loopback host '0.0.0.0' without
# PRAISONAI_LAUNCH_AUTH_TOKEN set. Generated a one-time bearer token
# (set PRAISONAI_LAUNCH_AUTH_TOKEN to override): <TOKEN>Capture the printed `
and send it on every request as the Authorization: Bearer` header.
Quick Start
- Install Package
Install PraisonAI Agents:
bash pip install praisonaiagentsFor MCP support, also install:
bash pip install praison-mcp - Create an Agent
Create an agent to deploy as an API:
python from praisonaiagents import Agent # Create your agent agent = Agent( name="API Assistant", role="API helper", goal="Answer questions and perform tasks via API", backstory="An AI assistant accessible through HTTP endpoints", llm="gpt-4o-mini" ) - Launch as API
Deploy the agent as an HTTP API:
python # Launch as HTTP API agent.launch( protocol="http", # Default protocol host="127.0.0.1", # Loopback default; set "0.0.0.0" to expose (requires a token) port=8000, path="/assistant" # Available at http://localhost:8000/assistant ) - Test the API
Test your deployed agent API:
bash curl -X POST http://localhost:8000/assistant \ -H "Content-Type: application/json" \ -d '{"message": "Hello, how can you help me?"}'
Launch Methods
HTTP API Server
The most common deployment method is as an HTTP API server using FastAPI:
from praisonaiagents import Agent
# Create agent
agent = Agent(
name="Customer Support",
role="Support specialist",
goal="Help customers with their inquiries",
tools=["web_search", "knowledge_base"] # Optional tools
)
# Launch as HTTP API
agent.launch(
protocol="http", # Protocol type (default: "http")
host="127.0.0.1", # Loopback default; set "0.0.0.0" to expose (requires a token)
port=8000, # Port number
path="/support", # API endpoint path
debug=False # Debug mode for development
)
# API will be available at:
# POST http://localhost:8000/supportMCP Server
For Model Context Protocol integration:
from praisonaiagents import Agent
# Create agent
agent = Agent(
name="SearchAgent",
instructions="Search the internet for information",
llm="gpt-4o-mini"
)
# Launch as MCP server
agent.launch(
protocol="mcp", # MCP protocol
port=8080, # Port number
host="127.0.0.1" # Loopback default; set "0.0.0.0" to expose (requires a token)
)
# MCP server will create SSE endpoints
# Tool will be named: execute_SearchAgent_taskLifecycle: when does launch() return and when does the script exit?
In HTTP mode, launch() returns immediately; a script stays alive at exit until Ctrl+C. REPLs and notebooks never block.
A single keep-alive hook is registered once, the first time launch() runs in a non-interactive script. The behaviour no longer depends on any text in your file — a string such as "call team.launch(port=1)" later in the script no longer makes it exit early.
Multiple launches
Every .launch() call runs, the code after them runs, and the script waits once at exit.
from praisonaiagents import Agent
sales = Agent(name="Sales", instructions="You help with sales")
support = Agent(name="Support", instructions="You help with support")
sales.launch(path="/sales", port=8000) # returns immediately
support.launch(path="/support", port=8001) # also runs
print("Both servers are up") # runs too
# Script end: waits here until Ctrl+CREPL / notebook
In an interactive session or Jupyter notebook, agent.launch(...) returns immediately and nothing waits at exit — the running kernel keeps the server threads alive.
API Usage
When launched as an HTTP API, agents expose a single endpoint that accepts POST requests:
HTTP API Endpoint
POST /path
Send messages to the agent and receive responses.
# Request
{
"message": "What's the weather like?"
}
# Response
{
"response": "I'd be happy to help with weather information..."
}The endpoint also supports form data:
curl -X POST http://localhost:8000/assistant \
-F "message=Hello, how are you?"Complete Examples
Example 1: Single Agent HTTP API
from praisonaiagents import Agent
# Create an agent with specific instructions
agent = Agent(
name="Research Assistant",
instructions="You are a helpful research assistant. Help users find and summarize information.",
llm="gpt-4o-mini"
)
# Launch the agent
agent.launch(
path="/research",
port=3030,
host="127.0.0.1" # Loopback default; set "0.0.0.0" to expose (requires a token)
)
# The agent is now available at http://localhost:3030/researchExample 2: Multi-Agent HTTP API System
from praisonaiagents import Agent, AgentTeam
# Create multiple specialized agents
research_agent = Agent(
name="Research",
instructions="Research and gather information on topics"
)
summarize_agent = Agent(
name="Summarize",
instructions="Create concise summaries of provided information"
)
# Create an agents collection
agents = AgentTeam(
name="ResearchTeam",
agents=[research_agent, summarize_agent]
)
# Launch all agents on the same endpoint
agents.launch(
path="/team",
port=8000,
host="127.0.0.1" # Loopback default; set "0.0.0.0" to expose (requires a token)
)
# All agents available at http://localhost:8000/teamExample 3: MCP Server with Tools
from praisonaiagents import Agent
# Create agent with tools
agent = Agent(
name="TweetAgent",
instructions="Create engaging tweets based on the topic provided",
tools=["web_search"] # Can include tools
)
# Launch as MCP server
agent.launch(
protocol="mcp",
port=8080,
host="127.0.0.1"
)
# MCP tool available as: execute_TweetAgent_taskExample 4: Multiple Endpoints on Same Port
from praisonaiagents import Agent
# Create different agents
sales_agent = Agent(
name="Sales",
instructions="Help with product information and sales"
)
support_agent = Agent(
name="Support",
instructions="Provide technical support"
)
# Launch on different paths but same port
sales_agent.launch(
path="/sales",
port=8000
)
support_agent.launch(
path="/support",
port=8000
)
# Both available on port 8000:
# - http://localhost:8000/sales
# - http://localhost:8000/supportMix Agent.launch() and AgentTeam.launch() on One Port
Agent.launch() and AgentTeam.launch() (aka PraisonAIAgents.launch()) share a single process-wide server registry.
In one process, a standalone agent and a team launched on the same port bind the same FastAPI app and the same uvicorn server — one / endpoint that lists both sets of routes, one /health, one /docs. You no longer get Address already in use when both call sites target the same port, and endpoints registered through one launcher are visible from the other.
from praisonaiagents import Agent, AgentTeam
assistant = Agent(name="Assistant", instructions="Answer.")
research = Agent(name="Research", instructions="Research topics.")
team = AgentTeam(name="Team", agents=[research])
# Same port — same FastAPI app / uvicorn server / route table
assistant.launch(path="/assistant", port=8000)
team.launch(path="/team", port=8000)
# curl http://localhost:8000/ # lists /assistant and /team
# curl http://localhost:8000/healthExample 5: Debug Mode for Development
from praisonaiagents import Agent
# Create agent
agent = Agent(
name="Dev Assistant",
instructions="Help with development tasks",
llm="gpt-4o-mini"
)
# Launch with debug mode enabled
agent.launch(
path="/dev",
port=8000,
debug=True # Enables auto-reload and detailed logging
)Launch Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
protocol | str | Launch protocol: “http” or “mcp” | “http” |
host | str | Host to bind to. Loopback by default; set "0.0.0.0" to expose (then a token is required). | “127.0.0.1” |
port | int | Port number | 8000 |
path | str | API endpoint path (HTTP) or base path (MCP) | “/” |
debug | bool | Enable debug mode with auto-reload | False |
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRAISONAI_SERVER_READY_TIMEOUT | 5.0 | Seconds .launch() waits for the shared HTTP server to become ready — used by both Agent.launch() and AgentTeam.launch(). Readiness is signalled only after uvicorn reports the socket is bound; on timeout, a warning is logged and execution continues. |
PRAISONAI_LAUNCH_AUTH_TOKEN | (unset) | Bearer token required by every request when set. Unset + loopback = keyless dev flow; unset + non-loopback = a one-time token is auto-generated, printed to stdout, and required on every request. See Authentication. |
Client Integration
Python Client
import requests
from typing import Dict, Any
class AgentAPIClient:
def __init__(self, base_url: str):
self.base_url = base_url.rstrip('/')
self.headers = {"Content-Type": "application/json"}
def chat(self, message: str) -> Dict[str, Any]:
response = requests.post(
self.base_url,
headers=self.headers,
json={"message": message}
)
response.raise_for_status()
return response.json()
# Usage
client = AgentAPIClient("http://localhost:8000/assistant")
response = client.chat("Hello!")
print(response["response"])JavaScript Client
class AgentAPIClient {
constructor(baseUrl) {
this.baseUrl = baseUrl.replace(/\/$/, '');
}
async chat(message) {
const response = await fetch(this.baseUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message })
});
if (!response.ok) {
throw new Error(`API error: ${response.statusText}`);
}
return response.json();
}
}
// Usage
const client = new AgentAPIClient('http://localhost:8000/assistant');
const response = await client.chat('Hello!');
console.log(response.response);MCP Client Integration
For MCP servers, use an MCP-compatible client:
from mcp import Client
# Connect to MCP server
client = Client("http://localhost:8080")
# Call the agent tool
result = await client.call_tool(
"execute_TweetAgent_task",
arguments={"input": "Create a tweet about AI"}
)Deployment Best Practices
- Use appropriate worker processes
- Enable connection pooling
- Monitor resource usage
- Consider horizontal scaling for high load
- Set
PRAISONAI_LAUNCH_AUTH_TOKENbefore exposing beyond localhost; the SDK auto-generates one if you don’t, but a rotation-managed preset token is preferred - Deploy behind a reverse proxy (nginx, Apache) for HTTPS and rate limiting
- Use HTTPS in production
- Validate and sanitize inputs
Production Deployment
Docker Deployment
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install praisonaiagents
# Copy agent code
COPY agent.py .
# Expose port
EXPOSE 8000
# Run agent API
CMD ["python", "agent.py"]# docker-compose.yml
version: '3.8'
services:
agent-api:
build: .
ports:
- "8000:8000"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
restart: unless-stoppedSystemd Service
# /etc/systemd/system/agent-api.service
[Unit]
Description=PraisonAI Agent API
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/agent-api
Environment="OPENAI_API_KEY=%OPENAI_API_KEY%"
ExecStart=/usr/bin/python3 /opt/agent-api/agent.py
Restart=always
[Install]
WantedBy=multi-user.targetNginx Reverse Proxy
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Important Notes
- Threading: The launch() method uses threading to run servers in the background
- Lifecycle:
launch()returns immediately; in a script, the process stays alive at exit until Ctrl+C (see Lifecycle) - Multiple Agents: You can run multiple agents and teams on the same port with different paths (HTTP mode only). All
.launch()call sites —Agent.launch(),AgentTeam.launch(),PraisonAIAgents.launch()— share one FastAPI app and one uvicorn server per port. - Dependencies: HTTP mode requires FastAPI and uvicorn, MCP mode requires praison-mcp
- API Documentation: HTTP APIs automatically get FastAPI documentation at
/docs
Troubleshooting
Port already in use
- Check if another process is using the port:
lsof -i :8000 - Kill the process or use a different port
- Ensure previous agent instances are properly stopped
Missing dependencies
- For HTTP:
pip install fastapi uvicorn - For MCP:
pip install praison-mcp mcp - Check error messages for specific missing packages
Agent not responding
- Check console for error messages
- Verify API key is set correctly
- Test with debug=True for more detailed logs
- Ensure agent initialization is successful
Connection refused
- Verify the host and port settings
- Check firewall rules
- Ensure the agent is actually running
- Try connecting from localhost first
Agent server slow to start
If you see Agent server on port N did not become ready within 5.0s in the logs, the FastAPI server took longer than the default 5s to come up. This is usually safe (.launch() still returns and the server keeps starting), but you can raise the wait:
export PRAISONAI_SERVER_READY_TIMEOUT=15 # secondsCommon causes: slow imports, cold-start on resource-constrained machines, blocking startup hooks.
If a bind fails (Address already in use, missing dependency), the SDK logs a warning and clears the port’s readiness flag so the next .launch() call on that port re-attempts the bind. You do not need to restart the process.
Next Steps
Detailed Agent API documentation
MCP IntegrationLearn more about Model Context Protocol
Best Practices
Pick the protocol that matches your caller
Use protocol="http" for web apps, cURL, and microservices that speak REST, and protocol="mcp" when the caller is an MCP-compatible agent host. HTTP is the default, so agent.launch(port=8000) gives you a POST endpoint with automatic FastAPI docs at /docs. Switch only when the consumer requires MCP tools.
Share a port with distinct paths, not duplicate ones
Multiple agents can run on the same port when each uses a unique path. Registration is atomic across threads, but if two .launch() calls reuse the same path on the same port the second is auto-suffixed (/path_abc123) and a warning is logged. Assign explicit, distinct paths (/sales, /support) so clients always hit the agent they expect.
Tune the readiness timeout for slow cold starts
.launch() returns only after the port accepts connections, waiting up to 5 seconds by default. On resource-constrained machines or with heavy imports, raise the wait so startup logs aren’t misread as failures:
export PRAISONAI_SERVER_READY_TIMEOUT=15A timeout logs a warning but does not abort — the server keeps starting in the background.
Set a token before exposing, and terminate TLS at the edge
The launch server now enforces its own bearer auth: set PRAISONAI_LAUNCH_AUTH_TOKEN before binding to a non-loopback host, or the SDK auto-generates a one-time token and prints it. A reverse proxy (nginx) is still recommended for HTTPS and rate limiting, but it is no longer the only thing standing between the internet and your agent. Bind to 127.0.0.1 (the default) when the proxy runs on the same host.