mcp_server.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """FastMCP transport for Atlas tools."""
  2. from __future__ import annotations
  3. from pathlib import Path
  4. from mcp.server.fastmcp import FastMCP
  5. from mcp.server.transport_security import TransportSecuritySettings
  6. from .atlas import enrich_entity, resolve_entity
  7. from .claims import build_claim_sets
  8. from .triple_export import entity_to_turtle
  9. mcp = FastMCP(
  10. "atlas",
  11. transport_security=TransportSecuritySettings(
  12. enable_dns_rebinding_protection=False
  13. ),
  14. )
  15. @mcp.tool(name="resolve_entity", description="Resolve a subject string to a canonical Atlas entity.")
  16. async def resolve_entity_tool(subject: str, context: str | None = None, debug: bool = False, debug_path: str | None = None):
  17. entity = await resolve_entity(subject, context)
  18. result = {
  19. "atlas_id": entity.atlas_id,
  20. "canonical_label": entity.canonical_label,
  21. "canonical_description": entity.canonical_description,
  22. "entity_type": entity.entity_type,
  23. "needs_curation": entity.needs_curation,
  24. "aliases": [alias.label for alias in entity.aliases],
  25. "g_trends_payload": {k: v for k, v in entity.raw_payload.items() if k != "wikidata"},
  26. "wikidata_payload": (
  27. entity.raw_payload.get("wikidata")
  28. if entity.raw_payload.get("wikidata") is not None
  29. else {"status": "missing"}
  30. ),
  31. }
  32. if debug:
  33. raw_claims, derived_claims = build_claim_sets(entity)
  34. turtle = entity_to_turtle(entity)
  35. result["raw_claims"] = raw_claims
  36. result["derived_claims"] = derived_claims
  37. result["turtle"] = turtle
  38. if debug_path:
  39. path = Path(debug_path)
  40. path.parent.mkdir(parents=True, exist_ok=True)
  41. path.write_text(turtle, encoding="utf-8")
  42. result["turtle_path"] = str(path)
  43. return result
  44. @mcp.tool(name="enrich_entity", description="Enrich a canonical Atlas entity.")
  45. async def enrich_entity_tool(subject: str, depth: int = 1, context: str | None = None):
  46. entity = await resolve_entity(subject, context)
  47. result = enrich_entity(entity, depth=depth)
  48. return {
  49. "seed": {
  50. "atlas_id": result.seed_entity.atlas_id,
  51. "canonical_label": result.seed_entity.canonical_label,
  52. },
  53. "related_entities": [
  54. {
  55. "atlas_id": item.atlas_id,
  56. "canonical_label": item.canonical_label,
  57. "entity_type": item.entity_type,
  58. }
  59. for item in result.related_entities
  60. ],
  61. "query_context": result.query_context,
  62. "depth": result.depth,
  63. }