Spaces:
Running
Running
| """FastMCP server exposing the deterministic engine over the MCP protocol. | |
| The agent layer (M5+) talks to these tools as a *client* even though it could import the | |
| engine directly — the client/server boundary is the showcase (golden rule #3). The engine is | |
| built once at import (warm); BioLORD is not loaded unless an unknown pathway appears. | |
| Run standalone (streamable-http on 127.0.0.1): | |
| python -m mcp_server.server | |
| """ | |
| from __future__ import annotations | |
| from fastmcp import FastMCP | |
| import config | |
| from mcp_server.engine import Engine | |
| from mcp_server.search import PathwaySearch | |
| _engine = Engine() # warm: loads assets once, reused across calls | |
| _search = PathwaySearch(embed_query=_engine.embed_query) # optional; disabled without PINECONE_API_KEY | |
| def build_server() -> FastMCP: | |
| """Construct the FastMCP server. Used by app.py, the demo, and tests.""" | |
| mcp = FastMCP( | |
| name="semblance-engine", | |
| instructions="Deterministic GSEA signature comparison. Tools never call an LLM.", | |
| ) | |
| def compare_signatures(results: list[dict], params: dict | None = None) -> dict: | |
| """Compare N canonical GSEA results under cutoff `params`. | |
| Returns a ComparisonResult: 2N signatures, cosine similarity matrix, | |
| dendrogram order + linkage + flat clusters, the NES-correlation baseline, | |
| per-pair drill-downs, and warnings. | |
| """ | |
| return _engine.compare(results, params) | |
| def describe_pathways(names: list[str]) -> dict: | |
| """Map pathway names to short descriptions (for the interpreter agent).""" | |
| return _engine.describe(names) | |
| def search_pathways(query: str, k: int = 10) -> dict: | |
| """Semantic free-text search over the MSigDB corpus (optional Pinecone module). | |
| Returns nearest pathways across collections, or `enabled: False` if the search module | |
| is not configured. Never used by the core comparison. | |
| """ | |
| return _search.search(query, k) | |
| def match_pathway(name: str, k: int = 10) -> dict: | |
| """Map a pathway/term name to its nearest known pathways across collections (cross-ontology). | |
| Embeds the name's concept and returns the closest corpus entries (self excluded), or | |
| `enabled: False` if the search module is not configured. | |
| """ | |
| return _search.match(name, k) | |
| def health() -> dict: | |
| """Liveness + asset status (used to poll readiness after subprocess launch).""" | |
| return {**_engine.health(), "search_enabled": _search.enabled} | |
| return mcp | |
| mcp = build_server() | |
| if __name__ == "__main__": | |
| mcp.run(transport="streamable-http", host=config.MCP_HOST, port=config.MCP_PORT) | |