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:
- Initialize: The client sends an
initializerequest to negotiate protocol capabilities and receive server metadata. - Discover: The client queries
tools/listto retrieve available tool definitions including input schemas. - Invoke: The client sends
tools/callwith a valid tool name and arguments conforming to the schema defined inmcp/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 inmcp/server.py. - Discovery: Query
tools/listto retrieve definitions from the registry inmcp/tools/__init__.pyand schemas frommcp/schemas.py. - Invocation: Send
tools/callwith JSON arguments matching the tool's inputSchema; handlers inmcp/tools/graph.pyand related modules process requests using the singleton session frommcp/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →