Use The Perplexity Ask via OpenRouter
This server exposes three tools that wrap Perplexity API calls via OpenRouter. While tool definitions are explicitly registered with JSON schemas and descriptions, the implementation has several significant gaps. All three tools are nearly identical in structure (accepting a messages array and returning text), which raises composition concerns. Descriptions are present but lack actionable guidance for LLM selection and error recovery. Parameter descriptions are minimal, the 'role' and 'content' fields lack context about valid values (e.g., what roles are accepted?). Output schemas are completely undocumented (the code concatenates citations as plain text, but this behavior is never formally specified). Error handling returns raw exceptions rather than actionable guidance. The naming (perplexity_ask, perplexity_research, perplexity_reason) lacks a consistent verb structure and makes it unclear when to choose one over another. Security is handled well (API key injection via Config, no secrets in parameters), but parameter validation, idempotency guidance, and composition patterns are absent.
Engages in a conversation using the Sonar API. Accepts an array of messages (each with a role and content) and returns a ask completion response from the Perplexity model.
Performs reasoning tasks using the Perplexity API. Accepts an array of messages (each with a role and content) and returns a well-reasoned response using the sonar-reasoning-pro model.
Performs deep research using the Perplexity API. Accepts an array of messages (each with a role and content) and returns a comprehensive research response with citations.
Tool names lack clear action verbs. 'perplexity_ask', 'perplexity_research', 'perplexity_reason' do not start with standard action verbs (get, create, search, update). Names like 'ask_perplexity_sonar', 'research_with_perplexity', 'reason_with_perplexity' would be clearer. LLMs cannot easily infer intent from provider-first names.
Parameter descriptions are incomplete. 'role' parameter describes what it is ('Role of the message (e.g., system, user, assistant)') but does not enumerate valid values or explain constraints. What if an LLM passes 'user_assistant' or 'system_override'? No validation or guidance. Same for 'content', is there a length limit? Required format?
Output schema completely undocumented. The code shows citations are appended as markdown text if present (src/OpenRouterAskTool.ts line 56: `content += "\n\nCitations:\n"`), but the tool definition provides zero documentation about return type, structure, or citation format. LLMs cannot plan downstream processing.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-21 | D | 50 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 59 | - | v1 |
No guidance on tool selection. All three tools accept identical input (messages array) and return identical output (text response). Descriptions state what model is used internally (sonar, sonar-reasoning-pro) but do not explain WHEN to call one vs. another. An LLM may randomly choose, leading to suboptimal results.
Error handling returns raw exceptions. src/OpenRouterAskTool.ts throws errors like 'Network error while calling OpenRouter API: ${error}' and 'OpenRouter API error: ${response.status} - ${errorMessage}'. These are not actionable for LLMs. No recovery guidance (e.g., 'retry with fewer messages', 'check API quota', 'use perplexity_ask instead'). Per pattern:recovery-guide, errors must tell the agent what to do next.
No pagination or result limiting. Tools return raw API responses without capping or paginating results. If a research query returns 10,000 words of citations and content, LLMs will receive the full text, risking context window exhaustion. No documented limit or pagination parameters.
No idempotency guidance. Messages array is mutable, calling the same tool twice with identical messages but in a different order, or with trailing whitespace variations, may produce different results. No indication of idempotency semantics or retry safety.
Composition concern: three nearly identical tools with overlapping responsibility. perplexity_research and perplexity_ask both accept messages and return text, yet descriptions suggest they operate on different models internally. Unclear how an LLM should compose these or whether one subsumes another. Consider a single 'ask_perplexity' tool with a 'model' parameter (enum: sonar, sonar-research, sonar-reasoning-pro) for clarity.