Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ For cloud or shared deployments, run the server in HTTP mode.
| `PERPLEXITY_API_KEY` | Your Perplexity API key | *Required* |
| `PERPLEXITY_BASE_URL` | Custom base URL for API requests | `https://api.perplexity.ai` |
| `PORT` | HTTP server port | `8080` |
| `BIND_ADDRESS` | Network interface to bind to | `0.0.0.0` |
| `ALLOWED_ORIGINS` | CORS origins (comma-separated) | `*` |
| `BIND_ADDRESS` | Network interface to bind to. Defaults to loopback. Set to `0.0.0.0` to expose on all interfaces. | `127.0.0.1` |
| `ALLOWED_ORIGINS` | CORS origins (comma-separated). Defaults to empty (no cross-origin browser requests). Set to an explicit allowlist (e.g. `https://app.example.com`) or to `*` to allow any origin. | *(empty)* |
| `ALLOWED_HOSTS` | Additional `Host` header values to accept (comma-separated). Loopback hosts on `PORT` are always allowed. Add the public hostname when binding to `0.0.0.0`. | *(loopback only)* |

#### Docker

Expand Down
34 changes: 34 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Security Policy

## Reporting a Vulnerability

Please report security vulnerabilities **privately** via one of:

- GitHub Security Advisory: [Report a vulnerability](https://github.com/perplexityai/modelcontextprotocol/security/advisories/new)
- Email: `security@perplexity.ai`

Please do not open a public issue, draft PR, or discussion for security reports.

## Supported Versions

Only the latest minor of `@perplexity-ai/mcp-server` on npm is supported with security fixes. Operators should pin to the latest patch within that minor.

## Security model of the HTTP transport

The HTTP transport in `src/http.ts` exposes the MCP server over `POST /mcp`. The server authenticates **outbound** calls to `api.perplexity.ai` using the `PERPLEXITY_API_KEY` env var. It does **not** authenticate **inbound** callers. Any process or page that can reach `/mcp` can therefore consume the operator's API quota and read tool responses.

For this reason the defaults are loopback-only and deny-all:

| Setting | Default | Why |
|---|---|---|
| `BIND_ADDRESS` | `127.0.0.1` | Loopback only — not reachable from the LAN or the internet. |
| `ALLOWED_ORIGINS` | *(empty)* | Reject all cross-origin browser requests by default. |
| `ALLOWED_HOSTS` | loopback only | Reject requests whose `Host` header doesn't match a known loopback name. |

If you need to expose the server beyond loopback you should configure an explicit `ALLOWED_ORIGINS` allowlist and an explicit `ALLOWED_HOSTS` allowlist, and ideally front the server with a reverse proxy that enforces authentication.

## Configuration notes

- **`ALLOWED_ORIGINS=*`** — the `cors` middleware will reflect the requesting `Origin` header back into `Access-Control-Allow-Origin` rather than emitting a literal `*`. The server emits a startup warning when this is set.
- **`BIND_ADDRESS=0.0.0.0`** — exposes the server on every network interface. The server emits a startup warning when this is set. The `start:http:UNSAFE-public` / `dev:http:UNSAFE-public` npm scripts are intentionally named to make the configuration visible.
- **Sandboxed / `file://` callers** — these send `Origin: null`. The CORS handler rejects `null` unless `"null"` is explicitly present in `ALLOWED_ORIGINS`.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
"watch": "tsc --watch",
"start": "node dist/index.js",
"start:http": "node dist/http.js",
"start:http:public": "BIND_ADDRESS=0.0.0.0 ALLOWED_ORIGINS=* node dist/http.js",
"start:http:UNSAFE-public": "BIND_ADDRESS=0.0.0.0 ALLOWED_ORIGINS=* node dist/http.js",
"dev": "tsx src/index.ts",
"dev:http": "tsx src/http.ts",
"dev:http:public": "BIND_ADDRESS=0.0.0.0 ALLOWED_ORIGINS=* tsx src/http.ts",
"dev:http:UNSAFE-public": "BIND_ADDRESS=0.0.0.0 ALLOWED_ORIGINS=* tsx src/http.ts",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage"
Expand Down
Loading
Loading