> ## 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.

# PraisonAI MCP Server

> Run PraisonAI as an MCP server for Claude Desktop, Cursor, and other MCP clients

# PraisonAI MCP Server

PraisonAI can expose its capabilities via the Model Context Protocol (MCP), allowing integration with Claude Desktop, Cursor, Windsurf, VSCode, and other MCP-compatible clients.

<Note>
  As of C12, the MCP server host ships as the standalone `praisonai-mcp` Tier-2 package. This page documents the heavy MCP host, whether you run it via `praisonai-mcp` (standalone) or `praisonai mcp` (umbrella). Both invocations are equivalent for host commands. See the [praisonai-mcp Package](/docs/features/praisonai-mcp-package) guide and [The Three MCP Layers](/docs/features/mcp-three-layers) for how it fits.

  To serve a single recipe as a scoped MCP server with `praisonai mcp serve-recipe`, see the [Recipe → MCP Bridge](/docs/features/mcp-recipe-server) guide.
</Note>

<Note>
  **Since the release cut from PraisonAI [PR #4311](https://github.com/MervinPraison/PraisonAI/pull/4311):** the `knowledge`, `hooks`, `session`, `tools`, `eval`, `workflow.run` / `run_file` / `auto`, `audio`, `guardrails`, `ocr`, `a2a`, `containers`, `skills`, and `realtime` MCP tools were rebound onto real core APIs and now execute correctly. Prior releases returned `"Error: … not available"` or `"has no attribute …"` for these tools even with the module installed. Tool names and args are unchanged. See PraisonAI [issue #4304](https://github.com/MervinPraison/PraisonAI/issues/4304).
</Note>

## Protocol Version

PraisonAI MCP Server implements **MCP Protocol Version 2025-11-25**.

## Quick Start

### STDIO Transport (Recommended for Claude Desktop)

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp serve --transport stdio
```

### HTTP Stream Transport

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp serve --transport http-stream --port 8080
```

## Features

* **80+ MCP Tools** - Access all PraisonAI capabilities as MCP tools (86 registered by `praisonai-mcp serve`)
* **7 MCP Resources** - Read-only access to configuration and status
* **7 MCP Prompts** - Pre-built prompts for common tasks
* **STDIO Transport** - For Claude Desktop and local integrations
* **HTTP Stream Transport** - For web-based integrations
* **Session Management** - Full session support with resumability
* **Origin Validation** - Security for HTTP transport
* **Progress Notifications** - For long-running operations

## Installation

Three pathways install the heavy MCP host.

| Pathway     | Command                               | When to use               |
| ----------- | ------------------------------------- | ------------------------- |
| Standalone  | `pip install "praisonai-mcp[all]"`    | MCP host only, slim image |
| Umbrella    | `pip install "praisonai[mcp]"`        | Full PraisonAI stack      |
| Dev install | `pip install -e "praisonai-mcp[all]"` | Hacking on the host       |

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Standalone
pip install "praisonai-mcp[all]"

# Or via the umbrella product
pip install "praisonai[mcp]"
```

## CLI Commands

### Start Server

The standalone `praisonai-mcp` console script and the umbrella `praisonai mcp` form are equivalent for all host commands.

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# STDIO transport (for Claude Desktop)
praisonai-mcp serve --transport stdio
praisonai mcp serve --transport stdio       # equivalent

# HTTP Stream transport
praisonai-mcp serve --transport http-stream --port 8080
praisonai mcp serve --transport http-stream --port 8080

# With authentication
praisonai-mcp serve --transport http-stream --api-key YOUR_KEY

# With custom allowed origins
praisonai-mcp serve --transport http-stream --allowed-origins "http://localhost:3000"
```

<Note>
  **Layer positioning:** this is the *heavy host*. For the lighter alternatives (client and light server), see [The Three MCP Layers](/docs/features/mcp-three-layers).
</Note>

### List Components

The three discovery commands share the same registration surface as `serve` and
`doctor` — anything `serve` exposes at runtime shows up here:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# List available tools (86 registered)
praisonai-mcp list-tools          # or: praisonai mcp list-tools

# List available resources (7 registered)
praisonai mcp list-resources

# List available prompts (7 registered)
praisonai mcp list-prompts
```

<Note>
  Requires **PraisonAI v4.6.154** or later for `list-resources` and `list-prompts` to
  return real content on a fresh process. Earlier releases printed
  `"No resources/prompts registered"` even when `doctor` reported 7 of each — see
  upstream [PR #3220](https://github.com/MervinPraison/PraisonAI/pull/3220).
</Note>

### Generate Client Config

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# For Claude Desktop
praisonai mcp config-generate --client claude-desktop

# For Cursor
praisonai mcp config-generate --client cursor

# For VSCode
praisonai mcp config-generate --client vscode

# For Windsurf
praisonai mcp config-generate --client windsurf
```

<Note>
  Since **v4.6.154**, the generator auto-selects the standalone `praisonai-mcp` form when it is on your PATH, and falls back to the umbrella `praisonai mcp` form otherwise.
</Note>

### Health Check

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Pretty (default)
praisonai-mcp doctor              # or: praisonai mcp doctor

# Machine-readable — safe for CI, safe on Windows cp1252 consoles
praisonai-mcp doctor --json       # or: praisonai mcp doctor --json
```

<Note>
  On Windows consoles using a legacy code page (e.g. cp1252), `doctor` falls back to ASCII markers (`[OK]`, `[--]`, `[X]`) instead of the Unicode `✓ ○ ✗` — so it never crashes with `UnicodeEncodeError`. Add `--json` for automation on any platform; it never emits Unicode symbols.
</Note>

See the full [`doctor` reference](/docs/docs/cli/mcp-server#doctor) for the JSON payload shape, exit codes, and error output.

## Server Options

| Option              | Description                              | Default     |
| ------------------- | ---------------------------------------- | ----------- |
| `--transport`       | Transport type: `stdio` or `http-stream` | `stdio`     |
| `--host`            | HTTP host                                | `127.0.0.1` |
| `--port`            | HTTP port                                | `8080`      |
| `--endpoint`        | HTTP endpoint path                       | `/mcp`      |
| `--api-key`         | API key for authentication               | None        |
| `--name`            | Server name                              | `praisonai` |
| `--response-mode`   | Response mode: `batch` or `stream`       | `batch`     |
| `--cors-origins`    | Comma-separated CORS origins             | `*`         |
| `--allowed-origins` | Comma-separated allowed origins          | localhost   |
| `--session-ttl`     | Session TTL in seconds                   | `3600`      |
| `--no-termination`  | Disable client session termination       | False       |
| `--resumability`    | Enable SSE resumability                  | True        |
| `--log-level`       | Log level: debug, info, warning, error   | `warning`   |

<Note>
  `--log-level` only sets the level of the per-server `praisonai.mcp_server.<name>` logger — it no longer touches the process root logger. Other loggers in the host process (including audit and injection-defense telemetry) keep their own levels, so this is not a "quiet everything" switch.
</Note>

## Client Configuration

<Note>
  Since **v4.6.154**, `praisonai mcp config-generate` auto-detects your install type and emits the matching command (`praisonai-mcp` for standalone, `praisonai` for umbrella). The blocks below show both forms so you can copy the one that matches your install.
</Note>

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    G[praisonai-mcp config-generate<br/>--transport stdio] --> D{shutil.which<br/>&quot;praisonai-mcp&quot;?}
    D -->|Yes| S["command: praisonai-mcp<br/>args: [serve, --transport, stdio]"]
    D -->|No| U["command: praisonai<br/>args: [mcp, serve, --transport, stdio]"]

    classDef start fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef check fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef standalone fill:#10B981,stroke:#7C90A0,color:#fff
    classDef umbrella fill:#189AB4,stroke:#7C90A0,color:#fff

    class G start
    class D check
    class S standalone
    class U umbrella
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI as praisonai-mcp
    participant PATH as $PATH
    participant Client as MCP Client

    User->>CLI: config-generate --client cursor --transport stdio
    CLI->>PATH: shutil.which("praisonai-mcp")
    alt Standalone install
        PATH-->>CLI: /usr/bin/praisonai-mcp
        CLI-->>User: {"command": "praisonai-mcp", "args": ["serve", ...]}
    else Umbrella install
        PATH-->>CLI: None
        CLI-->>User: {"command": "praisonai", "args": ["mcp", "serve", ...]}
    end
    User->>Client: paste JSON
    Client->>Client: spawn STDIO server (matches installed CLI)
```

### Claude Desktop

Add to `~/.config/claude/claude_desktop_config.json` (macOS/Linux) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

<Tabs>
  <Tab title="Standalone (praisonai-mcp)">
    ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    {
      "mcpServers": {
        "praisonai": {
          "command": "praisonai-mcp",
          "args": ["serve", "--transport", "stdio"]
        }
      }
    }
    ```
  </Tab>

  <Tab title="Umbrella (praisonai)">
    ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    {
      "mcpServers": {
        "praisonai": {
          "command": "praisonai",
          "args": ["mcp", "serve", "--transport", "stdio"]
        }
      }
    }
    ```
  </Tab>
</Tabs>

### Cursor

Add to Cursor MCP settings:

<Tabs>
  <Tab title="Standalone (praisonai-mcp)">
    ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    {
      "mcpServers": {
        "praisonai": {
          "command": "praisonai-mcp",
          "args": ["serve", "--transport", "stdio"]
        }
      }
    }
    ```
  </Tab>

  <Tab title="Umbrella (praisonai)">
    ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    {
      "mcpServers": {
        "praisonai": {
          "command": "praisonai",
          "args": ["mcp", "serve", "--transport", "stdio"]
        }
      }
    }
    ```
  </Tab>
</Tabs>

### HTTP Stream Client

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "mcpServers": {
    "praisonai": {
      "url": "http://127.0.0.1:8080/mcp",
      "transport": "http-stream"
    }
  }
}
```

## Environment Variables

Set these for full functionality:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export OPENAI_API_KEY=your_key
export ANTHROPIC_API_KEY=your_key  # Optional
export GOOGLE_API_KEY=your_key     # Optional
```

