perplexity-agent-mcp: an open-source MCP server for Perplexity’s Agent API

| In AI
| 7 minute read |by Constantin Gonzalez
Five open books on a wooden table in a sunlit library, each sending a coloured ray of light up into a glass orb, which combines them into a single white beam. AI: Google Gemini 3 Pro Image

I regularly use the Perplexity API, whether from the command line or by letting Claude use it through an MCP, as a second search engine for its research. That’s why I paid attention when, about a week ago, an email from Perplexity landed in my inbox with the subject line “Your Sonar workload runs better on Agent API.” The pitch: their newer Agent API beats the classic Sonar models I’d been using, on both quality and cost.

Their own benchmarks put the cheapest Agent preset at roughly twice the accuracy of Sonar for about the same money, with the deeper presets reaching a level Sonar can’t touch (79.67% vs. 29.10% on BrowseComp for the high preset against Sonar Deep Research, at about 27% higher cost per query).

Marketing numbers, of course, but the direction made sense, and Perplexity is clearly steering everyone from Sonar to the Agent API (though they did also say Sonar isn’t going away).

I wanted to try it out and switch to the better, more efficient engine. It sounded easy, only it wasn’t.

Nowhere to plug it in

Every Perplexity MCP server I could find talks to the old Sonar models. None of them talks to the new Agent API. The official one is Sonar only. The generic “OpenAI-compatible” servers look like they’d work, until you notice they call the chat-completions endpoint, which routes to Sonar and not to the agent. And scraping the Perplexity website is just clumsy.

What I actually wanted was just one small MCP server that does one job: take a question, ask the Agent API, return the answer with its sources. I also wanted this to be secure, because it would hold my API key and talk to the network for me. Ideally, it would have minimal dependencies to avoid supply-chain attacks, and follow well-established security practices.

That server didn’t exist. It felt like it should.

So I delegated it

I’ve written before about how I’ve stopped engineering prompts and started delegating. Instead of fiddling with wording, you write a proper delegation brief that hands over the intent and the principles, then let a capable agent do the work. So I asked Claude to survey the whole Perplexity-MCP landscape, confirm the gap was real, and write me exactly that brief. Then I handed the brief to Claude Code, running the excellent Superpowers plugin, and let it build.

About ten hours later, with a few back-and-forth clarifications and some brainstorming with me in between, it existed: github.com/zalez/perplexity-agent-mcp. One Python file, zero third-party dependencies, open source. It exposes three tools to any MCP client: run a query, fetch the result, cancel a run. It also supports different search depth presets, from “fast” to “xhigh” to “wide-research”, and answers come back with sources. Plus: a second, optional Python file that exposes the same Perplexity Agent client as a model for Simon Willison’s llm command-line tool. The command-line habit I opened this post with now runs on the Agent API too.

It works great, and it’s now my daily driver for letting Claude run research!

The part that impressed me

Here’s the thing that made me go “wow”: I handed over a high-level brief, not a fleshed-out blueprint. The territory turned out to be quite uncertain: Perplexity’s documentation and its live API had quietly drifted apart, so several things the brief stated confidently simply weren’t true anymore. That’s the classic “no plan survives contact with reality” moment, and telling an AI to “write software that does X” carries the same risk.

That’s where the Superpowers plugin comes in: good software development practices wrapped into a carefully curated set of AI Skills. With it, an AI coding agent wasn’t just following instructions, it was following principles, like: check every claim against the real thing, don’t trust the plan where the plan can be tested, review your own work as if someone hostile wrote it. So, most of those ten hours weren’t spent coding. Instead, it checked assumptions against reality, ran experiments to clarify requirements and figure out the unknowns, tried out different variants to find the best approach, and reviewed its own code.

That’s not a story about the initial brief being wrong. Of course parts of it were wrong. Instead, the point of delegating with intent and principles rather than step-by-step instructions is that the agent can keep going when the map and the territory disagree. Watching Claude probe, experiment, and discover its way through uncertain terrain was the most fun part for me. I’m also very happy with how the delegation brief mechanics worked: the delegation brief skill I built as part of my delegation post automatically picked up on “please write a briefing for Claude Code”. Then Claude wrote the full brief. This enabled Claude Code to take it from there, using its Superpowers set of software development skills to navigate the gaps between brief and reality. That’s a great, end-to-end autonomous stack to build software with!

A few things worth knowing

Here are the most interesting details we discovered along the way:

I learned something new about prompt-injection security. Putting uncontrolled external content into an MCP response is a prompt-injection attack surface: anyone can write harmful instructions into a web page, then wait for Perplexity to find them and pipe them straight into the model’s context. I remembered having seen UNTRUSTED annotations in other AI tools to try and mitigate this, so I asked Claude Code to research whether we could use it. Turns out this technique is called Spotlighting and there’s some research from Microsoft which was able to reduce the success rate of such attacks from over 50% to less than 2%. It works by putting the untrusted context into <untrusted-web-content-{16 hex chars}>…</untrusted-web-content-{same}> XML tags to signal to the LLM that, well, this content is indeed not to be trusted. The paper goes further with a stronger variant called datamarking: instead of only bracketing the block, you replace every space in the untrusted text with a special marker character, so the signal repeats on every single word. We chose not to, because it renders the answer nearly unreadable, and a research answer is exactly the kind of output a human ends up reading.

It discovered a constraint my brief never mentioned. Claude Desktop silently kills any tool call longer than sixty seconds, a limit documented nowhere and reverse-engineered by Claude Code itself during its own discovery runs. Perplexity’s deep research can take longer than that. Rather than let the tool die at the cliff while the work kept running and billing in the background, the agent reshaped the design: hand back a ticket instantly, collect the result when it’s ready. I’m a big fan of asynchronous patterns and Claude Code rightly came to this conclusion on its own, changing the originally proposed pattern from the brief. It also created its own table of tool-call timeouts across the major MCP clients and embedded it into the README.md file for others to use as reference.

“Simple” was hard, and that’s where the quality lived. One file, 1,443 lines, 168 tests (as it first shipped), arrived at through roughly thirty separate review passes. The nastiest bug in the whole thing, a way the API key could have leaked to a redirect target, was caught not by the pass that wrote it, but by a later review looking at the finished system as a whole. Superpowers earns its name there. It doesn’t just write, it argues with itself until the result is properly tested, verified, and deemed “ready to ship”.

Some real numbers

After it was built, I put it through its paces, and this is where Perplexity’s marketing meets my measurement. A normal query comes back in about twelve seconds and costs roughly four cents. Deeper research runs in the background and gets collected when ready. Across all my testing, total spend on the live API was about fifteen cents.

For the acceptance test I asked it how the film Obsession had done in German cinemas and what the critics thought. It worked out which Obsession I meant (among other movies by the same name), pulled box office numbers and a spread of reviews, and cited all of it. That’s exactly the sort of multi-hop question the old single-shot Sonar approach handles poorly. (I love that film, watched it a few weeks ago, and can confirm it’s brilliant, though decidedly not for the faint of heart.) On questions like that, the agentic search really is a step up.

Try it out!

It’s on GitHub, a single dependency-free file you can read in one sitting: github.com/zalez/perplexity-agent-mcp (you’ll need a Perplexity API key, which you can set up and pay for in the Perplexity API console). Fair warning, this is a developer MCP: you’ll be editing a config file and pasting in an API key, so it’s for people comfortable with that. Also: Perplexity retains the queries you send through the API. And if you prefer working from the command line, check out the llm wrapper, too.

Play with it, tell me what you think, star the repo, file issues, contribute!