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

# Recipe → MCP Bridge

> Turn any PraisonAI recipe into a scoped MCP server for Claude Desktop, Cursor, and Windsurf

Serve any recipe as its own MCP server, so an MCP client sees exactly one recipe's tools, prompts, and resources — safe-mode on by default.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Recipe[📋 Recipe file<br/>support-reply] --> Serve[⚙️ serve-recipe]
    Serve --> Server[🔌 Scoped MCP server]
    Server --> Client[✅ MCP client<br/>Claude Desktop / Cursor]

    classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef server fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff

    class Recipe input
    class Serve process
    class Server server
    class Client ok
```

## Quick Start

<Steps>
  <Step title="Build an agent recipe">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent

    agent = Agent(
        name="support-reply",
        instructions="Draft a friendly reply to a customer support ticket.",
    )
    agent.start("Customer says their order is late.")
    ```

    Save the recipe as `support-reply` so the bridge can find it by name.
  </Step>

  <Step title="Serve the recipe as an MCP server">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai mcp serve-recipe support-reply --transport stdio
    ```

    Only this recipe's tools and prompts are exposed — nothing else.
  </Step>

  <Step title="Point your MCP client at it">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai mcp config-generate-recipe support-reply --client claude-desktop
    ```

    Paste the printed block into your Claude Desktop config and the recipe appears as a tool.
  </Step>
</Steps>

***

## How It Works

A recipe maps to MCP primitives: agent tools become MCP tools, agent instructions become MCP prompts, and the recipe config becomes MCP resources — all behind a deny-list gate.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Client as MCP Client
    participant Host as Recipe Host
    participant Gate as Deny-List Gate
    participant Agent

    User->>Client: Call recipe tool
    Client->>Host: tools/call
    Host->>Gate: Check tool name
    Gate-->>Host: Allowed
    Host->>Agent: Run recipe
    Agent-->>Host: Result
    Host-->>Client: Response
    Client-->>User: Answer
```

| Recipe part | Becomes | Example |
| - | - | - |
| Recipe run | MCP tool | `support-reply.run` |
| Agent tool | MCP tool (namespaced) | `support-reply.agent.tool` |
| Recipe config | MCP resource | `recipe://support-reply/config` |
| Config schema | MCP resource | `recipe://support-reply/schema` |
| Recipe description | MCP prompt | `support-reply-description` |
| Agent instructions | MCP prompt | `support-reply-agent-instructions` |

***

## CLI Commands

Five commands work with recipes over MCP — one to discover, four to serve. Each works as `praisonai mcp <command>` inside the full stack, or `praisonai-mcp <command>` standalone.

### list-recipes

List every recipe the discovery layer can see — custom (`~/.praison`, `~/.config`), project (`./.praison`), and bundled (`agent_recipes`). You need a recipe name before you can `serve-recipe`.

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp list-recipes
praisonai-mcp list-recipes
praisonai mcp list-recipes --source package
praisonai mcp list-recipes --tags video,social
praisonai mcp list-recipes --json
```

| Flag | Default | Description |
| - | - | - |
| `--source` | `None` (all sources) | Filter by source. Only `custom`, `project`, `package` are accepted — the exact labels `TemplateDiscovery` assigns. |
| `--tags` | `None` | Comma-separated tag filter (`--tags video,social`). |
| `--json` | off | JSON output — safe for pipes and CI. |

<Note>
  `--source` used to advertise `local` and `all` — neither ever worked, and the command itself raised `TypeError` on every invocation before PraisonAI PR [#4962](https://github.com/MervinPraison/PraisonAI/pull/4962). `custom`, `project`, and `package` are the only accepted values.
</Note>

**Source labels — what each one lists:**

| Source | Where discovery reads from | Typical use |
| - | - | - |
| `custom` | `~/.praison`, `~/.config/praison` | User-installed recipes on this machine |
| `project` | `./.praison` (current working directory) | Recipes checked into a repo |
| `package` | Bundled `agent_recipes` inside the wheel | The recipes that ship with PraisonAI |

**Expected output** (default, non-JSON):

```
Available Recipes (2):

  • data-analyst (v1.0.0)
    Data analysis template using pandas tools

  • support-reply (v1.0.0)
    Draft a friendly reply to a customer support ticket
```

**JSON output** (`--json`):

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "recipes": [
    {
      "name": "data-analyst",
      "version": "1.0.0",
      "description": "Data analysis template using pandas tools",
      "source": "package",
      "tags": ["data", "pandas"]
    }
  ]
}
```

### Which recipe do I serve?

