finpy1789's picture
Per-session workspaces + multi-format ingestion (CSV/XLSX/XLS/JSON/images-OCR) with Markdown normalisation
450d35a verified
Raw
History Blame Contribute Delete
2.34 kB
"""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")
@mcp.tool()
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()
@mcp.tool()
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
@mcp.tool()
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)
@mcp.tool()
def companies_house_search(company: str) -> dict:
"""Search UK Companies House for a company's registration details."""
return external.companies_house_search(company)
@mcp.tool()
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)
@mcp.tool()
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()