Skip to main content
Glama
jujubytes-a11y

Perplexity MCP Server

README.md
# Perplexity MCP Server

Python MCP server that exposes Perplexity Sonar Chat Completions to any MCP client (Cursor, Claude Desktop, custom agents).

## Tools

| Tool | Default model | Purpose |
|------|---------------|---------|
| `perplexity_search` | `sonar-pro` | General web search |
| `perplexity_deep_research` | `sonar-deep-research` | Comprehensive synthesis |

Both tools accept optional Sonar parameters and return JSON:

```json
{
  "answer": "...",
  "citations": ["https://..."],
  "search_results": [],
  "model": "sonar-pro",
  "usage": {}
}
```

### Optional parameters

| Parameter | Values / format | When to use |
|-----------|-----------------|-------------|
| `temperature` | `0`–`2` (default `0.2`) | Lower = more focused; raise only for more varied phrasing |
| `max_tokens` | `1`–`128000` | Cap answer length; omit for API default |
| `search_recency_filter` | `hour` \| `day` \| `week` \| `month` \| `year` | News / “latest” questions; omit for evergreen topics |
| `search_after_date_filter` | `MM/DD/YYYY` | Absolute start of publication window |
| `search_before_date_filter` | `MM/DD/YYYY` | Absolute end of publication window |
| `search_domain_filter` | up to 20 domains; allowlist or `-domain` denylist (not mixed) | Trusted sources only, or exclude noisy sites |
| `search_mode` | `web` \| `academic` \| `sec` | Papers (`academic`), SEC filings (`sec`); omit for general web |
| `model` | `sonar` \| `sonar-pro` \| `sonar-deep-research` \| `sonar-reasoning-pro` | Override tool default only when you need a different speed/depth tradeoff |

Prefer date filters over `search_recency_filter` when the window is known exactly. Queries are capped at **4,000 characters**. The API key is never logged or returned in tool output.

## Setup

1. Copy env template and add your [Perplexity API key](https://www.perplexity.ai/settings/api):

```bash
cp .env.example .env
```

2. Install with [uv](https://docs.astral.sh/uv/):

```bash
uv sync
```

## Run locally (stdio)

```bash
uv run mcp-perplexity
```

### Cursor / Claude Desktop

Add to your MCP config (adjust the project path):

```json
{
  "mcpServers": {
    "perplexity": {
      "command": "uv",
      "args": ["--directory", "C:/Users/KozakJ/git/mcp_perplexity", "run", "mcp-perplexity"],
      "env": {
        "PERPLEXITY_API_KEY": "pplx-your-api-key-here"
      }
    }
  }
}
```

Or rely on a `.env` file in the project directory (`PERPLEXITY_API_KEY=...`).

### Cursor / Claude Desktop (container, stdio)

Rebuild after image changes, then only the API key is required — other settings use the same defaults as local runs:

```json
{
  "mcpServers": {
    "perplexity": {
      "command": "podman",
      "args": [
        "run", "-i", "--rm",
        "-e", "PERPLEXITY_API_KEY",
        "mcp-perplexity"
      ],
      "env": {
        "PERPLEXITY_API_KEY": "pplx-your-api-key-here"
      }
    }
  }
}
```

Override any setting the same way (`-e MCP_PORT`, etc.) only when you need non-defaults.

## Run with Podman (streamable HTTP)

`podman compose` needs a compose provider (`podman-compose` or Docker Compose). On a plain Podman install, use build + run:

```bash
podman build -t mcp-perplexity .
podman run --rm -p 8000:8000 --env-file .env ^
  -e MCP_TRANSPORT=streamable-http ^
  -e MCP_HOST=0.0.0.0 ^
  -e MCP_PORT=8000 ^
  --name mcp-perplexity mcp-perplexity
```

(On bash/zsh, replace `^` with `\`.)

If you have a compose provider installed (`pip install podman-compose`, or Docker Compose):

```bash
podman compose up --build
```

Endpoint: `http://localhost:8000/mcp` (Streamable HTTP). Bind to trusted networks only — this image does not add HTTP auth.

## Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| `PERPLEXITY_API_KEY` | *(required)* | Perplexity API key |
| `MCP_TRANSPORT` | `stdio` | `stdio` or `streamable-http` |
| `MCP_HOST` | `127.0.0.1` | HTTP bind host |
| `MCP_PORT` | `8000` | HTTP bind port |
| `PERPLEXITY_RPM` | `30` | Soft client-side requests/minute limit |
| `PERPLEXITY_MAX_CONCURRENCY` | `2` | Max concurrent API calls |
| `PERPLEXITY_SEARCH_TIMEOUT` | `60` | Search timeout (seconds) |
| `PERPLEXITY_DEEP_RESEARCH_TIMEOUT` | `180` | Deep research timeout (seconds) |
| `PERPLEXITY_MAX_RETRIES` | `3` | Retries on 429/5xx and transport errors |

Retries use exponential backoff (honors `Retry-After` when present). Logging goes to **stderr** only so stdio JSON-RPC stays clean.

TDQS

A3.6/5.0

Scored across 2 tools

Disambiguation3/5

Both tools target web search via Perplexity with nearly identical descriptions, differing only in timeout and 'deep research' label. An agent may struggle to choose between them without clear use-case differentiation.

Naming Consistency5/5

Both tool names follow a consistent pattern: 'perplexity_search' and 'perplexity_deep_research' use the same prefix and verb_noun structure, making them clearly identifiable.

Tool Count3/5

With only 2 tools, the set is minimal but arguably covers the server's purpose (search and deep research). However, the overlap reduces the value of having two separate tools.

Completeness2/5

The set only provides two search variants, lacking any additional functionalities like result filtering, history, or configuration. Important search UX features are missing, making the surface incomplete for a comprehensive search server.

Maintenance

ActivityStale
ResponsivenessNo issues