Spaces:
Sleeping
Sleeping
| """MCP server exposing the tool layer over the Model Context Protocol. | |
| Run standalone: python -m src.tools.mcp_server | |
| Any MCP-capable client (Claude Desktop, LangChain MCP adapters, etc.) can | |
| then call the ratio engine, filings search, and currency conversion. | |
| The same underlying functions are also exposed in-process as LangChain | |
| tools (src/tools/langchain_tools.py) so the Gradio app works without a | |
| separate server process. | |
| """ | |
| from __future__ import annotations | |
| from mcp.server.fastmcp import FastMCP | |
| from src.tools import external, ratios | |
| mcp = FastMCP("financial-analyst-tools") | |
| def calculate_ratio(name: str, inputs: dict[str, float]) -> dict: | |
| """Compute a financial ratio. `name` is one of: roe, roa, ebitda_margin, | |
| current_ratio, quick_ratio, debt_to_equity, interest_coverage, | |
| free_cash_flow. `inputs` maps the formula's argument names to figures. | |
| """ | |
| return ratios.compute(name, **inputs).as_dict() | |
| def calculator(expression: str) -> float: | |
| """Evaluate a plain arithmetic expression, e.g. '(1200 - 950) / 950'.""" | |
| allowed = set("0123456789.+-*/() eE") | |
| if not set(expression) <= allowed: | |
| raise ValueError("Only arithmetic characters are allowed") | |
| return float(eval(expression, {"__builtins__": {}}, {})) # noqa: S307 — charset-restricted | |
| def sec_edgar_search(company: str, form_type: str = "10-K") -> dict: | |
| """Search recent SEC EDGAR filings for a company.""" | |
| return external.sec_edgar_search(company, form_type) | |
| def companies_house_search(company: str) -> dict: | |
| """Search UK Companies House for a company's registration details.""" | |
| return external.companies_house_search(company) | |
| def convert_currency(amount: float, from_currency: str, to_currency: str) -> dict: | |
| """Convert an amount between currencies at current ECB rates.""" | |
| return external.convert_currency(amount, from_currency, to_currency) | |
| def convert_file_to_markdown(path: str) -> str: | |
| """Convert a financial document (PDF, CSV, XLSX/XLS, JSON, PNG/JPG via OCR, | |
| or plain text) into clean Markdown with intact tables — the normalised form | |
| used for embedding and analysis.""" | |
| from src.ingestion.loader import to_markdown | |
| return to_markdown(path) | |
| if __name__ == "__main__": | |
| mcp.run() | |