Merge branch 'main' into graphid-isolation
This commit is contained in:
commit
445ea2e45c
14 changed files with 810 additions and 453 deletions
|
|
@ -69,6 +69,14 @@ COPY ./server/graph_service ./graph_service
|
|||
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||
uv sync --frozen --no-dev
|
||||
|
||||
# Install falkordb if requested
|
||||
ARG INSTALL_FALKORDB=false
|
||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||
if [ "$INSTALL_FALKORDB" = "true" ]; then \
|
||||
WHEEL=$(ls /tmp/*.whl | head -n 1); \
|
||||
uv pip install "$WHEEL[falkordb]"; \
|
||||
fi
|
||||
|
||||
# Change ownership to app user
|
||||
RUN chown -R app:app /app
|
||||
|
||||
|
|
|
|||
33
README.md
33
README.md
|
|
@ -77,6 +77,23 @@ We're excited to open-source Graphiti, believing its potential reaches far beyon
|
|||
<a href="https://arxiv.org/abs/2501.13956"><img src="images/arxiv-screenshot.png" alt="Zep: A Temporal Knowledge Graph Architecture for Agent Memory" width="700px"></a>
|
||||
</p>
|
||||
|
||||
## Zep vs Graphiti
|
||||
|
||||
| Aspect | Zep | Graphiti |
|
||||
|--------|-----|----------|
|
||||
| **What they are** | Complete managed platform for AI memory | Open-source graph framework |
|
||||
| **User & conversation management** | Built-in users, threads, and message storage | Build your own |
|
||||
| **Retrieval & performance** | Pre-configured, production-ready retrieval with sub-200ms performance at scale | Custom implementation required; performance depends on your setup |
|
||||
| **Developer tools** | Dashboard with graph visualization, debug logs, API logs; SDKs for Python, TypeScript, and Go | Build your own tools |
|
||||
| **Enterprise features** | SLAs, support, security guarantees | Self-managed |
|
||||
| **Deployment** | Fully managed or in your cloud | Self-hosted only |
|
||||
|
||||
### When to choose which
|
||||
|
||||
**Choose Zep** if you want a turnkey, enterprise-grade platform with security, performance, and support baked in.
|
||||
|
||||
**Choose Graphiti** if you want a flexible OSS core and you're comfortable building/operating the surrounding system.
|
||||
|
||||
## Why Graphiti?
|
||||
|
||||
Traditional RAG approaches often rely on batch processing and static data summarization, making them inefficient for
|
||||
|
|
@ -239,6 +256,22 @@ The quickstart demonstrates:
|
|||
The example is fully documented with clear explanations of each functionality and includes a comprehensive README with
|
||||
setup instructions and next steps.
|
||||
|
||||
### Running with Docker Compose
|
||||
|
||||
You can use Docker Compose to quickly start the required services:
|
||||
|
||||
- **Neo4j Docker:**
|
||||
```sh
|
||||
docker compose up
|
||||
```
|
||||
This will start the Neo4j Docker service and related components.
|
||||
|
||||
- **FalkorDB Docker:**
|
||||
```sh
|
||||
docker compose --profile falkordb up
|
||||
```
|
||||
This will start the FalkorDB Docker service and related components.
|
||||
|
||||
## MCP Server
|
||||
|
||||
The `mcp_server` directory contains a Model Context Protocol (MCP) server implementation for Graphiti. This server
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
services:
|
||||
graph:
|
||||
profiles: [""]
|
||||
build:
|
||||
context: .
|
||||
ports:
|
||||
|
|
@ -24,8 +25,10 @@ services:
|
|||
- NEO4J_USER=${NEO4J_USER}
|
||||
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
|
||||
- PORT=8000
|
||||
- db_backend=neo4j
|
||||
neo4j:
|
||||
image: neo4j:5.26.2
|
||||
profiles: [""]
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
|
|
@ -44,5 +47,46 @@ services:
|
|||
environment:
|
||||
- NEO4J_AUTH=${NEO4J_USER}/${NEO4J_PASSWORD}
|
||||
|
||||
falkordb:
|
||||
image: falkordb/falkordb:latest
|
||||
profiles: ["falkordb"]
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- falkordb_data:/data
|
||||
environment:
|
||||
- FALKORDB_ARGS=--port 6379 --cluster-enabled no
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-p", "6379", "ping"]
|
||||
interval: 1s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
start_period: 3s
|
||||
graph-falkordb:
|
||||
build:
|
||||
args:
|
||||
INSTALL_FALKORDB: "true"
|
||||
context: .
|
||||
profiles: ["falkordb"]
|
||||
ports:
|
||||
- "8001:8001"
|
||||
depends_on:
|
||||
falkordb:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8001/healthcheck')"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
environment:
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- FALKORDB_HOST=falkordb
|
||||
- FALKORDB_PORT=6379
|
||||
- FALKORDB_DATABASE=default_db
|
||||
- GRAPHITI_BACKEND=falkordb
|
||||
- PORT=8001
|
||||
- db_backend=falkordb
|
||||
|
||||
volumes:
|
||||
neo4j_data:
|
||||
falkordb_data:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
|
@ -261,7 +262,29 @@ class FalkorDriver(GraphDriver):
|
|||
# Create a new instance of FalkorDriver with the same connection but a different database
|
||||
cloned = FalkorDriver(falkor_db=self.client, database=database)
|
||||
|
||||
return cloned
|
||||
return cloned
|
||||
|
||||
async def health_check(self) -> None:
|
||||
"""Check FalkorDB connectivity by running a simple query."""
|
||||
try:
|
||||
await self.execute_query("MATCH (n) RETURN 1 LIMIT 1")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"FalkorDB health check failed: {e}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def convert_datetimes_to_strings(obj):
|
||||
if isinstance(obj, dict):
|
||||
return {k: FalkorDriver.convert_datetimes_to_strings(v) for k, v in obj.items()}
|
||||
elif isinstance(obj, list):
|
||||
return [FalkorDriver.convert_datetimes_to_strings(item) for item in obj]
|
||||
elif isinstance(obj, tuple):
|
||||
return tuple(FalkorDriver.convert_datetimes_to_strings(item) for item in obj)
|
||||
elif isinstance(obj, datetime):
|
||||
return obj.isoformat()
|
||||
else:
|
||||
return obj
|
||||
|
||||
def sanitize(self, query: str) -> str:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -106,3 +106,12 @@ class Neo4jDriver(GraphDriver):
|
|||
for query in index_queries
|
||||
]
|
||||
)
|
||||
|
||||
async def health_check(self) -> None:
|
||||
"""Check Neo4j connectivity by running the driver's verify_connectivity method."""
|
||||
try:
|
||||
await self.client.verify_connectivity()
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Neo4j health check failed: {e}")
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
# Graphiti MCP Server Environment Configuration
|
||||
|
||||
# Neo4j Database Configuration
|
||||
# Database Configuration
|
||||
# Choose between 'neo4j' or 'falkordb'
|
||||
DATABASE_TYPE=falkordb
|
||||
|
||||
# These settings are used to connect to your Neo4j database
|
||||
NEO4J_URI=bolt://localhost:7687
|
||||
NEO4J_USER=neo4j
|
||||
NEO4J_PASSWORD=demodemo
|
||||
|
||||
# These settings are used to connect to your FalkorDB database
|
||||
FALKORDB_PORT=6379
|
||||
FALKORDB_HOST=localhost
|
||||
FALKORDB_USER=
|
||||
FALKORDB_PASSWORD=
|
||||
|
||||
# OpenAI API Configuration
|
||||
# Required for LLM operations
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ RUN groupadd -r app && useradd -r -d /app -g app app
|
|||
COPY pyproject.toml uv.lock ./
|
||||
|
||||
# Install dependencies first (better layer caching)
|
||||
ARG INSTALL_FALKORDB=false
|
||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||
uv sync --frozen --no-dev
|
||||
if [ "$INSTALL_FALKORDB" = "true" ]; then \
|
||||
uv sync --frozen --no-dev --extra falkordb; \
|
||||
else \
|
||||
uv sync --frozen --no-dev; \
|
||||
fi
|
||||
|
||||
# Copy application code
|
||||
COPY graphiti_mcp_server.py ./
|
||||
|
|
@ -43,7 +48,7 @@ RUN chown -Rv app:app /app
|
|||
USER app
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
EXPOSE $PORT
|
||||
|
||||
# Command to run the application
|
||||
CMD ["uv", "run", "graphiti_mcp_server.py"]
|
||||
|
|
|
|||
|
|
@ -82,11 +82,21 @@ uv sync
|
|||
|
||||
## Configuration
|
||||
|
||||
The server uses the following environment variables:
|
||||
The server supports both Neo4j and FalkorDB as database backends. Use the `DATABASE_TYPE` environment variable to choose between them.
|
||||
|
||||
#### Neo4j Configuration (default)
|
||||
|
||||
- `NEO4J_URI`: URI for the Neo4j database (default: `bolt://localhost:7687`)
|
||||
- `NEO4J_USER`: Neo4j username (default: `neo4j`)
|
||||
- `NEO4J_PASSWORD`: Neo4j password (default: `demodemo`)
|
||||
|
||||
#### FalkorDB Configuration
|
||||
- `DATABASE_TYPE`: Set to `falkordb`
|
||||
- `FALKORDB_HOST`: FalkorDB host (default: `localhost`)
|
||||
- `FALKORDB_PORT`: FalkorDB port (default: `6379`)
|
||||
- `FALKORDB_USERNAME`: FalkorDB username (optional)
|
||||
- `FALKORDB_PASSWORD`: FalkorDB password (optional)
|
||||
|
||||
- `OPENAI_API_KEY`: OpenAI API key (required for LLM operations)
|
||||
- `OPENAI_BASE_URL`: Optional base URL for OpenAI API
|
||||
- `MODEL_NAME`: OpenAI model name to use for LLM operations.
|
||||
|
|
@ -115,7 +125,7 @@ uv run graphiti_mcp_server.py
|
|||
With options:
|
||||
|
||||
```bash
|
||||
uv run graphiti_mcp_server.py --model gpt-4.1-mini --transport sse
|
||||
uv run graphiti_mcp_server.py --model gpt-4.1-mini --transport sse --database-type falkordb --port 8001
|
||||
```
|
||||
|
||||
Available arguments:
|
||||
|
|
@ -124,6 +134,7 @@ Available arguments:
|
|||
- `--small-model`: Overrides the `SMALL_MODEL_NAME` environment variable.
|
||||
- `--temperature`: Overrides the `LLM_TEMPERATURE` environment variable.
|
||||
- `--transport`: Choose the transport method (sse or stdio, default: sse)
|
||||
- `--database-type`: Choose database backend (neo4j or falkordb, default: neo4j)
|
||||
- `--group-id`: Set a namespace for the graph (optional). If not provided, defaults to "default".
|
||||
- `--destroy-graph`: If set, destroys all Graphiti graphs on startup.
|
||||
- `--use-custom-entities`: Enable entity extraction using the predefined ENTITY_TYPES
|
||||
|
|
@ -175,11 +186,30 @@ The Docker Compose setup includes a Neo4j container with the following default c
|
|||
- URI: `bolt://neo4j:7687` (from within the Docker network)
|
||||
- Memory settings optimized for development use
|
||||
|
||||
To run only Neo4j with its MCP server:
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
- Neo4j MCP server on port 8000
|
||||
|
||||
#### FalkorDB Configuration
|
||||
|
||||
The Docker Compose setup includes a FalkorDB container with the following default configuration:
|
||||
- Host: `falkordb`
|
||||
- Port: `6379`
|
||||
- No authentication by default
|
||||
|
||||
To run only FalkorDB with its MCP server:
|
||||
```bash
|
||||
docker compose --profile falkordb up
|
||||
```
|
||||
- FalkorDB MCP server on port 8001
|
||||
|
||||
#### Running with Docker Compose
|
||||
|
||||
A Graphiti MCP container is available at: `zepai/knowledge-graph-mcp`. The latest build of this container is used by the Compose setup below.
|
||||
|
||||
Start the services using Docker Compose:
|
||||
Start the services using Docker Compose For Neo4j:
|
||||
|
||||
```bash
|
||||
docker compose up
|
||||
|
|
@ -191,13 +221,25 @@ Or if you're using an older version of Docker Compose:
|
|||
docker-compose up
|
||||
```
|
||||
|
||||
This will start both the Neo4j database and the Graphiti MCP server. The Docker setup:
|
||||
For FalkorDB:
|
||||
|
||||
```bash
|
||||
docker compose --profile falkordb up
|
||||
```
|
||||
|
||||
Or if you're using an older version of Docker Compose:
|
||||
|
||||
```bash
|
||||
docker-compose --profile falkordb up
|
||||
```
|
||||
|
||||
This will start the database(s) and the Graphiti MCP server(s). The Docker setup:
|
||||
|
||||
- Uses `uv` for package management and running the server
|
||||
- Installs dependencies from the `pyproject.toml` file
|
||||
- Connects to the Neo4j container using the environment variables
|
||||
- Exposes the server on port 8000 for HTTP-based SSE transport
|
||||
- Includes a healthcheck for Neo4j to ensure it's fully operational before starting the MCP server
|
||||
- Connects to the database container using the environment variables
|
||||
- Exposes the server on port 8000 (Neo4j) or 8001 (FalkorDB) for HTTP-based SSE transport
|
||||
- Includes healthchecks to ensure databases are fully operational before starting the MCP server
|
||||
|
||||
## Integrating with MCP Clients
|
||||
|
||||
|
|
|
|||
8
mcp_server/claude_desktop_config.json
Normal file
8
mcp_server/claude_desktop_config.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"graphiti": {
|
||||
"transport": "sse",
|
||||
"url": "http://localhost:8001/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
services:
|
||||
neo4j:
|
||||
profiles: [""]
|
||||
image: neo4j:5.26.0
|
||||
ports:
|
||||
- "7474:7474" # HTTP
|
||||
|
|
@ -19,7 +20,8 @@ services:
|
|||
retries: 5
|
||||
start_period: 30s
|
||||
|
||||
graphiti-mcp:
|
||||
graphiti-mcp-neo4j:
|
||||
profiles: [""]
|
||||
image: zepai/knowledge-graph-mcp:latest
|
||||
build:
|
||||
context: .
|
||||
|
|
@ -31,6 +33,8 @@ services:
|
|||
neo4j:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- PORT=8000
|
||||
- DATABASE_TYPE=neo4j
|
||||
- NEO4J_URI=${NEO4J_URI:-bolt://neo4j:7687}
|
||||
- NEO4J_USER=${NEO4J_USER:-neo4j}
|
||||
- NEO4J_PASSWORD=${NEO4J_PASSWORD:-demodemo}
|
||||
|
|
@ -42,6 +46,50 @@ services:
|
|||
- "8000:8000" # Expose the MCP server via HTTP for SSE transport
|
||||
command: ["uv", "run", "graphiti_mcp_server.py", "--transport", "sse"]
|
||||
|
||||
falkordb:
|
||||
profiles: ["falkordb"]
|
||||
image: falkordb/falkordb:latest
|
||||
ports:
|
||||
- "6379:6379"
|
||||
command: ["falkordb-server", "--loadmodule", "/FalkorDB/bin/src/falkordb.so"]
|
||||
volumes:
|
||||
- falkordb_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
|
||||
graphiti-mcp-falkordb:
|
||||
profiles: ["falkordb"]
|
||||
build:
|
||||
args:
|
||||
INSTALL_FALKORDB: "true"
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
env_file:
|
||||
- path: .env
|
||||
required: false
|
||||
depends_on:
|
||||
falkordb:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- PORT=8001
|
||||
- DATABASE_TYPE=falkordb
|
||||
- FALKORDB_HOST=falkordb
|
||||
- FALKORDB_PORT=6379
|
||||
- FALKORDB_USER=${FALKORDB_USER:-}
|
||||
- FALKORDB_PASSWORD=${FALKORDB_PASSWORD:-}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- MODEL_NAME=${MODEL_NAME}
|
||||
- PATH=/root/.local/bin:${PATH}
|
||||
- SEMAPHORE_LIMIT=${SEMAPHORE_LIMIT:-10}
|
||||
ports:
|
||||
- "8001:8001" # Expose the MCP server via HTTP for SSE transport
|
||||
command: ["uv", "run", "graphiti_mcp_server.py", "--transport", "sse"]
|
||||
|
||||
volumes:
|
||||
neo4j_data:
|
||||
neo4j_logs:
|
||||
falkordb_data:
|
||||
|
|
@ -10,15 +10,17 @@ import os
|
|||
import sys
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, TypedDict, cast
|
||||
from typing import Any, cast
|
||||
|
||||
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
|
||||
from dotenv import load_dotenv
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from openai import AsyncAzureOpenAI
|
||||
from pydantic import BaseModel, Field
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from graphiti_core import Graphiti
|
||||
from graphiti_core.driver.neo4j_driver import Neo4jDriver
|
||||
from graphiti_core.edges import EntityEdge
|
||||
from graphiti_core.embedder.azure_openai import AzureOpenAIEmbedderClient
|
||||
from graphiti_core.embedder.client import EmbedderClient
|
||||
|
|
@ -465,6 +467,21 @@ class Neo4jConfig(BaseModel):
|
|||
password=os.environ.get('NEO4J_PASSWORD', 'password'),
|
||||
)
|
||||
|
||||
class FalkorConfig(BaseModel):
|
||||
"""Configuration for FalkorDB database connection."""
|
||||
|
||||
host: str = 'localhost'
|
||||
port: int = 6379
|
||||
user: str = ''
|
||||
password: str = ''
|
||||
|
||||
@classmethod
|
||||
def from_env(cls) -> 'FalkorConfig':
|
||||
host = os.environ.get('FALKORDB_HOST', 'localhost')
|
||||
port = int(os.environ.get('FALKORDB_PORT', 6379))
|
||||
user = os.environ.get('FALKORDB_USER', '')
|
||||
password = os.environ.get('FALKORDB_PASSWORD', '')
|
||||
return cls(host=host, port=port, user=user, password=password)
|
||||
|
||||
class GraphitiConfig(BaseModel):
|
||||
"""Configuration for Graphiti client.
|
||||
|
|
@ -475,18 +492,35 @@ class GraphitiConfig(BaseModel):
|
|||
llm: GraphitiLLMConfig = Field(default_factory=GraphitiLLMConfig)
|
||||
embedder: GraphitiEmbedderConfig = Field(default_factory=GraphitiEmbedderConfig)
|
||||
neo4j: Neo4jConfig = Field(default_factory=Neo4jConfig)
|
||||
falkordb: FalkorConfig = Field(default_factory=FalkorConfig)
|
||||
|
||||
group_id: str | None = None
|
||||
use_custom_entities: bool = False
|
||||
destroy_graph: bool = False
|
||||
database_type: str = 'neo4j'
|
||||
|
||||
@classmethod
|
||||
def from_env(cls) -> 'GraphitiConfig':
|
||||
"""Create a configuration instance from environment variables."""
|
||||
return cls(
|
||||
llm=GraphitiLLMConfig.from_env(),
|
||||
embedder=GraphitiEmbedderConfig.from_env(),
|
||||
neo4j=Neo4jConfig.from_env(),
|
||||
)
|
||||
db_type = os.environ.get('DATABASE_TYPE')
|
||||
if not db_type:
|
||||
raise ValueError('DATABASE_TYPE environment variable must be set (e.g., "neo4j" or "falkordb")')
|
||||
if db_type == 'neo4j':
|
||||
return cls(
|
||||
llm=GraphitiLLMConfig.from_env(),
|
||||
embedder=GraphitiEmbedderConfig.from_env(),
|
||||
neo4j=Neo4jConfig.from_env(),
|
||||
database_type=db_type,
|
||||
)
|
||||
elif db_type == 'falkordb':
|
||||
return cls(
|
||||
llm=GraphitiLLMConfig.from_env(),
|
||||
embedder=GraphitiEmbedderConfig.from_env(),
|
||||
falkordb=FalkorConfig.from_env(),
|
||||
database_type=db_type,
|
||||
)
|
||||
else:
|
||||
raise ValueError(f'Unsupported DATABASE_TYPE: {db_type}')
|
||||
|
||||
@classmethod
|
||||
def from_cli_and_env(cls, args: argparse.Namespace) -> 'GraphitiConfig':
|
||||
|
|
@ -587,13 +621,38 @@ async def initialize_graphiti():
|
|||
if not config.neo4j.uri or not config.neo4j.user or not config.neo4j.password:
|
||||
raise ValueError('NEO4J_URI, NEO4J_USER, and NEO4J_PASSWORD must be set')
|
||||
|
||||
# Validate FalkorDB configuration
|
||||
if config.database_type == 'falkordb' and (not config.falkordb.host or not config.falkordb.port):
|
||||
raise ValueError('FALKORDB_HOST and FALKORDB_PORT must be set for FalkorDB')
|
||||
|
||||
embedder_client = config.embedder.create_client()
|
||||
|
||||
# Construct the driver based on the database_type
|
||||
driver = None
|
||||
if config.database_type == 'neo4j':
|
||||
driver = Neo4jDriver(
|
||||
uri=config.neo4j.uri,
|
||||
user=config.neo4j.user,
|
||||
password=config.neo4j.password,
|
||||
)
|
||||
elif config.database_type == 'falkordb':
|
||||
from graphiti_core.driver.falkordb_driver import FalkorDriver
|
||||
host = config.falkordb.host if hasattr(config.falkordb, 'host') else 'localhost'
|
||||
port = int(config.falkordb.port) if hasattr(config.falkordb, 'port') else 6379
|
||||
username = config.falkordb.user or None
|
||||
password = config.falkordb.password or None
|
||||
driver = FalkorDriver(
|
||||
host=host,
|
||||
port=port,
|
||||
username=username,
|
||||
password=password,
|
||||
)
|
||||
else:
|
||||
raise ValueError(f'Unsupported database type: {config.database_type}')
|
||||
|
||||
# Initialize Graphiti client
|
||||
graphiti_client = Graphiti(
|
||||
uri=config.neo4j.uri,
|
||||
user=config.neo4j.user,
|
||||
password=config.neo4j.password,
|
||||
graph_driver=driver,
|
||||
llm_client=llm_client,
|
||||
embedder=embedder_client,
|
||||
max_coroutines=SEMAPHORE_LIMIT,
|
||||
|
|
@ -606,7 +665,7 @@ async def initialize_graphiti():
|
|||
|
||||
# Initialize the graph database with Graphiti's indices
|
||||
await graphiti_client.build_indices_and_constraints()
|
||||
logger.info('Graphiti client initialized successfully')
|
||||
logger.info(f'Graphiti client initialized successfully with {config.database_type}')
|
||||
|
||||
# Log configuration details for transparency
|
||||
if llm_client:
|
||||
|
|
@ -616,6 +675,7 @@ async def initialize_graphiti():
|
|||
logger.info('No LLM client configured - entity extraction will be limited')
|
||||
|
||||
logger.info(f'Using group_id: {config.group_id}')
|
||||
logger.info(f'Using database type: {config.database_type}')
|
||||
logger.info(
|
||||
f'Custom entity extraction: {"enabled" if config.use_custom_entities else "disabled"}'
|
||||
)
|
||||
|
|
@ -1131,7 +1191,7 @@ async def clear_graph() -> SuccessResponse | ErrorResponse:
|
|||
|
||||
@mcp.resource('http://graphiti/status')
|
||||
async def get_status() -> StatusResponse:
|
||||
"""Get the status of the Graphiti MCP server and Neo4j connection."""
|
||||
"""Get the status of the Graphiti MCP server and database connection."""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
|
|
@ -1145,14 +1205,14 @@ async def get_status() -> StatusResponse:
|
|||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Test database connection
|
||||
await client.driver.client.verify_connectivity() # type: ignore
|
||||
await client.driver.health_check() # type: ignore # type: ignore
|
||||
|
||||
return StatusResponse(
|
||||
status='ok', message='Graphiti MCP server is running and connected to Neo4j'
|
||||
status='ok', message=f'Graphiti MCP server is running and connected to {config.database_type}'
|
||||
)
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error checking Neo4j connection: {error_msg}')
|
||||
logger.error(f'Error checking {config.database_type} connection: {error_msg}')
|
||||
return StatusResponse(
|
||||
status='error',
|
||||
message=f'Graphiti MCP server is running but Neo4j connection failed: {error_msg}',
|
||||
|
|
@ -1200,6 +1260,17 @@ async def initialize_server() -> MCPConfig:
|
|||
default=os.environ.get('MCP_SERVER_HOST'),
|
||||
help='Host to bind the MCP server to (default: MCP_SERVER_HOST environment variable)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--port',
|
||||
type=int,
|
||||
default=int(os.environ.get('PORT', 8000)),
|
||||
help='Port to run the MCP server on (default: 8000 or value of PORT env variable)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database-type',
|
||||
choices=['neo4j', 'falkordb'],
|
||||
help='Type of database to use (default: neo4j)',
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
|
@ -1226,6 +1297,11 @@ async def initialize_server() -> MCPConfig:
|
|||
# Set MCP server host from CLI or env
|
||||
mcp.settings.host = args.host
|
||||
|
||||
if args.port:
|
||||
logger.info(f'Setting MCP server port to: {args.port}')
|
||||
# Set MCP server port from CLI or env
|
||||
mcp.settings.port = args.port
|
||||
|
||||
# Return MCP configuration
|
||||
return MCPConfig.from_cli(args)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ requires-python = ">=3.10,<4"
|
|||
dependencies = [
|
||||
"mcp>=1.5.0",
|
||||
"openai>=1.68.2",
|
||||
"graphiti-core>=0.14.0",
|
||||
"graphiti-core==0.18.8",
|
||||
"azure-identity>=1.21.0",
|
||||
"graphiti-core",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
falkordb = ["falkordb>=1.1.2,<2.0.0"]
|
||||
892
mcp_server/uv.lock
generated
892
mcp_server/uv.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -423,6 +423,14 @@
|
|||
"created_at": "2025-10-15T16:29:33Z",
|
||||
"repoId": 840056306,
|
||||
"pullRequestNo": 1005
|
||||
},
|
||||
{
|
||||
"name": "dontang97",
|
||||
"id": 88384441,
|
||||
"comment_id": 3431443627,
|
||||
"created_at": "2025-10-22T09:52:01Z",
|
||||
"repoId": 840056306,
|
||||
"pullRequestNo": 1020
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue