|
|
| """
|
| MCP Web Server using FastMCP
|
| """
|
| import sys
|
| import os
|
|
|
|
|
| current_dir = os.path.dirname(os.path.abspath(__file__))
|
| src_dir = os.path.dirname(os.path.dirname(current_dir))
|
| if src_dir not in sys.path:
|
| sys.path.append(src_dir)
|
|
|
| from mcp.server.fastmcp import FastMCP
|
| from typing import List, Dict, Any, Union
|
| from core.mcp_telemetry import log_usage, log_trace, log_metric
|
| import uuid
|
| import time
|
|
|
|
|
| try:
|
| from .tools.search import search_web
|
| from .tools.extract import extract_content
|
| from .tools.research import research_topic
|
| from .tools.wikipedia import search_wikipedia, get_wikipedia_page
|
| from .tools.arxiv import search_arxiv
|
| except ImportError:
|
|
|
| try:
|
| from tools.search import search_web
|
| from tools.extract import extract_content
|
| from tools.research import research_topic
|
| from tools.wikipedia import search_wikipedia, get_wikipedia_page
|
| from tools.arxiv import search_arxiv
|
| except ImportError:
|
|
|
| sys.path.append(os.path.join(current_dir, "tools"))
|
| from search import search_web
|
| from extract import extract_content
|
| from research import research_topic
|
| from wikipedia import search_wikipedia, get_wikipedia_page
|
| from arxiv import search_arxiv
|
|
|
|
|
| mcp = FastMCP("MCP Web", host="0.0.0.0")
|
|
|
| @mcp.tool()
|
| def search(query: str, max_results: int = 5) -> List[Dict[str, Any]]:
|
| """
|
| Search the web for the given query using DuckDuckGo.
|
| Returns a list of results with title, url, snippet.
|
| """
|
| start_time = time.time()
|
| trace_id = str(uuid.uuid4())
|
| span_id = str(uuid.uuid4())
|
| log_usage("mcp-web", "search")
|
|
|
| try:
|
| results = search_web(query, max_results)
|
| duration = (time.time() - start_time) * 1000
|
| log_trace("mcp-web", trace_id, span_id, "search", duration, "ok")
|
| log_metric("mcp-web", "search_results_count", len(results), {"query": query})
|
| return results
|
| except Exception as e:
|
| duration = (time.time() - start_time) * 1000
|
| log_trace("mcp-web", trace_id, span_id, "search", duration, "error")
|
| raise e
|
|
|
| @mcp.tool()
|
| def extract(url: str) -> str:
|
| """
|
| Extracts text content from a given URL.
|
| Useful for reading articles or documentation.
|
| """
|
| log_usage("mcp-web", "extract")
|
| return extract_content(url)
|
|
|
| @mcp.tool()
|
| def research(query: str, max_results: int = 3) -> List[Dict[str, Any]]:
|
| """
|
| Research a topic by searching and extracting content in parallel.
|
| Returns search results populated with full content.
|
| """
|
| log_usage("mcp-web", "research")
|
| return research_topic(query, max_results)
|
|
|
| @mcp.tool()
|
| def wikipedia_search(query: str, max_results: int = 5) -> List[str]:
|
| """
|
| Search Wikipedia for the given query.
|
| Returns a list of page titles.
|
| """
|
| log_usage("mcp-web", "wikipedia_search")
|
| return search_wikipedia(query, max_results)
|
|
|
| @mcp.tool()
|
| def wikipedia_page(title: str) -> Dict[str, Any]:
|
| """
|
| Get the content of a Wikipedia page.
|
| Returns title, content, summary, url.
|
| """
|
| log_usage("mcp-web", "wikipedia_page")
|
| return get_wikipedia_page(title)
|
|
|
| @mcp.tool()
|
| def arxiv_search(query: str, max_results: int = 5) -> List[Dict[str, Any]]:
|
| """
|
| Search Arxiv for papers.
|
| Returns metadata including title, summary, authors, pdf_url.
|
| """
|
| log_usage("mcp-web", "arxiv_search")
|
| return search_arxiv(query, max_results)
|
|
|
| if __name__ == "__main__":
|
|
|
| import os
|
| if os.environ.get("MCP_TRANSPORT") == "sse":
|
| import uvicorn
|
| port = int(os.environ.get("PORT", 7860))
|
| uvicorn.run(mcp.sse_app(), host="0.0.0.0", port=port)
|
| else:
|
| mcp.run()
|
|
|