Spaces:
Paused
Paused
| import json | |
| import os | |
| import sys | |
| from mcp.server.fastmcp import FastMCP | |
| from perplexity import Client | |
| from perplexity.config import SEARCH_MODES | |
| from perplexity.logger import get_logger | |
| logger = get_logger("mcp") | |
| mcp = FastMCP( | |
| "perplexity", | |
| host=os.environ.get("MCP_HOST", "127.0.0.1"), | |
| port=int(os.environ.get("MCP_PORT", "8000")), | |
| ) | |
| def perplexity_ask(query: str) -> str: | |
| """Ask Perplexity a question and get a concise AI-generated answer. | |
| Uses Perplexity's auto mode, which selects the best approach for the query. | |
| This is the default general-purpose tool for factual questions, explanations, summaries, and most everyday queries. | |
| Limitations: Does not support follow-up context, file uploads, or source filtering. Returns plain text only. | |
| """ | |
| return client.search(query, mode="auto").get("answer", "") | |
| def perplexity_research(query: str) -> str: | |
| """Conduct deep, multi-step research on a topic using Perplexity. | |
| Uses Perplexity's deep research mode, which autonomously breaks the query into sub-questions, searches broadly, and synthesizes a comprehensive report. | |
| Best for complex topics requiring thorough investigation across many sources. | |
| Limitations: Significantly slower (30-120 seconds). No follow-up, file uploads, or source filtering. Plain text only. | |
| """ | |
| return client.search(query, mode="deep research").get("answer", "") | |
| def perplexity_reason(query: str) -> str: | |
| """Ask Perplexity to reason step-by-step through a complex problem. | |
| Uses Perplexity's reasoning mode with chain-of-thought reasoning before producing an answer. | |
| Best for logic puzzles, math problems, multi-step analysis, coding questions, and decisions requiring structured thinking. | |
| Limitations: Slower than auto mode. No follow-up, file uploads, or source filtering. Plain text only. | |
| """ | |
| return client.search(query, mode="reasoning").get("answer", "") | |
| def perplexity_search(query: str) -> str: | |
| """Search the web using Perplexity and get an AI-synthesized answer. | |
| Uses Perplexity's Pro mode with web sources, providing a more thorough web search than auto mode. | |
| Best for current events, recent developments, and queries where up-to-date web results are important. | |
| Limitations: Only searches the web. No follow-up or file uploads. Plain text only. | |
| """ | |
| return client.search(query, mode="pro", sources=["web"]).get("answer", "") | |
| def main(): | |
| global client | |
| cookies_env = os.environ.get("PERPLEXITY_COOKIES") | |
| if cookies_env: | |
| try: | |
| cookies = json.loads(cookies_env) | |
| except json.JSONDecodeError: | |
| sys.exit("ERROR: PERPLEXITY_COOKIES is not valid JSON.") | |
| else: | |
| cookies = {} | |
| client = Client(cookies) | |
| mcp.tool()(perplexity_ask) | |
| if client.own: | |
| logger.info("Authenticated - all 4 tools available.") | |
| mcp.tool()(perplexity_research) | |
| mcp.tool()(perplexity_reason) | |
| mcp.tool()(perplexity_search) | |
| else: | |
| logger.warning( | |
| "No PERPLEXITY_COOKIES set - running anonymously. " | |
| "Only perplexity_ask is available. " | |
| "Set PERPLEXITY_COOKIES to enable perplexity_search, perplexity_reason, and perplexity_research." | |
| ) | |
| transport = os.environ.get("MCP_TRANSPORT", "stdio") | |
| if transport not in ("stdio", "http"): | |
| sys.exit("ERROR: MCP_TRANSPORT must be 'stdio' or 'http'") | |
| if transport == "stdio": | |
| mcp.run() | |
| else: | |
| mcp.run(transport="streamable-http") | |
| if __name__ == "__main__": | |
| main() | |