Fix MCP server telemetry and update graphiti-core to v0.23.0 (#1057)

* Fix MCP server telemetry and update graphiti-core to v0.23.0

- Regenerate uv.lock in Docker builds to ensure posthog dependency is included
- Update graphiti-core version to 0.23.0 across all configurations
- Fix Python 3.11 compatibility for Pydantic TypedDict import
- Add FalkorDB Browser UI access information to startup logs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add typing-extensions as explicit dependency

Required for Python 3.11 compatibility with Pydantic 2.11.7,
which mandates typing_extensions.TypedDict on Python < 3.12.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Use built-in TypedDict from typing module

Python 3.10+ includes TypedDict in the standard library.
Removed typing-extensions dependency as it's unnecessary.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Revert to typing_extensions.TypedDict for Pydantic compatibility

Pydantic requires typing_extensions.TypedDict on Python < 3.12.
Docker container uses Python 3.11, so this is necessary.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add Ruff linter rule to prevent typing.TypedDict usage

Adds banned-api configuration to both main and MCP server pyproject.toml
files to enforce typing_extensions.TypedDict usage, required for
Pydantic compatibility on Python < 3.12.

Also includes Ruff auto-formatting changes to quote styles.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Bump MCP server version to 1.0.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Daniel Chalef 2025-11-08 18:31:24 -08:00 committed by GitHub
parent d01e3c5df9
commit d97c248551
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 59 additions and 33 deletions

View file

@ -33,16 +33,20 @@ ENV UV_COMPILE_BYTECODE=1 \
WORKDIR /app/mcp WORKDIR /app/mcp
# Accept graphiti-core version as build argument # Accept graphiti-core version as build argument
ARG GRAPHITI_CORE_VERSION=0.22.0 ARG GRAPHITI_CORE_VERSION=0.23.0
# Copy project files for dependency installation # Copy project files for dependency installation
COPY pyproject.toml uv.lock ./ COPY pyproject.toml uv.lock ./
# Remove the local path override for graphiti-core in Docker builds # Remove the local path override for graphiti-core in Docker builds
# and regenerate lock file to match the PyPI version
RUN sed -i '/\[tool\.uv\.sources\]/,/graphiti-core/d' pyproject.toml && \ RUN sed -i '/\[tool\.uv\.sources\]/,/graphiti-core/d' pyproject.toml && \
if [ -n "${GRAPHITI_CORE_VERSION}" ]; then \ if [ -n "${GRAPHITI_CORE_VERSION}" ]; then \
sed -i "s/graphiti-core\[falkordb\]>=0\.16\.0/graphiti-core[falkordb]==${GRAPHITI_CORE_VERSION}/" pyproject.toml; \ sed -i "s/graphiti-core\[falkordb\]>=0\.23\.0/graphiti-core[falkordb]==${GRAPHITI_CORE_VERSION}/" pyproject.toml; \
fi fi && \
echo "Regenerating lock file for PyPI graphiti-core..." && \
rm -f uv.lock && \
uv lock
# Install Python dependencies # Install Python dependencies
RUN --mount=type=cache,target=/root/.cache/uv \ RUN --mount=type=cache,target=/root/.cache/uv \

View file

@ -28,15 +28,19 @@ ENV UV_COMPILE_BYTECODE=1 \
WORKDIR /app/mcp WORKDIR /app/mcp
# Accept graphiti-core version as build argument # Accept graphiti-core version as build argument
ARG GRAPHITI_CORE_VERSION=0.22.0 ARG GRAPHITI_CORE_VERSION=0.23.0
# Copy project files for dependency installation # Copy project files for dependency installation
COPY pyproject.toml uv.lock ./ COPY pyproject.toml uv.lock ./
# Remove the local path override for graphiti-core in Docker builds # Remove the local path override for graphiti-core in Docker builds
# Install with BOTH neo4j and falkordb extras for maximum flexibility # Install with BOTH neo4j and falkordb extras for maximum flexibility
# and regenerate lock file to match the PyPI version
RUN sed -i '/\[tool\.uv\.sources\]/,/graphiti-core/d' pyproject.toml && \ RUN sed -i '/\[tool\.uv\.sources\]/,/graphiti-core/d' pyproject.toml && \
sed -i "s/graphiti-core\[falkordb\]>=0\.16\.0/graphiti-core[neo4j,falkordb]==${GRAPHITI_CORE_VERSION}/" pyproject.toml sed -i "s/graphiti-core\[falkordb\]>=0\.23\.0/graphiti-core[neo4j,falkordb]==${GRAPHITI_CORE_VERSION}/" pyproject.toml && \
echo "Regenerating lock file for PyPI graphiti-core..." && \
rm -f uv.lock && \
uv lock
# Install Python dependencies # Install Python dependencies
RUN --mount=type=cache,target=/root/.cache/uv \ RUN --mount=type=cache,target=/root/.cache/uv \

View file

@ -5,7 +5,7 @@ services:
context: .. context: ..
dockerfile: docker/Dockerfile dockerfile: docker/Dockerfile
args: args:
GRAPHITI_CORE_VERSION: ${GRAPHITI_CORE_VERSION:-0.22.0} GRAPHITI_CORE_VERSION: ${GRAPHITI_CORE_VERSION:-0.23.0}
MCP_SERVER_VERSION: ${MCP_SERVER_VERSION:-1.0.0} MCP_SERVER_VERSION: ${MCP_SERVER_VERSION:-1.0.0}
BUILD_DATE: ${BUILD_DATE:-} BUILD_DATE: ${BUILD_DATE:-}
VCS_REF: ${VCS_REF:-} VCS_REF: ${VCS_REF:-}

View file

@ -1,15 +1,16 @@
[project] [project]
name = "mcp-server" name = "mcp-server"
version = "1.0.0" version = "1.0.1"
description = "Graphiti MCP Server" description = "Graphiti MCP Server"
readme = "README.md" readme = "README.md"
requires-python = ">=3.10,<4" requires-python = ">=3.10,<4"
dependencies = [ dependencies = [
"mcp>=1.9.4", "mcp>=1.9.4",
"openai>=1.91.0", "openai>=1.91.0",
"graphiti-core[falkordb]>=0.16.0", "graphiti-core[falkordb]>=0.23.0",
"pydantic-settings>=2.0.0", "pydantic-settings>=2.0.0",
"pyyaml>=6.0", "pyyaml>=6.0",
"typing-extensions>=4.0.0",
] ]
[project.optional-dependencies] [project.optional-dependencies]
@ -24,7 +25,7 @@ providers = [
"sentence-transformers>=2.0.0", "sentence-transformers>=2.0.0",
] ]
dev = [ dev = [
"graphiti-core>=0.16.0", "graphiti-core>=0.23.0",
"httpx>=0.28.1", "httpx>=0.28.1",
"mcp>=1.9.4", "mcp>=1.9.4",
"pyright>=1.1.404", "pyright>=1.1.404",
@ -58,6 +59,10 @@ select = [
] ]
ignore = ["E501"] ignore = ["E501"]
[tool.ruff.lint.flake8-tidy-imports.banned-api]
# Required by Pydantic on Python < 3.12
"typing.TypedDict".msg = "Use typing_extensions.TypedDict instead."
[tool.ruff.format] [tool.ruff.format]
quote-style = "single" quote-style = "single"
indent-style = "space" indent-style = "space"

View file

@ -245,35 +245,35 @@ class GraphitiService:
db_provider = self.config.database.provider db_provider = self.config.database.provider
if db_provider.lower() == 'falkordb': if db_provider.lower() == 'falkordb':
raise RuntimeError( raise RuntimeError(
f"\n{'='*70}\n" f'\n{"=" * 70}\n'
f"Database Connection Error: FalkorDB is not running\n" f'Database Connection Error: FalkorDB is not running\n'
f"{'='*70}\n\n" f'{"=" * 70}\n\n'
f"FalkorDB at {db_config['host']}:{db_config['port']} is not accessible.\n\n" f'FalkorDB at {db_config["host"]}:{db_config["port"]} is not accessible.\n\n'
f"To start FalkorDB:\n" f'To start FalkorDB:\n'
f" - Using Docker Compose: cd mcp_server && docker compose up\n" f' - Using Docker Compose: cd mcp_server && docker compose up\n'
f" - Or run FalkorDB manually: docker run -p 6379:6379 falkordb/falkordb\n\n" f' - Or run FalkorDB manually: docker run -p 6379:6379 falkordb/falkordb\n\n'
f"{'='*70}\n" f'{"=" * 70}\n'
) from db_error ) from db_error
elif db_provider.lower() == 'neo4j': elif db_provider.lower() == 'neo4j':
raise RuntimeError( raise RuntimeError(
f"\n{'='*70}\n" f'\n{"=" * 70}\n'
f"Database Connection Error: Neo4j is not running\n" f'Database Connection Error: Neo4j is not running\n'
f"{'='*70}\n\n" f'{"=" * 70}\n\n'
f"Neo4j at {db_config.get('uri', 'unknown')} is not accessible.\n\n" f'Neo4j at {db_config.get("uri", "unknown")} is not accessible.\n\n'
f"To start Neo4j:\n" f'To start Neo4j:\n'
f" - Using Docker Compose: cd mcp_server && docker compose -f docker/docker-compose-neo4j.yml up\n" f' - Using Docker Compose: cd mcp_server && docker compose -f docker/docker-compose-neo4j.yml up\n'
f" - Or install Neo4j Desktop from: https://neo4j.com/download/\n" f' - Or install Neo4j Desktop from: https://neo4j.com/download/\n'
f" - Or run Neo4j manually: docker run -p 7474:7474 -p 7687:7687 neo4j:latest\n\n" f' - Or run Neo4j manually: docker run -p 7474:7474 -p 7687:7687 neo4j:latest\n\n'
f"{'='*70}\n" f'{"=" * 70}\n'
) from db_error ) from db_error
else: else:
raise RuntimeError( raise RuntimeError(
f"\n{'='*70}\n" f'\n{"=" * 70}\n'
f"Database Connection Error: {db_provider} is not running\n" f'Database Connection Error: {db_provider} is not running\n'
f"{'='*70}\n\n" f'{"=" * 70}\n\n'
f"{db_provider} at {db_config.get('uri', 'unknown')} is not accessible.\n\n" f'{db_provider} at {db_config.get("uri", "unknown")} is not accessible.\n\n'
f"Please ensure {db_provider} is running and accessible.\n\n" f'Please ensure {db_provider} is running and accessible.\n\n'
f"{'='*70}\n" f'{"=" * 70}\n'
) from db_error ) from db_error
# Re-raise other errors # Re-raise other errors
raise raise
@ -931,6 +931,11 @@ async def run_mcp_server():
logger.info(f' Base URL: http://{display_host}:{mcp.settings.port}/') logger.info(f' Base URL: http://{display_host}:{mcp.settings.port}/')
logger.info(f' MCP Endpoint: http://{display_host}:{mcp.settings.port}/mcp/') logger.info(f' MCP Endpoint: http://{display_host}:{mcp.settings.port}/mcp/')
logger.info(' Transport: HTTP (streamable)') logger.info(' Transport: HTTP (streamable)')
# Show FalkorDB Browser UI access if enabled
if os.environ.get('BROWSER', '1') == '1':
logger.info(f' FalkorDB Browser UI: http://{display_host}:3000/')
logger.info('=' * 60) logger.info('=' * 60)
logger.info('For MCP clients, connect to the /mcp/ endpoint above') logger.info('For MCP clients, connect to the /mcp/ endpoint above')

View file

@ -1,6 +1,8 @@
"""Response type definitions for Graphiti MCP Server.""" """Response type definitions for Graphiti MCP Server."""
from typing import Any, TypedDict from typing import Any
from typing_extensions import TypedDict
class ErrorResponse(TypedDict): class ErrorResponse(TypedDict):

2
mcp_server/uv.lock generated
View file

@ -1082,6 +1082,7 @@ dependencies = [
{ name = "openai" }, { name = "openai" },
{ name = "pydantic-settings" }, { name = "pydantic-settings" },
{ name = "pyyaml" }, { name = "pyyaml" },
{ name = "typing-extensions" },
] ]
[package.optional-dependencies] [package.optional-dependencies]
@ -1132,6 +1133,7 @@ requires-dist = [
{ name = "pyyaml", specifier = ">=6.0" }, { name = "pyyaml", specifier = ">=6.0" },
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.7.1" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.7.1" },
{ name = "sentence-transformers", marker = "extra == 'providers'", specifier = ">=2.0.0" }, { name = "sentence-transformers", marker = "extra == 'providers'", specifier = ">=2.0.0" },
{ name = "typing-extensions", specifier = ">=4.0.0" },
{ name = "voyageai", marker = "extra == 'providers'", specifier = ">=0.2.3" }, { name = "voyageai", marker = "extra == 'providers'", specifier = ">=0.2.3" },
] ]
provides-extras = ["azure", "providers", "dev"] provides-extras = ["azure", "providers", "dev"]

View file

@ -90,6 +90,10 @@ select = [
] ]
ignore = ["E501"] ignore = ["E501"]
[tool.ruff.lint.flake8-tidy-imports.banned-api]
# Required by Pydantic on Python < 3.12
"typing.TypedDict".msg = "Use typing_extensions.TypedDict instead."
[tool.ruff.format] [tool.ruff.format]
quote-style = "single" quote-style = "single"
indent-style = "space" indent-style = "space"