How to Use the MCP Server for Tool Exposure in semantica.mcp_server

The Semantica MCP server exposes knowledge-graph tools through a JSON-RPC 2.0 interface over stdin/stdout, allowing clients to discover capabilities via tools/list and invoke them via tools/call after initialization.

The semantica.mcp_server module implements the Model-Context Protocol (MCP) to programmatically expose Semantica's graph manipulation, reasoning, and export capabilities. This server enables any MCP-compatible client to interact with the underlying knowledge graph through a standardized JSON-RPC interface. Understanding how to use the MCP server for tool exposure in semantica.mcp_server allows developers to integrate semantic AI workflows into external applications without managing the graph state directly.

Architecture and Protocol Flow

The server operates as a stdio-based JSON-RPC 2.0 process defined in mcp/server.py. It reads newline-delimited requests from standard input and writes responses to standard output, making it compatible with subprocess-based clients and transport bridges.

The interaction follows a strict three-phase sequence:

  1. Initialize: The client sends an initialize request to negotiate protocol capabilities and receive server metadata.
  2. Discover: The client queries tools/list to retrieve available tool definitions including input schemas.
  3. Invoke: The client sends tools/call with a valid tool name and arguments conforming to the schema defined in mcp/schemas.py.

Starting the MCP Server

Launch the server using either module entry point. The primary entry point executes python -m semantica.mcp.server, though python -m semantica.mcp is also supported for convenience.

python -m semantica.mcp.server

Once started, the process blocks and waits for JSON-RPC messages on stdin. The server maintains a singleton graph session through get_graph in mcp/session.py, ensuring all tool operations share the same underlying knowledge graph instance.

Tool Discovery and Schema Inspection

Before invocation, clients must discover available capabilities. The tools/list method returns an array of tool definitions populated from the registry in mcp/tools/__init__.py. Each definition contains:

  • name: The invocation identifier (e.g., add_entity, search_graph)
  • description: Human-readable purpose text
  • inputSchema: JSON Schema object defining required parameters

The registry assembles these definitions from individual tool modules including mcp/tools/graph.py, mcp/tools/reasoning.py, and mcp/tools/export.py. The internal _TOOL_INDEX dictionary maps these names to their corresponding handler functions.

Invoking Tools via tools/call

To execute a tool, send a tools/call request with the target name and a JSON arguments object. The server validates the payload against the schema, routes the request via _handle_tools_call in mcp/server.py, and dispatches to the appropriate handler (e.g., handle_add_entity in mcp/tools/graph.py).

Arguments must strictly conform to the inputSchema. For graph operations, handlers use the shared session accessor to read from or write to the knowledge graph singleton.

Practical Implementation Examples

Python Subprocess Client

The following implementation spawns the server as a subprocess and manages the JSON-RPC protocol programmatically:

import json
import subprocess
import sys

# Start the MCP server as a subprocess (stdio-based JSON-RPC)

proc = subprocess.Popen(
    [sys.executable, "-m", "semantica.mcp.server"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True,
)

def rpc(method, params=None, req_id=1):
    request = json.dumps({
        "jsonrpc": "2.0",
        "id": req_id,
        "method": method,
        "params": params or {}
    })
    proc.stdin.write(request + "\n")
    proc.stdin.flush()
    return json.loads(proc.stdout.readline())

# 1. Initialize

print(rpc("initialize"))

# 2. List available tools

tools = rpc("tools/list")["result"]["tools"]
print("Available tools:", [t["name"] for t in tools])

# 3. Call add_entity

entity = {
    "id": "person:alice",
    "label": "Alice",
    "type": "Person",
    "metadata": {"role": "engineer"},
}
resp = rpc("tools/call", {"name": "add_entity", "arguments": entity})
print("add_entity response:", json.loads(resp["result"]["content"][0]["text"]))

HTTP Bridge with curl

While the native transport uses stdio, you can bridge to HTTP using netcat or similar tools. Once bridged (e.g., nc -l -p 9999 | python -m semantica.mcp.server), interact via HTTP:


# Initialize session

curl -s http://localhost:9999 -d '{
  "jsonrpc":"2.0",
  "id":1,
  "method":"initialize",
  "params":{}
}'

# Discover tools

curl -s http://localhost:9999 -d '{
  "jsonrpc":"2.0",
  "id":2,
  "method":"tools/list",
  "params":{}
}'

# Invoke add_entity

curl -s http://localhost:9999 -d '{
  "jsonrpc":"2.0",
  "id":3,
  "method":"tools/call",
  "params":{
    "name":"add_entity",
    "arguments":{
      "id":"person:bob",
      "label":"Bob",
      "type":"Person",
      "metadata":{"department":"sales"}
    }
  }
}'

Both examples demonstrate the required protocol sequence: initialize → discover → call. Replace the tool name and arguments to access other capabilities like search_graph, run_reasoning, or export functions defined in mcp/tools/export.py.

Summary

  • Transport Protocol: The server implements JSON-RPC 2.0 over stdin/stdout, requiring newline-delimited message framing.
  • Entry Point: Launch via python -m semantica.mcp.server, which executes the main loop in mcp/server.py.
  • Discovery: Query tools/list to retrieve definitions from the registry in mcp/tools/__init__.py and schemas from mcp/schemas.py.
  • Invocation: Send tools/call with JSON arguments matching the tool's inputSchema; handlers in mcp/tools/graph.py and related modules process requests using the singleton session from mcp/session.py.
  • State Management: All tools share a single knowledge graph instance per server process, ensuring consistent state across invocations.

Frequently Asked Questions

What transport protocol does semantica.mcp_server use?

The server uses JSON-RPC 2.0 over standard input and output (stdio). It reads newline-delimited JSON requests from stdin and writes responses to stdout, enabling simple subprocess-based integration without network configuration.

How does the server maintain graph state between tool calls?

The server maintains a singleton knowledge graph instance using get_graph from mcp/session.py. All tool handlers access this shared session, ensuring that entities added via add_entity remain available for subsequent search_graph or run_reasoning operations within the same server process.

Where are tool schemas and handlers defined?

Tool schemas reside in mcp/schemas.py, while the handler registry is constructed in mcp/tools/__init__.py. Individual implementations, such as handle_add_entity for graph mutations, are located in domain-specific modules like mcp/tools/graph.py, mcp/tools/reasoning.py, and mcp/tools/export.py.

Can I expose custom tools through the MCP server?

Yes, the modular architecture in mcp/tools/__init__.py imports tool definitions from specific modules. To expose custom functionality, implement a handler function following the existing pattern, define its JSON schema, and register it in the tool index so that tools/list includes it in the capability advertisement.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →