# Semantica MCP Server Architecture and LLM Tools Explained

> Explore Semantica's MCP server architecture, a JSON-RPC 2.0 implementation, and its LLM tools offering unified access to OpenAI, Groq, and HuggingFace providers.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: architecture
- Published: 2026-08-20

---

**Semantica's MCP server is a lightweight JSON-RPC 2.0 implementation over stdio that dispatches requests to a modular tool registry, while its LLM tools provide a unified abstraction layer for OpenAI, Groq, HuggingFace, and other providers.**

The `semantica-agi/semantica` repository implements a **Model-Context Protocol (MCP)** server that bridges AI assistants with knowledge-graph operations. This architecture cleanly separates protocol handling, tool execution, LLM inference, and graph persistence — enabling extensible AI-powered reasoning workflows.

## Core MCP Server Components

### SemanticaMCPServer: The JSON-RPC Event Loop

At the heart of the system is `SemanticaMCPServer` in [`semantica/mcp/server.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/server.py). This class implements the full MCP lifecycle:

- Reads JSON-RPC requests line-by-line from **`stdin`**
- Parses and dispatches to registered handlers via **`_DISPATCH`**
- Writes responses to **`stdout`**

The dispatch table maps standard MCP methods to Python functions:

| Method | Handler Purpose |
|--------|---------------|
| `initialize` | Server handshake and capability negotiation |
| `tools/list` | Returns all available tools from `TOOL_DEFINITIONS` |
| `tools/call` | Executes a specific tool by name |
| `resources/list` | Lists readable resources |
| `resources/read` | Fetches resource content |
| `ping` | Health check |

### Tool Registry and Indexing

Tool definitions live in [`semantica/mcp/tools/__init__.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/tools/__init__.py), which exports **`TOOL_DEFINITIONS`** — an ordered list consolidating all MCP tools. The server builds **`_TOOL_INDEX`** at startup for O(1) name-based lookups.

Tool categories include:

- **Extraction tools** — Parse unstructured text into structured entities
- **Decision tools** — Execute rule-based or LLM-assisted decisions
- **Graph tools** — CRUD operations and analytics on the knowledge graph
- **Reasoning tools** — Forward-chaining and abductive inference
- **Export tools** — Data serialization (CSV, Parquet, JSON, RDF)

### Session Management and Graph Access

The [`semantica/mcp/session.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/session.py) module provides **`get_graph()`**, a singleton accessor that returns the configured graph store instance. Supported backends include **Neo4j**, **FalkorDB**, and **Amazon Neptune**.

Tool handlers call `get_graph()` to read or mutate knowledge-graph state without managing connection lifecycle manually.

## LLM Tool Architecture

Semantica's LLM layer in `semantica/llms/` abstracts multiple providers behind a common interface. The server itself does not host models — instead, MCP tools invoke LLMs on demand.

### Provider Implementations

| Module | Provider | Implementation Notes |
|--------|----------|----------------------|
| [`openai.py`](https://github.com/semantica-agi/semantica/blob/main/openai.py) | OpenAI | Wraps `ChatCompletion` API with `call()` function |
| [`groq.py`](https://github.com/semantica-agi/semantica/blob/main/groq.py) | Groq | Same pattern for Groq-hosted endpoints |
| [`huggingface.py`](https://github.com/semantica-agi/semantica/blob/main/huggingface.py) | HuggingFace | Uses inference API or local transformers pipeline |
| [`litellm.py`](https://github.com/semantica-agi/semantica/blob/main/litellm.py) | Multi-provider | Unified interface via `litellm` library |

All modules expose this common signature:

```python
def call(prompt: str, *, model: str = "gpt-4o", temperature: float = 0.0, **kwargs) -> str:
    """Return the model's completion for `prompt`."""

```

### LLM Registry

[`semantica/llms/__init__.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/llms/__init__.py) exports **`LLM_REGISTRY`**, mapping provider identifiers to implementations:

```python
from semantica.llms import LLM_REGISTRY

llm = LLM_REGISTRY["openai"]  # or "groq", "huggingface", "litellm"

response = llm.call(
    prompt="Extract entities from: 'Alice founded Acme Corp in 2023'",
    model="gpt-4o-mini",
    temperature=0.0
)

```

This registry pattern allows MCP tools to stay provider-agnostic. Changing the LLM backend requires only configuration changes — no tool code modifications.

## How MCP Tools Integrate with LLMs

The **extraction tool** demonstrates the integration: it receives unstructured text, constructs a structured prompt, calls `LLM_REGISTRY[provider]`, and parses the LLM output into graph entities for `add_entity` operations.

In [`semantica/mcp/tools/reasoning.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/tools/reasoning.py), both **`run_reasoning`** (forward-chaining) and **`abductive_reasoning`** wrap the internal `semantica.reasoning` package. These tools may invoke LLMs for hypothesis generation when rule-based inference is insufficient.

## End-to-End Request Flow

1. **Client sends JSON-RPC** over stdio (from VS Code Copilot, Cursor, Claude Code, etc.)

2. **Server parses and dispatches** via `SemanticaMCPServer.dispatch()` using `_DISPATCH`

3. **Tool resolution** for `tools/call` looks up the handler in `_TOOL_INDEX`

4. **Handler execution** runs business logic; LLM calls go through `LLM_REGISTRY`

5. **Graph operations** use `get_graph()` from `semantica/mcp/session`

6. **Response serialization** wraps results in `_ok()` or errors in `_err()`, written to stdout

## Practical JSON-RPC Examples

### Adding an Entity

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "add_entity",
    "arguments": {
      "id": "person:alice",
      "label": "Alice",
      "type": "Person",
      "metadata": { "role": "engineer" }
    }
  }
}

```

### Running Forward-Chaining Reasoning

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "run_reasoning",
    "arguments": {
      "facts": ["Person(Alice)"],
      "rules": ["IF Person(?x) THEN Mortal(?x)"]
    }
  }
}

```

## Key Source Files

| Path | Responsibility |
|------|--------------|
| [`semantica/mcp/server.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/server.py) | JSON-RPC event loop, dispatch table, response formatting |
| [`semantica/mcp/tools/__init__.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/tools/__init__.py) | Tool definition assembly and exposure |
| [`semantica/mcp/tools/graph.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/tools/graph.py) | Entity/relationship CRUD, search, analytics |
| [`semantica/mcp/tools/reasoning.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/tools/reasoning.py) | Forward-chaining and abductive logic |
| [`semantica/mcp/session.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/session.py) | Singleton graph store accessor (`get_graph`) |
| `semantica/llms/*.py` | Provider-specific LLM wrappers |
| [`semantica/llms/__init__.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/llms/__init__.py) | `LLM_REGISTRY` unification |
| `semantica/graph_store/*` | Neo4j, FalkorDB, Neptune implementations |

## Summary

- **SemanticaMCPServer** in [`semantica/mcp/server.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/server.py) handles JSON-RPC 2.0 over stdio with a clean dispatch architecture
- **Tool registration** uses `TOOL_DEFINITIONS` and `_TOOL_INDEX` for extensible tool discovery
- **LLM abstraction** via `LLM_REGISTRY` supports OpenAI, Groq, HuggingFace, and any `litellm` provider with zero tool code changes
- **Graph session management** through `get_graph()` provides consistent, backend-agnostic knowledge-graph access
- **Modular separation** of protocol, tools, LLMs, and persistence enables independent scaling and testing of each layer

## Frequently Asked Questions

### What transport protocol does Semantica's MCP server use?

Semantica's MCP server uses **standard input/output (stdio)** with JSON-RPC 2.0 as the message format. This follows the Model-Context Protocol specification, allowing seamless integration with AI assistants that spawn the server as a subprocess.

### How do I add a new LLM provider to Semantica?

Create a new module in `semantica/llms/` implementing the `call(prompt: str, *, model: str, temperature: float, **kwargs) -> str` signature. Then register it in [`semantica/llms/__init__.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/llms/__init__.py) by adding an entry to `LLM_REGISTRY` with a unique provider key. MCP tools will immediately recognize the new provider without modification.

### Can Semantica work with self-hosted or local LLMs?

Yes. The [`huggingface.py`](https://github.com/semantica-agi/semantica/blob/main/huggingface.py) module supports local inference via the transformers pipeline. For broader compatibility, the [`litellm.py`](https://github.com/semantica-agi/semantica/blob/main/litellm.py) wrapper enables any provider that `litellm` supports, including local servers compatible with the OpenAI API format (such as vLLM or Ollama).

### What graph databases are compatible with Semantica MCP?

Semantica supports **Neo4j**, **FalkorDB**, and **Amazon Neptune** through the `semantica/graph_store/` implementations. The `get_graph()` function in [`semantica/mcp/session.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/mcp/session.py) returns the configured backend instance, allowing tools to operate against any supported store using the same interface.