python-mcp-server
Provides graph search and traversal capabilities via Graphiti on Neo4j, enabling discovery of entities and relationships in the knowledge graph.
Provides text embedding generation for query and document vectors, enabling semantic search for both graph and vector RAG tools.
Provides vector similarity search and BM25 full-text ranking via pgvector, enabling document retrieval based on semantic and exact-term matching.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@python-mcp-serverWhat connects Tesla and battery technology?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Python MCP Server ๐ง
A Model Context Protocol (MCP) server that gives AI agents access to a Graphiti knowledge graph and a pgvector document store for grounded, evidence-backed responses.
Features
๐ Hybrid graph search โ semantic + BM25 + graph traversal via Graphiti
๐ Vector RAG โ pgvector similarity search; query strings are embedded internally via OpenAI (no pre-computed vectors required from callers)
๐งพ Evidence retrieval, not fake verification โ
verify_factreturns related graph evidence; the calling LLM judges entailmentโก Fail fast โ client errors surface as MCP errors, not silent empty results
โ๏ธ Clean config split โ
cfg.ymlfor config, env vars for secrets only
Related MCP server: Memory MCP
Tools
Tool | Input | Returns |
|
| Graph entities/relationships |
|
| Document chunks ranked by similarity |
|
|
|
|
| Graph results + document chunks |
All tools take strings โ embeddings are generated server-side.
Resources: knowledge://instructions, knowledge://examples.
Prompt: answer_with_verification.
Quick Start
pip install python-mcp-server
# or
uvx python-mcp-serverConfiguration
cfg.yml holds all non-secret config. Secrets live only in environment
variables โ never in cfg.yml, never in the Postgres URL.
cfg.yml
local:
log_level: DEBUG
neo4j:
uri: bolt://localhost:7687
user: neo4j
database: neo4j
postgres:
host: localhost
port: 5432
database: knowledge
user: postgres
embeddings_table: energy_embeddings
embedding_model: text-embedding-3-smallThe server selects the top-level key based on the ENV env var (default local).
A beta section is also supported.
Secrets (environment)
export NEO4J_PASSWORD="..."
export POSTGRES_PASSWORD="..."
export OPENAI_API_KEY="..."
export ENV="local"Programmatic usage
from python_mcp_server import create_server
from python_mcp_server.config import Config, Neo4jConfig, PostgresConfig, LogLevel
config = Config(
log_level=LogLevel.INFO,
neo4j=Neo4jConfig(uri="bolt://localhost:7687", user="neo4j", database="neo4j"),
postgres=PostgresConfig(
host="localhost", port=5432, database="knowledge", user="postgres",
embeddings_table="energy_embeddings",
embedding_model="text-embedding-3-small",
),
)
server = create_server(
config=config,
neo4j_password="...",
postgres_password="...",
openai_api_key="...",
)Usage
Claude Code
export NEO4J_PASSWORD=... POSTGRES_PASSWORD=... OPENAI_API_KEY=...
claude mcp add domain-expert -- uvx python-mcp-serverClaude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"knowledge-graph": {
"command": "uvx",
"args": ["python-mcp-server"],
"env": {
"NEO4J_PASSWORD": "...",
"POSTGRES_PASSWORD": "...",
"OPENAI_API_KEY": "..."
}
}
}
}Pydantic-AI
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStdio
mcp = MCPServerStdio("uvx", "python-mcp-server")
agent = Agent(toolsets=[mcp])
result = await agent.run("What connects Tesla and battery technology?")Database Schema
pgvector table expected by rag_search:
CREATE TABLE energy_embeddings (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT NOT NULL,
book TEXT,
section_level TEXT,
analysis_relevance TEXT,
embedding vector(1536), -- text-embedding-3-small
content_tsv tsvector
GENERATED ALWAYS AS (to_tsvector('english', content)) STORED
);
CREATE INDEX ON energy_embeddings USING ivfflat (embedding vector_cosine_ops);
CREATE INDEX idx_content_tsv ON energy_embeddings USING gin(content_tsv);Embedding dimension must match embedding_model in cfg.yml.
rag_search issues two rankings against this table โ cosine over embedding
and BM25 over content_tsv โ and fuses them via Reciprocal Rank Fusion
(k=60). Exact-term matches (protocol field names, enum values, requirement
IDs) come through the BM25 leg that pure cosine would miss.
Development
git clone <repo> && cd python-mcp-server
uv sync --dev
cp template-secrets.env .env # fill in secrets
uv run poe checks # deptry, black, ruff, mypy, bandit, pip-audit
uv run poe cover # tests with coverage
uv run python-mcp-serverArchitecture
src/python_mcp_server/
โโโ clients/
โ โโโ embedder.py # OpenAI embeddings (injected)
โ โโโ graphiti_client.py # Neo4j via Graphiti
โ โโโ rag_client.py # pgvector similarity search
โโโ config.py # cfg.yml loader
โโโ models.py # Pydantic response models
โโโ server.py # FastMCP tools, resources, prompt
โโโ __main__.py # CLI entry pointDesign Principles
String-in, evidence-out. Callers pass natural language; the server handles embeddings and returns typed Pydantic results.
No fake verification.
verify_factreturns evidence; the caller LLM decides entailment. The server never invents averified: bool.Fail fast. Database errors propagate to the MCP client so Claude sees "Neo4j unreachable" instead of "no results."
Config vs. secrets are separate concerns.
cfg.ymlis checked in; passwords and API keys never are.
Available Tools
4 toolscombined_searchA
Search both the knowledge graph and document vectors.
USE WHEN: You need both structured facts and supporting context.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | Original search query |
| graph_results | Yes | Results from knowledge graph |
| vector_results | Yes | Results from vector search |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states the tool searches two sources, implying a read-only operation, but it does not disclose any potential side effects, result structure, or limitations (e.g., how results are combined, whether there is pagination). For a search tool this is acceptable but not exhaustive; the description could mention that it returns a combined result set or any rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences, with the primary purpose in the first and usage guidance in the second. No filler or redundancy. The most important information (what it does) is front-loaded, and the 'USE WHEN' clause is directly relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema (which likely describes return format) and the description covers purpose and usage, it is mostly complete. However, the lack of parameter documentation and the absence of behavioral notes (e.g., read-only status) leave minor gaps. For a search tool, the description is adequate but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate by explaining the parameters. It mentions 'query' implicitly but provides no detail about the 'limit' parameter, its purpose, or its effect. The description adds no meaning beyond the schema's basic type and default. Since it fails to document 'limit', the score is low.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Search both the knowledge graph and document vectors.' This is a specific verb (search) and resource (knowledge graph + document vectors), which distinguishes it from sibling tools like search_knowledge (likely just graph) and rag_search (likely just vectors). No ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes an explicit 'USE WHEN' clause: 'You need both structured facts and supporting context.' This provides clear context for when to use the tool. However, it does not explicitly mention when not to use it or point to alternatives, leaving some room for inference. It does not say 'if you only need facts, use search_knowledge.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rag_searchA
Search documents using vector similarity for context.
USE WHEN: You need detailed context, explanations, or source documents. The query string is embedded internally; no pre-computed vector needed.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It usefully reveals that the query is embedded internally and that no precomputed vector is required. It does not state side-effect safety, ordering, or failure behavior, but 'Search documents' reasonably implies a non-mutating read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences with no filler, and it is well front-loaded: mechanism first, use case second, operational detail last. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The USE WHEN rule and output schema cover the core calling intent, and the tool is simple enough that query plus optional limit define the invocation. However, with three sibling tools, the description never explains when to choose rag_search over search_knowledge or combined_search, leaving a selection gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds crucial meaning to the query parameter by clarifying it is a plain-text string and that the tool performs the embedding internally. The remaining limit parameter is self-explanatory from its name and default, so the 0% schema coverage is largely compensated for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the action ('Search documents') and mechanism ('vector similarity') and ties it to a concrete need ('context, explanations, or source documents'). It does not explicitly differentiate it from sibling search_knowledge, so an agent may still be unsure which search tool to choose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
A labeled USE WHEN condition is present and tells the agent the kind of request that fits this tool. It does not mention when not to use it or name alternatives, so the guidance is clear but incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_knowledgeA
Search factual knowledge in the Graphiti knowledge graph.
USE WHEN: You need verified facts, entities, relationships, or structured knowledge. Combines semantic search, BM25, and graph traversal.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | List of search results |
| total | Yes | Total number of results |
| source | No | Source of the results - verified facts from knowledge graph |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral disclosure burden. It does meaningful work by revealing the hybrid nature of the search: 'Combines semantic search, BM25, and graph traversal.' It does not mention result freshness, permissions, rate limits, or whether results are reranked, but the hybrid mechanism is a useful behavioral disclosure beyond a bare 'search' statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose: 'Search factual knowledge in the Graphiti knowledge graph.' The USE WHEN section adds usage context, and the final sentence explains the search mechanism, with no fluff or redundancy. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter search with an output schema, the description covers the purpose, the underlying techniques, and the main use case. The main completeness gap is the lack of differentiation among the siblings (rag_search, verify_fact, combined_search), and the absence of any clarification of the limit parameter's role leaves a modest but real decision gap for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not mention query or limit at all. The query parameter's expected format, syntax hints, or semantics, and the meaning of limit, are left entirely to the schema names/defaults, so the description fails to compensate for the schema's minimal documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a clear verb and resource: 'Search factual knowledge in the Graphiti knowledge graph.' It also clarifies the content types covered ('verified facts, entities, relationships, or structured knowledge' and the hybrid retrieval approach ('semantic search, BM25, and graph traversal'). It does not explicitly differentiate this tool from siblings like rag_search, verify_fact, or combined_search, so it stops short of full discrimination.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'USE WHEN: You need verified facts, entities, relationships, or structured knowledge' clearly states when an agent should consider this tool. However, it provides no exclusions, no 'use instead' guidance, and no comparison to the sibling tools, so it lacks the full when/not-when structure.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_factA
Retrieve knowledge-graph evidence relevant to a statement.
USE WHEN: You want to check a claim against the graph. Returns related facts; the caller judges whether they support or contradict the statement. No boolean verdict โ entailment is the caller's job.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| statement | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| evidence | Yes | Related facts from the knowledge graph, ranked by relevance |
| statement | Yes | The statement the evidence was gathered for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It explicitly discloses a non-obvious trait: 'No boolean verdict โ entailment is the caller's job,' which prevents the agent from expecting a yes/no answer. This is meaningful behavioral context beyond the schema, though it does not discuss safety or permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-organized: a one-line purpose, a 'USE WHEN' trigger, and a crucial behavioral caveat. Every sentence earns its place and the most important scoping information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter retrieval tool with an output schema, the description covers purpose, usage context, and the key behavioral boundary. It does not explicitly route between sibling tools, but the name and 'USE WHEN' clause make the intended use reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies that 'statement' is the claim to verify against the graph, adding meaning beyond the schema. However, 'limit' receives no explanation, though its default of 5 and name make its basic meaning inferable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Retrieve knowledge-graph evidence relevant to a statement.' It clearly frames the tool as a fact-checking/evidence-gathering operation, distinguishing it from generic search siblings by emphasizing that the caller, not the tool, judges entailment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' clause explicitly states when to invoke the tool: 'You want to check a claim against the graph.' It provides clear context and sets expectations about no boolean verdict, but it does not name sibling alternatives or state when not to use them, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.0-beta- First observed
combined_search - First observed
rag_search - First observed
search_knowledge - First observed
verify_fact
TDQS
Scored across 4 tools
Each tool has a reasonably clear purpose: graph knowledge search, document vector search, combined search, and claim verification. The only mild overlap is between search_knowledge and verify_fact, but the descriptions distinguish general exploration from targeted claim checking.
Names are all lowercase snake_case and readable, but the pattern is inconsistent: search_knowledge and verify_fact are verb_noun, while rag_search and combined_search are qualifier_search. This makes the naming convention less predictable across the set.
Four tools is a well-scoped size for a retrieval-focused server. Each tool has a distinct role, and combined_search earns a place as a convenience for workflows needing both knowledge graph and document context.
For a read-only search and verification server, the core operations are covered: graph search, RAG search, combined search, and claim verification. Missing ingestion or update/delete tools would be a gap only if the server were meant to manage the underlying knowledge store, which the descriptions do not indicate.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yoโฆ
Cloud or self-hosted knowledge for AI agents: hybrid search, reranking, GraphRAG, scoped MCP tools.
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Related MCP Servers
AlicenseCqualityNot gradedmaintenanceA lightweight server implementation of the Model Context Protocol that connects Memgraph database with LLMs, allowing users to interact with graph databases through natural language.125MIT- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that provides AI assistants with persistent semantic memory and knowledge graph capabilities using PostgreSQL and vector embeddings. It enables cross-session storage, hybrid search, and complex relationship tracking for enhanced contextual awareness.4 npm1MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server implementing Graph RAG with local, embedded Knowledge Graph using FAISS for vector search and NetworkX for graph traversal, enabling hybrid retrieval through anchor discovery and relationship expansion.2MIT

Geniro Graphiti MCPofficial
AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that provides Claude CLI with a Graphiti knowledge-graph memory backed by Neo4j, featuring synchronous writes and no silent ingestion failures.Apache 2.0