> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Server: Unified

> Deploy a unified server with all PraisonAI providers

Deploy a unified server that combines all PraisonAI provider types in a single endpoint.

## CLI

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install "praisonai[serve]"
export OPENAI_API_KEY="your-key"

# Start unified server
praisonai serve unified --port 8765
```

**Expected Output:**

```
🚀 Starting Unified PraisonAI Server...
   Host: 127.0.0.1
   Port: 8765
   Providers: agents-api, recipe, mcp, a2a, a2u
📡 Discovery: http://127.0.0.1:8765/__praisonai__/discovery
✅ Server started at http://127.0.0.1:8765
```

## Python

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from fastapi import FastAPI
import uvicorn
from praisonaiagents import Agent

app = FastAPI(title="PraisonAI Unified Server")

# Create agents
assistant = Agent(
    name="Assistant",
    role="Helpful AI Assistant",
    goal="Help users with their questions",
    llm="gpt-4o-mini"
)

# Discovery endpoint
@app.get("/__praisonai__/discovery")
async def discovery():
    return {
        "schema_version": "1.0.0",
        "server_name": "praisonai-unified",
        "providers": [
            {"type": "agents-api", "name": "Agents API"},
            {"type": "recipe", "name": "Recipe Runner"},
            {"type": "mcp", "name": "MCP Server"},
            {"type": "a2a", "name": "A2A Protocol"},
            {"type": "a2u", "name": "A2U Event Stream"},
        ],
        "endpoints": [
            {"name": "agents", "provider_type": "agents-api"},
            {"name": "agent", "provider_type": "agents-api"},
            {"name": "mcp/tools", "provider_type": "mcp"},
            {"name": "a2a", "provider_type": "a2a"},
            {"name": "a2u/events", "provider_type": "a2u"},
        ]
    }

# Health endpoint
@app.get("/health")
async def health():
    return {"status": "healthy", "providers": 5}

# Agent endpoint
@app.post("/agent")
async def query_agent(request: dict):
    query = request.get("query", "")
    response = assistant.chat(query)
    return {"response": response}

uvicorn.run(app, host="0.0.0.0", port=8765)
```

<Note>
  `create_unified_app(..., api_key=...)` now installs the `_api_auth` middleware on every mounted route except `/health`. Existing callers that were passing `api_key=` but not sending `Authorization: Bearer` / `X-API-Key` from clients will start getting `401` — this closes a silent auth-bypass on the tool-driving routes.
</Note>

## Security

`praisonai serve unified` mounts tool-driving routes (notably `POST /v1/tools/invoke` via `mount_provider_routes`), so binding it to a non-localhost interface without authentication is refused.

<Warning>
  Binding to any host other than `127.0.0.1` / `localhost` / `::1` **requires** an API key. The server exits immediately (`SystemExit`) if neither `--api-key` nor `PRAISONAI_SERVE_API_KEY` is set.
</Warning>

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Localhost — no key required
praisonai serve unified --port 8765

# Remote — key required (via env var)
export PRAISONAI_SERVE_API_KEY="your-secret"
praisonai serve unified --port 8765 --host 0.0.0.0

# Or via flag
praisonai serve unified --port 8765 --host 0.0.0.0 --api-key "your-secret"
```

Clients send the key in `Authorization: Bearer …` or `X-API-Key: …`. The `/health` route is public.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Start[praisonai serve unified] --> Host{Host is<br/>localhost?}
    Host -->|Yes| Run[Start — no key needed]
    Host -->|No| Key{--api-key or<br/>PRAISONAI_SERVE_API_KEY?}
    Key -->|Set| Auth[Start — Bearer / X-API-Key enforced]
    Key -->|Missing| Exit[SystemExit — refuse to bind]

    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff
    classDef stop fill:#8B0000,stroke:#7C90A0,color:#fff

    class Host,Key decision
    class Run,Auth ok
    class Exit stop
```

## Unified Endpoints

