Perplexity MCP Server
# 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
Scored across 2 tools
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.
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.
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.
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.