Pair `list-recipes` with `serve-recipe` — discover first, then serve.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Q{Know the recipe name?} -->|No| L[praisonai mcp list-recipes]
    L --> Pick[Pick a recipe]
    Q -->|Yes| Pick
    Pick --> S[praisonai mcp serve-recipe]
    S --> Client[✅ Claude Desktop / Cursor]

    classDef q fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef list fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef pick fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef serve fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef ok fill:#10B981,stroke:#7C90A0,color:#fff

    class Q q
    class L list
    class Pick pick
    class S serve
    class Client ok
```

### serve-recipe

Turn a recipe into a scoped MCP server.

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

| Flag | Default | Description |
| - | - | - |
| `--transport` | `stdio` | `stdio` or `http-stream` |
| `--host` | `127.0.0.1` | HTTP host (http-stream only) |
| `--port` | `8080` | HTTP port (http-stream only) |
| `--endpoint` | `/mcp` | HTTP endpoint path |
| `--api-key` | `None` | Bearer token for HTTP auth |
| `--safe-mode` / `--no-safe-mode` | enabled | Apply the deny-list gate |
| `--expose-tools` / `--no-expose-tools` | enabled | Expose agent tools |
| `--expose-prompts` / `--no-expose-prompts` | enabled | Expose prompts |
| `--session-ttl` | `3600` | Session TTL in seconds |
| `--log-level` | `warning` | `debug`, `info`, `warning`, or `error` |
| `--json` | off | JSON output |

### validate-recipe

Check a recipe is safe to host before serving it.

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp validate-recipe support-reply
```

| Flag | Default | Description |
| - | - | - |
| `--json` | off | JSON output |

Warnings flag recipes with no tools or with shell/exec tools.

### inspect-recipe

Show the tools, resources, and prompts a recipe would expose.

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp inspect-recipe support-reply --tools
```

| Flag | Default | Description |
| - | - | - |
| `--tools` | off | Show tools |
| `--resources` | off | Show resources |
| `--prompts` | off | Show prompts |
| `--metadata` | off | Show recipe metadata |
| `--json` | off | JSON output |

With no flags, it shows everything.

### config-generate-recipe

Emit a client config block that points at this recipe.

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai mcp config-generate-recipe support-reply --client claude-desktop
```

| Flag | Default | Description |
| - | - | - |
| `--client` | `claude-desktop` | `claude-desktop`, `cursor`, `vscode`, `windsurf`, or `generic` |
| `--transport` | `stdio` | `stdio` or `http-stream` |
| `--host` | `127.0.0.1` | HTTP host (http-stream only) |
| `--port` | `8080` | HTTP port (http-stream only) |
| `--output` | `None` | Write config to a file instead of stdout |

<Note>
  Since **v4.6.154**, recipe configs auto-pick the right entry point — `praisonai-mcp serve-recipe` when the standalone binary is on your PATH, and `praisonai mcp serve-recipe` otherwise.
</Note>

***

## Which Serve Command

Three commands serve MCP — pick the one that matches your scope.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{What do you want<br/>to expose?} -->|One recipe| R[praisonai mcp serve-recipe]
    Q -->|Full capability registry| F[praisonai-mcp serve]
    Q -->|Config-driven tools| C[praisonai serve mcp]

    classDef q fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef recipe fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef full fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef cfg fill:#6366F1,stroke:#7C90A0,color:#fff

    class Q q
    class R recipe
    class F full
    class C cfg
```

| Command | Serves | Use it for |
| - | - | - |
| `praisonai mcp serve-recipe` | One recipe, scoped | Ship a single recipe to a client |
| `praisonai-mcp serve` | Full capability registry | Expose the whole heavy host |
| `praisonai serve mcp` | Config-driven tools | Light server from shared config |

***

## Allow / Deny Lists and Safe Mode

Safe mode is on by default and filters every tool through a deny-list before it reaches a client.

<Warning>
  Safe mode blocks destructive tools by default. Only disable it with `--no-safe-mode` when you fully trust the recipe.
</Warning>

**Default denied tools** (from `DEFAULT_DENIED_TOOLS` in the adapter):

| Denied tool | Denied tool | Denied tool |
| - | - | - |
| `shell.exec` | `shell.run` | `shell_tool` |
| `file.write` | `file.delete` | `fs.write` |
| `fs.delete` | `network.unrestricted` | `db.write` |
| `db.delete` | `execute_command` | `os.system` |
| `subprocess.run` | `eval` | `exec` |

A tool is blocked when a denied name matches part of the tool name in either direction. Set an allow-list and only those tools pass; leave it empty and the deny-list applies.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai_mcp.mcp_server import RecipeMCPConfig

# Allow-list: only these tools pass
config = RecipeMCPConfig(
    recipe_name="support-reply",
    tool_allowlist=["search", "summarize"],
)

# Deny-list: extend the defaults
config = RecipeMCPConfig(
    recipe_name="support-reply",
    tool_denylist=["shell.exec", "file.delete", "my.custom.tool"],
)
```