| Endpoint                   | Method | Provider   | Description        |
| -------------------------- | ------ | ---------- | ------------------ |
| `/__praisonai__/discovery` | GET    | -          | Discovery document |
| `/health`                  | GET    | -          | Health check       |
| `/agents`                  | POST   | agents-api | Multi-agent router |
| `/agent`                   | POST   | agents-api | Single agent       |
| `/mcp/tools`               | GET    | mcp        | List MCP tools     |
| `/mcp/tools/call`          | POST   | mcp        | Call MCP tool      |
| `/.well-known/agent.json`  | GET    | a2a        | A2A agent card     |
| `/a2a`                     | POST   | a2a        | A2A messages       |
| `/a2u/info`                | GET    | a2u        | A2U info           |
| `/a2u/events/<stream>`     | GET    | a2u        | A2U event stream   |

## Discovery Document

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
curl http://localhost:8765/__praisonai__/discovery
```

**Response:**

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "schema_version": "1.0.0",
  "server_name": "praisonai-unified",
  "providers": [
    {"type": "agents-api", "name": "Agents API", "capabilities": ["invoke", "health"]},
    {"type": "recipe", "name": "Recipe Runner", "capabilities": ["list", "describe", "invoke"]},
    {"type": "mcp", "name": "MCP Server", "capabilities": ["list-tools", "call-tool"]},
    {"type": "a2a", "name": "A2A Protocol", "capabilities": ["agent-card", "message-send"]},
    {"type": "a2u", "name": "A2U Event Stream", "capabilities": ["subscribe", "stream"]}
  ],
  "endpoints": [...]
}
```

## Client Usage

Use the unified endpoints CLI to interact with any provider:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# List all endpoints
praisonai endpoints list --url http://localhost:8765

# Filter by provider type
praisonai endpoints list --url http://localhost:8765 --type agents-api

# Get discovery document
praisonai endpoints discovery --url http://localhost:8765

# Health check
praisonai endpoints health --url http://localhost:8765
```

## CLI Options

| Option      | Default     | Description                                                                                                                                                                                                  |
| ----------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--port`    | 8765        | Server port                                                                                                                                                                                                  |
| `--host`    | 127.0.0.1   | Server host                                                                                                                                                                                                  |
| `--api-key` | -           | API key. **Required when `--host` is not `127.0.0.1` / `localhost` / `::1`.** Can also be set via `PRAISONAI_SERVE_API_KEY`. Enforces `Authorization: Bearer` / `X-API-Key` on every route except `/health`. |
| `--file`    | agents.yaml | Agents configuration file                                                                                                                                                                                    |

## Environment Variables

| Variable                  | Default | Description                                                                                                                                                                                                                                                     |
| ------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PRAISONAI_SERVE_API_KEY` | -       | API key required to bind `praisonai serve unified` on a non-localhost host. The server exits with `SystemExit` if this is unset and no `--api-key` is passed when `--host` is not localhost. Also drives the `_api_auth` middleware when the server is running. |

## Provider Types

| Type         | Description                   |
| ------------ | ----------------------------- |
| `recipe`     | Recipe runner endpoints       |
| `agents-api` | Single/multi-agent HTTP API   |
| `mcp`        | MCP server (stdio, http, sse) |
| `tools-mcp`  | Tools exposed as MCP server   |
| `a2a`        | Agent-to-agent protocol       |
| `a2u`        | Agent-to-user event stream    |

## Troubleshooting

| Issue                                                                       | Fix                                                                                                                     |
| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Port in use                                                                 | `lsof -i :8765`                                                                                                         |
| Missing deps                                                                | `pip install "praisonai[serve]"`                                                                                        |
| No API key                                                                  | `export OPENAI_API_KEY="your-key"`                                                                                      |
| Provider not found                                                          | Check discovery document                                                                                                |
| `--api-key ... is required when binding to a non-localhost host` at startup | Set `PRAISONAI_SERVE_API_KEY=...` (or `--api-key ...`), or bind to `127.0.0.1` / `localhost` for a private-only server. |

## Related

* [Endpoints CLI](/docs/cli/endpoints) - Client for all server types
* [Serve CLI](/docs/cli/serve) - All serve commands
* [A2A Server](./a2a) - Agent-to-agent protocol
* [A2U Server](./a2u) - Agent-to-user events
* [Agents Server](./agents) - HTTP API server