## Available Tools

Run `praisonai mcp list-tools` to see all available tools. Key categories:

<Note>
  As of PraisonAI [PR #4311](https://github.com/MervinPraison/PraisonAI/pull/4311), the tools below **execute against real core** — earlier releases returned `"not available"` or `"has no attribute …"` even with the module installed. Now functional (previously silently broken): `knowledge.add` / `.query` / `.list` / `.clear` / `.stats`, `hooks.list` / `.stats`, `session.list` / `.info` / `.delete`, `tools.list` / `.info` / `.search`, `eval.accuracy` / `.performance`, `workflow.run` / `.run_file` / `.auto`, `audio.transcribe` / `.speech`, `guardrails.check`, `ocr.extract`, `a2a.send`, `containers.file_read` / `.file_write`, `skills.load`, and `realtime.send`. The input signatures are unchanged — adapters translate to the new core kwargs internally.
</Note>

### Agent Tools

* `praisonai.agent.chat` - Chat with an agent
* `praisonai.agent.run` - Run a task with an agent
* `praisonai.workflow.run` - Run a workflow
* `praisonai.research.run` - Run deep research

### Capability Tools

* `praisonai.chat.completion` - Chat completion
* `praisonai.images.generate` - Generate images
* `praisonai.audio.transcribe` - Transcribe audio
* `praisonai.audio.speech` - Text to speech
* `praisonai.embed.create` - Create embeddings
* `praisonai.moderate.check` - Content moderation
* `praisonai.rerank` - Rerank documents
* `praisonai.search` - Web search

### Memory Tools

* `praisonai.memory.show` - Show memory
* `praisonai.memory.add` - Add to memory
* `praisonai.memory.search` - Search memory
* `praisonai.memory.clear` - Clear memory

### Knowledge Tools

* `praisonai.knowledge.add(source)` — add a knowledge source (file path, URL, or raw text). No `source_type` needed; the store auto-detects.
* `praisonai.knowledge.query` - Query knowledge
* `praisonai.knowledge.list` - List sources
* `praisonai.knowledge.clear` - Clear knowledge
* `praisonai.knowledge.stats` - Corpus statistics

### Rules Tools

* `praisonai.rules.list` - List active rules
* `praisonai.rules.show(rule_name)` - Show a specific rule
* `praisonai.rules.create(rule_name, content)` - Create a new rule
* `praisonai.rules.delete(rule_name)` - Delete a rule

<Warning>
  **Security**: As of PraisonAI 4.6.34, rule names are validated to prevent path traversal attacks. Rule names must be single filenames (no `/`, `\`, `..`, leading `.`, or NUL bytes).
</Warning>

#### Rules Tool Examples

**Valid rule names:**

* `"team-style.md"` ✅
* `"coding_standards.txt"` ✅
* `"PROJECT_RULES"` ✅

**Invalid rule names:**

* `"../../etc/passwd"` ❌ (contains traversal)
* `"subdir/rule.md"` ❌ (contains directory separator)
* `".bashrc"` ❌ (starts with dot)

For security details, see [GHSA-9mqq-jqxf-grvw](https://github.com/advisories/GHSA-9mqq-jqxf-grvw).

## Available Resources

| URI                             | Description                                                                             |
| ------------------------------- | --------------------------------------------------------------------------------------- |
| `praisonai://memory/sessions`   | List active sessions from the session store; returns `{ "sessions": [...] }`            |
| `praisonai://workflows`         | List available workflows                                                                |
| `praisonai://tools`             | List available tools                                                                    |
| `praisonai://agents`            | List agent configurations                                                               |
| `praisonai://knowledge/sources` | List knowledge sources; returns the corpus as `{ "sources": [...] }`, not an empty list |
| `praisonai://config`            | Get current configuration                                                               |
| `praisonai://mcp/status`        | Get MCP server status                                                                   |

<Note>
  As of PraisonAI [PR #4311](https://github.com/MervinPraison/PraisonAI/pull/4311), `praisonai://memory/sessions` is backed by the session store (`get_default_session_store().list_sessions()`) and `praisonai://knowledge/sources` by `Knowledge().get_all()`. Both previously returned an empty list plus a hidden error.
</Note>

## Available Prompts

| Name                  | Description                               |
| --------------------- | ----------------------------------------- |
| `deep-research`       | Generate deep research prompts            |
| `code-review`         | Generate code review prompts              |
| `workflow-auto`       | Generate workflow auto-generation prompts |
| `guardrail-check`     | Generate guardrail check prompts          |
| `context-engineering` | Generate context engineering prompts      |
| `eval-criteria`       | Generate evaluation criteria prompts      |
| `agent-instructions`  | Generate agent instructions prompts       |

## Python API

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.mcp_server.server import MCPServer
from praisonai.mcp_server.adapters import register_all

# Register all tools, resources, and prompts
register_all()

# Create server
server = MCPServer(
    name="praisonai",
    version="1.0.0",
    instructions="PraisonAI MCP Server",
)

# Run with STDIO transport
server.run(transport="stdio")

# Or HTTP Stream transport
server.run(
    transport="http-stream",
    host="127.0.0.1",
    port=8080,
)
```

## Custom Tools

Register custom tools:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.mcp_server.registry import register_tool

@register_tool("custom.greet")
def greet(name: str) -> str:
    """Greet a person by name."""
    return f"Hello, {name}!"
```

## Security

<Warning>
  **Path Traversal Protection**: PraisonAI 4.6.34 includes hardening against path traversal attacks in MCP rules tools. See [GHSA-9mqq-jqxf-grvw](https://github.com/advisories/GHSA-9mqq-jqxf-grvw) for details.
</Warning>

### Origin Validation

For HTTP Stream transport, origin validation is enabled by default:

* Localhost binding: Only localhost origins allowed
* External binding: Requires explicit `--allowed-origins` configuration

### Authentication

Use `--api-key` for Bearer token authentication:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp serve --transport http-stream --api-key YOUR_SECRET_KEY
```

Clients must include:

```
Authorization: Bearer YOUR_SECRET_KEY
```

## STDIO Transport Reliability

The STDIO transport (`praisonai-mcp serve --transport stdio`) is hardened to work everywhere your MCP client runs and to survive bad input and shutdown.

* **Runs on Windows too** — including Windows + Python 3.13, which used to crash. The host reads stdin on a dedicated background thread (named `mcp-stdio-reader`) instead of the async pipe API, so it no longer fails with `OSError: [WinError 6] The handle is invalid` when Cursor, Claude Desktop, or Windsurf spawn it with redirected pipes.
* **Bad input never kills the server** — malformed (non-UTF-8) bytes become a JSON-RPC parse error (`-32700`) and the server keeps running.
* **Bounded input queue** — incoming lines are capped at `1000` with backpressure, so a fast or hostile client can't grow memory without limit.
* **Clean shutdown** — stopping the server (Ctrl+C or client disconnect) wakes a reader that is blocked on idle-but-open stdin, so it never hangs.

<Note>
  You don't configure any of this — it's the default behaviour of the STDIO transport. See [MCP STDIO Server Transport](/docs/features/mcp-stdio-server-transport) for the full picture.
</Note>

## Troubleshooting

### Error semantics

A tool response with `isError: true` means the call **failed** — either the adapter raised, or it returned an `"Error: …"` string that the host now surfaces as an error. MCP clients, routers, and retry logic can rely on this field. Adapters that succeed always return `isError: false`.

<Note>
  Since PraisonAI [PR #4311](https://github.com/MervinPraison/PraisonAI/pull/4311), `_handle_tools_call` sets `isError: true` when an adapter returns a string starting with `"Error: "`. Earlier releases returned many of those with `isError: false`, which routers and retry logic treat as success.
</Note>

### Check Server Health

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp doctor
```

### Enable Debug Logging

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp serve --log-level debug
```

Clients can also raise the log level at runtime via the JSON-RPC `logging/setLevel` method. This scopes to the same per-server `praisonai.mcp_server.<name>` logger, and requires the `admin` scope when [scoped API keys](/docs/features/mcp-scoped-api-keys) are configured.

### Common Issues

1. **"Missing dependency"** - Install with `pip install praisonai[mcp]`
2. **"No API keys configured"** - Set `OPENAI_API_KEY` environment variable
3. **"Origin validation failed"** - Add origin to `--allowed-origins`

| Issue                                                        | Fix                                                                                                             |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
| `OSError: [WinError 6] The handle is invalid` on Windows     | Upgrade to a `praisonai-mcp` release with the threaded stdin reader — STDIO now works on Windows + Python 3.13. |
| MCP host exits after a client sends binary / non-UTF-8 bytes | Fixed — the server returns a `-32700` parse error and keeps running.                                            |
| `praisonai-mcp serve --transport stdio` hangs on shutdown    | Fixed — `stop()` unblocks the idle reader for a clean exit.                                                     |