<Note>
  Setting `tool_denylist` replaces the defaults — copy in the entries you still want to block.
</Note>

***

## Python API

Load a recipe and run it as an MCP server in three lines.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai_mcp.mcp_server import RecipeMCPAdapter

adapter = RecipeMCPAdapter("support-reply")
adapter.load()
adapter.to_mcp_server().run(transport="stdio")
```

### RecipeMCPAdapter

| Method | Signature | Returns |
| - | - | - |
| `__init__` | `RecipeMCPAdapter(recipe_name, config=None)` | adapter |
| `load` | `load()` | `None` — loads recipe, builds registries |
| `to_mcp_server` | `to_mcp_server()` | `MCPServer` ready to run |
| `get_recipe_info` | `get_recipe_info()` | metadata dict |
| `get_tool_registry` | `get_tool_registry()` | tool registry |
| `get_resource_registry` | `get_resource_registry()` | resource registry |
| `get_prompt_registry` | `get_prompt_registry()` | prompt registry |

| `__init__` param | Type | Default | Description |
| - | - | - | - |
| `recipe_name` | `str` | required | Recipe to adapt |
| `config` | `RecipeMCPConfig` | `None` | Config (defaults applied if omitted) |

### RecipeMCPConfig

| Option | Type | Default | Description |
| - | - | - | - |
| `recipe_name` | `str` | required | Recipe name |
| `expose_agent_tools` | `bool` | `True` | Expose agent tools |
| `expose_run_tool` | `bool` | `True` | Expose the `recipe.run` meta-tool |
| `tool_namespace` | `str` | `"prefixed"` | `flat`, `nested`, or `prefixed` |
| `expose_config` | `bool` | `True` | Expose recipe config as a resource |
| `expose_outputs` | `bool` | `True` | Expose output definitions |
| `expose_prompts` | `bool` | `True` | Expose prompts |
| `expose_agent_instructions` | `bool` | `True` | Expose agent instructions as prompts |
| `safe_mode` | `bool` | `True` | Apply the deny-list gate |
| `tool_allowlist` | `List[str]` | `None` | Only these tools pass |
| `tool_denylist` | `List[str]` | `None` | Blocked tools (defaults if `None`) |
| `workspace_path` | `str` | `None` | Workspace root for the recipe |
| `allow_network` | `bool` | `False` | Allow network access |
| `env_allowlist` | `List[str]` | `None` | Environment variables to pass through |
| `server_name` | `str` | `None` | Server name (defaults to recipe name) |
| `server_version` | `str` | `"1.0.0"` | Server version |
| `server_description` | `str` | `None` | Server description |
| `server_icon` | `str` | `None` | Server icon |
| `session_ttl` | `int` | `3600` | Session TTL in seconds |
| `max_concurrent_runs` | `int` | `5` | Concurrent recipe runs |

***

## End-to-End Example

Go from an agent recipe to a working Claude Desktop tool in three steps.

<Steps>
  <Step title="Write the recipe">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent

    agent = Agent(
        name="support-reply",
        instructions="Draft a friendly reply to a customer support ticket.",
    )
    ```
  </Step>

  <Step title="Serve it">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai mcp serve-recipe support-reply --transport stdio
    ```
  </Step>

  <Step title="Generate the client config">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai mcp config-generate-recipe support-reply --client claude-desktop
    ```

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

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

Paste that block into Claude Desktop's config and the `support-reply` recipe appears as a tool.

***

## Best Practices

<AccordionGroup>
  <Accordion title="Validate before you serve">
    Run `praisonai mcp validate-recipe <name>` to catch missing tools or shell/exec warnings before a client connects.
  </Accordion>

  <Accordion title="Inspect what you expose">
    `praisonai mcp inspect-recipe <name>` shows the exact tools, resources, and prompts a client will see.
  </Accordion>

  <Accordion title="Keep safe mode on">
    Safe mode blocks destructive tools like `shell.exec` and `file.delete`. Only use `--no-safe-mode` for recipes you fully trust.
  </Accordion>

  <Accordion title="Prefer an allow-list for production">
    An allow-list exposes only the tools you name, which is tighter than extending the deny-list.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="PraisonAI MCP Server" icon="server" href="/docs/mcp/praisonai-mcp-server">
    Heavy MCP host reference and client setup.
  </Card>

  <Card title="praisonai-mcp Package" icon="plug" href="/docs/features/praisonai-mcp-package">
    Package install and CLI guide.
  </Card>

  <Card title="The Three MCP Layers" icon="layer-group" href="/docs/features/mcp-three-layers">
    Client vs light server vs heavy host.
  </Card>

  <Card title="Package Tiers" icon="layer-group" href="/docs/features/architecture-tiers">
    Where praisonai-mcp sits in the stack.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.