Cursor Docker networking fix + multi project support + open router support
Summary
This PR significantly enhances the Graphiti MCP Server with OpenRouter integration improvements, Docker deployment enhancements, dependency updates, comprehensive documentation consolidation, and introduces seamless multi-project support through URL-based group_id switching.
Key Changes
🆕 NEW: OpenRouter App Identification
- Automatic header injection: Added
HTTP-RefererandX-Titleheaders for proper OpenRouter app identification - Leaderboard visibility: App now appears as "Graphiti MCP Server" instead of "Unknown" in OpenRouter usage logs
- Smart detection: Headers automatically added when using
openrouter.aibase URL - Zero configuration: Works seamlessly with existing OpenRouter setup
🚀 NEW: Multi-Project Support
- URL-based group_id switching: Revolutionary feature enabling seamless project isolation
- Single server, unlimited projects: Use one Graphiti instance for all your projects
- Zero configuration switching: Change projects instantly via URL parameters
- Real-time group isolation: Each connection maintains its own data namespace
🐳 Docker & Infrastructure Improvements
- Fixed Docker networking: Set MCP server host to
0.0.0.0for proper container accessibility - Updated Neo4j: Bumped from version 5.26.0 to 5.26.2 for latest fixes
- Simplified Docker Compose: Cleaned up configuration and improved formatting
- Enhanced logging: Added detailed SSE transport logging for better debugging
📚 Documentation Consolidation & Enhancement
- Merged Cursor setup guide: Integrated
CURSOR_SETUP.mdinto mainmcp_server/README.md - 🆕 Multi-project documentation: Comprehensive guide for URL-based group switching
- Enhanced setup instructions: Step-by-step integration guide with new features
- Troubleshooting section: Included common issues and solutions
- Support links: Added GitHub issues, docs, and community channel links
🔧 Configuration Updates
- Streamlined env file handling: Simplified Docker Compose environment configuration
- Improved quote consistency: Standardized YAML formatting across Docker files
🆕 OpenRouter App Identification Details
Automatic Header Injection
When using OpenRouter (detected by openrouter.ai in base URL), the system automatically adds:
HTTP-Referer: https://github.com/getzep/graphiti
X-Title: Graphiti MCP Server
Before vs After
Before: Usage logs show "Unknown" app
Provider / Model App Tokens Cost
Gemini 2.5 Flash Unknown 1,182 $0.000501
After: Usage logs show proper identification
Provider / Model App Tokens Cost
Gemini 2.5 Flash Graphiti MCP Server 1,182 $0.000501
Technical Implementation
# Added to both OpenAIClient and OpenAIGenericClient
if config.base_url and 'openrouter.ai' in config.base_url:
default_headers.update({
'HTTP-Referer': 'https://github.com/getzep/graphiti',
'X-Title': 'Graphiti MCP Server'
})
self.client = AsyncOpenAI(
api_key=config.api_key,
base_url=config.base_url,
default_headers=default_headers if default_headers else None
)
🆕 Multi-Project Feature Details
URL-Based Group Switching
{
"mcpServers": {
"graphiti-work": {
"url": "http://localhost:8000/sse?group_id=work_projects"
},
"graphiti-personal": {
"url": "http://localhost:8000/sse?group_id=personal_coding"
},
"graphiti-client-a": {
"url": "http://localhost:8000/sse?group_id=client_a_project"
}
}
}
Technical Implementation
# New middleware for automatic group_id extraction
def get_effective_group_id(provided_group_id: str | None = None) -> str | None:
"""Get the effective group_id, prioritizing URL-based, then provided, then config default."""
if current_group_id is not None:
return current_group_id
if provided_group_id is not None:
return provided_group_id
return config.group_id
# Updated all tool functions to use effective group_id
async def add_memory(name: str, episode_body: str, group_id: str | None = None, ...):
effective_group_id = get_effective_group_id(group_id)
# ... rest of implementation
Technical Details
OpenRouter Headers Implementation
# Files modified:
# - graphiti_core/llm_client/openai_client.py
# - graphiti_core/llm_client/openai_generic_client.py
# Smart header detection and injection
default_headers = {}
if config.base_url and 'openrouter.ai' in config.base_url:
default_headers.update({
'HTTP-Referer': 'https://github.com/getzep/graphiti',
'X-Title': 'Graphiti MCP Server'
})
Docker Networking Fix
# Set host to 0.0.0.0 for Docker container accessibility
mcp.settings.host = '0.0.0.0'
Multi-Project Access Patterns
- Default:
http://localhost:8000/sse - Project A:
http://localhost:8000/sse?group_id=project_a - Project B:
http://localhost:8000/sse?group_id=project_b - Personal:
http://localhost:8000/sse?group_id=personal
Neo4j Version Update
- Updated from
neo4j:5.26.0toneo4j:5.26.2 - Maintains compatibility while getting latest bug fixes
Files Changed
graphiti_core/llm_client/openai_client.py- NEW: Added OpenRouter identification headersgraphiti_core/llm_client/openai_generic_client.py- NEW: Added OpenRouter identification headersmcp_server/graphiti_mcp_server.py- Major enhancement: Added URL-based group_id support, Docker networking, and logging improvementsmcp_server/docker-compose.yml- Neo4j update and configuration cleanupmcp_server/README.md- Comprehensive update: Multi-project setup guide and Cursor documentationmcp_server/CURSOR_SETUP.md- Removed (content merged into README)
Benefits
- ✅ 🆕 OpenRouter app identification - Proper attribution in usage logs and leaderboards
- ✅ 🆕 Seamless multi-project support - Use one server for unlimited isolated projects
- ✅ 🆕 Zero-configuration project switching - Change projects via URL parameters
- ✅ 🆕 Real-time group isolation - Instant data separation without server restarts
- ✅ 🆕 Backward compatibility - All existing configurations continue to work
- ✅ Fixed Docker container networking issues
- ✅ Updated to latest stable Neo4j version
- ✅ Single source of truth for comprehensive documentation
- ✅ Improved developer experience with better setup instructions
- ✅ Enhanced debugging with detailed logging
Testing & Validation
- [x] 🆕 Verified OpenRouter headers are properly injected and working
- [x] 🆕 Confirmed app shows as "Graphiti MCP Server" in OpenRouter logs
- [x] 🆕 Tested mixed provider setup (OpenRouter LLM + OpenAI embeddings)
- [x] Verified Docker containers start and communicate properly
- [x] Confirmed MCP server is accessible on
0.0.0.0:8000 - [x] 🆕 Tested URL-based group_id switching functionality
- [x] 🆕 Validated data isolation between different group_ids
- [x] 🆕 Confirmed Neo4j shows distinct groups:
default,project_a,project_b,personal - [x] Tested Neo4j 5.26.2 compatibility
- [x] Validated merged documentation renders correctly
- [x] 🆕 Verified no regressions in existing functionality
- [x] 🆕 All configuration tests passing (12/12)
OpenRouter Integration Verification
# Live testing shows successful API calls
2025-05-26 22:41:06,117 - httpx - INFO - HTTP Request: POST https://openrouter.ai/api/v1/chat/completions "HTTP/1.1 200 OK"
2025-05-26 22:41:06,843 - httpx - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings "HTTP/1.1 200 OK"
Database Verification
// Query to see all groups in Neo4j
MATCH (n) RETURN DISTINCT n.group_id as group_id, labels(n) as node_types, count(n) as count ORDER BY group_id
// Results show successful group isolation:
// "default", ["Episodic"], 8
// "default", ["Entity"], 43
// "personal", ["Episodic"], 1
// "personal", ["Entity"], 2
// "project_a", ["Episodic"], 1
// "project_a", ["Entity"], 1
// "project_b", ["Episodic"], 1
// "project_b", ["Entity"], 1
[!IMPORTANT] Major Enhancement: Introduces OpenRouter app identification alongside URL-based multi-project support, Docker networking fixes, Neo4j updates, and documentation consolidation.
- 🆕 OpenRouter App Identification:
- Added automatic
HTTP-RefererandX-Titleheaders for proper OpenRouter attribution- Smart detection when using
openrouter.aibase URL- App now appears as "Graphiti MCP Server" in usage logs instead of "Unknown"
- Zero configuration required - works automatically with existing OpenRouter setup
- 🆕 Multi-Project Feature:
- Added URL-based group_id switching via query parameters (e.g.,
?group_id=project_a)- Updated all MCP tool functions to use
get_effective_group_id()for consistent group handling- Added FastAPI middleware for automatic group_id extraction from URLs
- Enables seamless project isolation using a single server instance
- Docker Networking Fix:
- Set
mcp.settings.hostto0.0.0.0ingraphiti_mcp_server.pyfor Docker container accessibility- Dependency Update:
- Updated Neo4j from version
5.26.0to5.26.2indocker-compose.yml- Enhanced Documentation:
- Merged
CURSOR_SETUP.mdintoREADME.mdwith comprehensive multi-project setup guide- Added detailed examples for URL-based group switching in Cursor and Claude Desktop
- Validation:
- Confirmed OpenRouter headers working and app properly identified
- Confirmed data isolation across groups in Neo4j database
- Verified backward compatibility with existing configurations
This PR transforms the Graphiti MCP Server from a single-project tool into a powerful multi-project platform with proper OpenRouter integration, while maintaining full backward compatibility and improving the overall developer experience.
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.
I have read the CLA Document and I hereby sign the CLA
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.
I have read the CLA Document and I hereby sign the CLA
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.
I have read the CLA Document and I hereby sign the CLA
Ideally I'd split this PR into multiple feature focused ones.
I'll do next time.
PS: I'm the maintainer of this other OS project called DiffGuard. Feel free to integrate in your github actions workflow if you want
https://github.com/jonit-dev/diffguard
TLDR: You can point the PR diff to be reviewed automatically by any open router available model and scored. It can even block the PR merge if it think it has too many issues. If you don't want to spend credits, check deepseek-r1t-chimera:free model, however I'm getting good results with o4-mini
@jonit-dev Thanks for contributing. This PR covers a lot of varying ground. Would you please split it into smaller PRs that can be reviewed and merged independently?
Closing due to no response.