Files
KaifAhmad1andClaude Sonnet 4.6 7b31304e1e feat(mcp): add modular MCP server package at repo root
Adds a fully self-contained `mcp/` package that exposes Semantica as a
Model Context Protocol server over stdio (JSON-RPC 2.0).

17 tools across 5 domains:
- Extraction: extract_entities, extract_relations, extract_all
- Decision intelligence: record_decision, query_decisions, find_precedents,
  get_causal_chain, analyze_decision_impact
- Knowledge graph: add_entity, add_relationship, search_graph,
  get_graph_summary, get_graph_analytics
- Reasoning: run_reasoning, abductive_reasoning
- Export & provenance: export_graph (JSON/CSV/GraphML/Parquet/RDF), get_provenance

4 resources: semantica://graph/summary, semantica://decisions/list,
semantica://schema/info, semantica://ontology/schema

Package layout:
  mcp/__init__.py + __main__.py  — entry points (python -m mcp)
  mcp/server.py                  — SemanticaMCPServer + stdio event loop
  mcp/session.py                 — lazy ContextGraph singleton
  mcp/schemas.py                 — JSON Schema for all 17 tool inputs
  mcp/tools/{extraction,decisions,graph,reasoning,export}.py
  mcp/resources/registry.py      — URI → handler map
  mcp/README.md                  — per-tool setup (Claude Code, Cursor, Windsurf,
                                   Cline, Continue, VS Code, Amazon Q)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:38:23 +05:30

48 lines
1.3 KiB
Python

"""
Shared graph session — lazy singleton across all tool handlers.
The graph is initialised once on first access and shared for the
lifetime of the MCP server process. Set SEMANTICA_KG_PATH to
automatically load a persisted graph on start.
"""
from __future__ import annotations
import logging
import os
from typing import Any, Optional
log = logging.getLogger("semantica.mcp.session")
_graph: Optional[Any] = None
def get_graph() -> Any:
"""
Return the shared ContextGraph instance, creating it on first call.
The graph is created with advanced_analytics=True so all centrality,
community-detection, and embedding features are available.
"""
global _graph
if _graph is None:
from semantica.context import ContextGraph
_graph = ContextGraph(advanced_analytics=True)
kg_path = os.environ.get("SEMANTICA_KG_PATH", "").strip()
if kg_path and os.path.exists(kg_path):
try:
_graph.load(kg_path)
log.info("Graph loaded from %s", kg_path)
except Exception as exc:
log.warning("Could not load graph from %s: %s", kg_path, exc)
return _graph
def reset_graph() -> None:
"""Reset the singleton (mainly useful in tests)."""
global _graph
_graph = None