Project: Context Sync MCP Server Version: 2.0.0 Language: TypeScript Total Lines: ~10,897 LOC Last Updated: 2026-04-11
Context Sync is a Model Context Protocol (MCP) server that provides a local-first memory layer for AI development tools. It enables AI assistants (Claude, Cursor, VS Code Copilot, etc.) to maintain persistent context across sessions by tracking:
- Project metadata (architecture, tech stack, structure)
- Decisions (architectural, library, pattern, configuration choices)
- Conversations (tool interactions and conversations)
- Code structure (workspace organization, file trees)
- Git context (branch info, commit history, status)
- Custom context (user-provided notes, learnings, caveats)
11 AI development tools supported:
- Claude Desktop, Claude Code
- Cursor, VS Code + GitHub Copilot
- Continue.dev, Zed, Windsurf
- Codeium, TabNine
- Codex CLI, Antigravity (Google Gemini IDE)
Responsibility: MCP server implementation, tool routing, and session management
⚠️ Architectural concern: At 2,235 LOC,server.tshas grown into a God Class with five distinct responsibilities (protocol handling, tool routing, session state, shutdown logic, schema migration triggers). This violates the single-responsibility principle the Engine Pattern is designed to enforce. The schema migration trigger in particular belongs in the storage layer. Consider splitting into:server.ts(protocol only),tool-router.ts(dispatch), and lettingstorage.tsown migration triggers.
Key Components:
ContextSyncServerclass - Main MCP server orchestrator- 8 core tools exposed to AI assistants (registered in
core-tools.ts):set_project- Project initializationremember- Store contextrecall- Retrieve contextread_file- File accesssearch- Full-text searchstructure- Workspace structuregit- Git operationsnotion- Notion documentation access (if configured)
- Note:
list_mcp_resourcesis an MCP protocol handler (ListResourcesRequestSchemaatserver.ts:376), not a registered tool
Responsibilities (current — too broad):
- Handle MCP protocol requests/responses
- Route tool calls to specialized engines
- Manage session state (current project)
- Graceful shutdown handling
- Schema migration triggers
Responsibility: SQLite database abstraction and persistence
Key Components:
Storageclass - SQLite wrapper- Prepared statement caching (LRU, max 100 statements) for 2-5x performance
- Schema initialization and migration support
Database Tables:
projects
├─ id (TEXT, PK)
├─ name, path, architecture, tech_stack
└─ created_at, updated_at, is_current
conversations
├─ id (TEXT, PK)
├─ project_id (FK), tool, role, content
└─ timestamp, metadata
decisions
├─ id (TEXT, PK)
├─ project_id (FK), type, description, reasoning
└─ timestamp
project_dependencies — tracked deps (name, version, critical, dev)
project_build_system — build type, commands, config file
project_test_framework — test runner name, pattern, coverage
project_env_vars — required env vars with examples
project_services — service name, port, protocol, health check
project_databases — DB type, connection var, migrations path
project_metrics — LOC, file count, contributors, hotspots, complexity
active_work — current task, context, files, branch, status
constraints — architectural rules (key/value + reasoning)
Performance Features:
- Prepared statement caching with LRU eviction
- Indexed queries on (project_id, timestamp)
- Foreign key constraints
project-detector.ts (316 LOC)
- Detects project type (Node, Python, Rust, Go, etc.)
- Identifies tech stack from package files (package.json, Cargo.toml, pyproject.toml, etc.)
- Extracts project metadata (name, description)
- Caches detection results (3,600s / 1 hour TTL)
project-scanner.ts (193 LOC)
- Scans directory structure
- Identifies important files (.env, config files, source directories)
- Produces file tree representation
- Caches results for performance
project-analyzers.ts (466 LOC)
- Analyzes code complexity
- Detects frameworks and libraries
- Generates architecture insights
- Produces project metrics
project-cache.ts (155 LOC)
- Implements TTL-based caching (3,600s / 1 hour default)
- Reduces redundant filesystem operations
- Fast-path detection result retrieval
project-metrics.ts (128 LOC)
- Calculates project metrics (LOC, file count, contributors)
- Generates hotspot analysis
- Stores results in
project_metricstable
project-profiler.ts (161 LOC)
- Gathers comprehensive project data
- Combines scanner, analyzer, detector results
- Produces ProjectIdentity object for client
recall-engine.ts (536 LOC)
- Retrieves stored project context
- Merges multiple data sources (git, structure, storage)
- Returns formatted ContextSummary
- Implements semantic search on decisions/conversations
remember-engine.ts (597 LOC)
- Stores user-provided context
- Categorizes context types:
active_work- Current taskconstraint- Architectural constraintsproblem- Known issues/blockersgoal- Project targetsdecision- Made choices with reasoningnote- Important informationcaveat- AI mistakes/workarounds/technical debt
- Validates metadata for caveat entries
- Stores in database with timestamps
search-engine.ts (455 LOC)
- Full-text search across conversations and decisions
- Boolean operators (AND, OR, NOT)
- Regex pattern support
- Configurable result limits
read-file-engine.ts (368 LOC)
- Safe file reading with size limits
- Binary file detection
- Syntax highlighting metadata
- Line offset/limit support
- Encoding detection
structure-engine.ts (555 LOC)
- Generates workspace file tree
- Excludes common ignore patterns (.git, node_modules, etc.)
- Provides depth-limited traversal
- File type categorization
git-integration.ts (629 LOC)
- Core git operations wrapper
- Status checking (modified, staged, untracked files)
- Branch information retrieval
- Commit history access
- Tag listing
git-status-engine.ts (385 LOC)
- Comprehensive git status analysis
- Tracks ahead/behind with remote
- Generates git status context
- Detects uncommitted changes
git-context-engine.ts (322 LOC)
- Retrieves git-specific context
- Branch information and recent commits
- Repository state summary
- Useful for recall operations
git-hook-manager.ts (424 LOC)
- Installs post-commit, pre-push, post-merge, post-checkout hooks
- Backs up existing hooks
- Marks auto-hooks for safe removal
- Triggers context updates on git events
notion-integration.ts (544 LOC)
- Notion API client wrapper
- Page search and read operations (exposed via MCP tool)
- Page creation, update, query (implemented but not exposed via MCP tool)
- Database operations
- Token management
notion-handlers.ts (269 LOC)
- MCP request handlers for Notion operations
- Tool implementations for search/read (the only actions exposed via the
notionMCP tool) - Authentication and error handling
types.ts (61 LOC)
- Core type definitions
- Interfaces: ProjectContext, Conversation, Decision, ContextSummary
- StorageInterface definition
schema.ts (228 LOC)
- Database schema definitions
- Current schema version tracking
- Migration helper functions
schema-migration.ts (479 LOC)
- v0 → v1 schema migration
- Safe migration with backup
- Version tracking in database
path-normalizer.ts (127 LOC)
- Cross-platform path normalization
- Windows/Mac/Linux compatibility
- Path resolution helpers
workspace-detector.ts (453 LOC)
- Detects workspace boundaries
- Identifies project roots
- Handles monorepos
- File watching via chokidar for change detection
- Caches detection results
context-layers.ts (109 LOC)
- Type definitions for ProjectIdentity
- RememberInput type
- RecallResult structure
AI Tool Request
↓
Server (route to set_project)
↓
ProjectDetector → detect tech stack + architecture
↓
ProjectScanner → scan file structure
↓
ProjectAnalyzer → analyze complexity
↓
Storage → save ProjectContext
↓
GitHookManager → install hooks
↓
Response with ProjectIdentity
AI Tool Request (remember: { type, content, metadata })
↓
RememberEngine → validate input
↓
Storage → create Decision/note in DB
↓
Git context captured (if git repo)
↓
Response with saved context ID
AI Tool Request (recall)
↓
RecallEngine → query Storage
↓
GitStatusEngine → get git status
↓
SearchEngine → find recent decisions/conversations
↓
StructureEngine → get workspace tree
↓
Merge all data → ContextSummary
↓
Response with complete context
Each major feature (Git, Project Analysis, File Reading) has a dedicated Engine class:
- Single responsibility
- Testable in isolation
- Composable
- Cacheable
StorageInterface defines contract, Storage class implements SQLite backend:
- Prepared statement caching for performance
- LRU eviction prevents memory bloat
⚠️ Abstraction boundary is leaky: The claim that the storage layer "could be swapped for PostgreSQL, MongoDB, etc." is overstated.schema-migration.ts(479 LOC) andschema.tscontain SQLite-specific DDL, migration logic, and version-tracking queries. These are tightly coupled to SQLite semantics and would require significant rework to swap backends. The interface defines the contract correctly, but the implementation details bleed into the migration layer.
ContextSyncServer creates and composes all engines:
- Central orchestration point
- Dependency injection friendly
- Single point of initialization
Multiple levels:
- ProjectCache (3,600s / 1 hour TTL) - Detection results
- Prepared statements (LRU, 100 max) - SQL queries
- Git hook detection - Prevents repeated hook installs
⚠️ TTL is hardcoded, not configurable. The 3,600s (1 hour) TTL appears inproject-detector.tsandproject-cache.tsas a fixed constant (60 * 60 * 1000). There is no environment variable, config file option, or API to adjust it. For actively-changing projects (where 1 hour of stale detection can cause confusion) or use cases that require frequent re-scanning, this is a usability gap.CONTEXT_SYNC_CACHE_TTLshould be exposed as a configuration option.
Graceful degradation:
- Missing Notion config → Notion features disabled
- Non-git projects → git tools return null
- Missing files → return null vs throw
- Notion API errors → logged, not fatal
| Library | Version | Purpose | Alternative for Rust |
|---|---|---|---|
@modelcontextprotocol/sdk |
^0.5.0 | MCP protocol | N/A (Anthropic official) |
better-sqlite3 |
^11.0.0 | Embedded SQL database | rusqlite or sqlx |
@notionhq/client |
^5.4.0 | Notion API | notion_sdk_rs |
simple-git |
^3.30.0 | Git wrapper | git2-rs |
chokidar |
^4.0.3 | File watching | notify |
commander |
^11.0.5 | CLI argument parsing | clap |
js-yaml |
^4.1.1 | YAML parsing | serde_yaml |
@iarna/toml |
^2.2.5 | TOML parsing | toml |
readline-sync |
^1.4.10 | Interactive CLI | rustyline |
- File System - Reading, watching, traversing
- Git - Via subprocess calls to git CLI
- SQLite - Embedded database
- Notion API - HTTP/HTTPS REST API
- Process Signals - SIGINT, SIGTERM handling
-
Global NPM:
npm install -g @context-sync/server- Auto-config runs on install
- Installs git hooks automatically
-
Local Development:
npm install+ manual setupnpm run dev- Run with tsxnpm run build- Compile to dist/
~/.context-sync/
├── data.db # SQLite database (user context)
├── config.json # Settings (Notion token, custom paths)
└── install-status.json # Installation metadata
CONTEXT_SYNC_DB_PATH- Custom database locationNOTION_API_KEY- Notion authentication (stored in config.json)
When installed globally:
preinstallhook logs friendly messagepostinstallhook runs setup (bin/install.cjs)- Auto-detects AI tool configuration directories:
- Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) - Cursor:
~/.cursor/mcp.json - VS Code + GitHub Copilot:
~/Library/Application Support/Code/User/mcp.json(macOS) - Continue.dev:
.continue/mcpServers/context-sync.yaml - Zed:
~/Library/Application Support/Zed/settings.json(macOS) - Windsurf:
~/.codeium/windsurf/mcp_config.json - Codeium:
~/Library/Application Support/Code/User/settings.json(macOS) - TabNine:
~/Library/Application Support/TabNine/config.json(macOS) - Codex CLI:
~/.codex/config.toml - Claude Code:
~/.claude/mcp_servers.json - Antigravity:
~/.gemini/antigravity/mcp_config.json
- Claude Desktop:
- Creates/updates MCP configuration
- Installs git hooks on project setup
- Project detection: ~200-500ms (filesystem scan)
- Prepared statement reuse: 2-5x faster queries
- Caching (3,600s / 1 hour TTL): Near-instant on cache hit
- Typical: 40-60MB (Node process)
- Prepared statements cache: Max ~2MB (100 statements)
- Large projects: ~100-200MB depending on codebase size
- Project size: Tested up to 50K files (works)
- Database size: SQLite can handle GB-scale databases
- Concurrent connections: Single-threaded (Node.js runtime limitation — not an MCP protocol requirement; a Rust or Go implementation of the same MCP server would not have this constraint)
- File paths validated before reading
- Database inputs parameterized (SQL injection prevention)
- Notion token stored in user's home directory (not in git)
- SQLite database stored in
~/.context-sync/(user-only permissions) - Notion token in
config.json— plaintext API token on the filesystem⚠️ - Risk: dotfile sync tools (Mackup, chezmoi, Dropbox), shared machines, or backup services can expose the token
- Mitigation options: use OS keychain (macOS Keychain, libsecret on Linux), or prompt for token per-session via environment variable
- Current behavior is functional but not suitable for shared or managed machines
- No data sent to external services without explicit user action
- Marked with "Context Sync Auto-Hook" comment
- Existing hooks backed up before installation
- Can be safely removed
- No automated test suite
- Manual testing via
npm test(placeholder) - Manually verified across 14 AI tool configurations during development; no automated cross-platform test harness exists
- TypeScript strict mode enabled
- TSLint/ESLint not configured
- Type safety throughout
- Prepared for schema migrations
- Main:
dist/index.js(compiled entry point) - Types:
dist/index.d.ts(TypeScript definitions) - CLI:
bin/setup.cjs(Notion configuration wizard) - Platform Support: darwin (x64, arm64), linux (x64, arm64), win32 (x64)
- Semantic versioning (currently 2.0.0)
- GitHub releases automated
prepublishOnlyhook:npm run build && npm test- Published to npm registry as
@context-sync/server - Distributed as binary + source
- No test suite - Manual testing only; this is the highest-priority gap — it blocks safe refactoring, confident releases, and any future Rust migration validation
- Single-threaded - Node.js runtime limitation (not an MCP constraint; other runtimes could serve concurrent requests)
- SQLite only - Migration layer is SQLite-specific despite the
StorageInterfaceabstraction - Git subprocess calls - Each git operation spawns a child process;
git2-rs(libgit2 binding) or a native Node.js git library would reduce this overhead - No query language - Basic keyword/regex search only; no structured query or relevance ranking
- Hardcoded cache TTL - 3,600s (1 hour) fixed; not configurable via env var or config file
- No ESLint/TSLint - Code style not enforced; formatting and lint errors possible
- Plaintext token storage - Notion API key stored in
config.json; no OS keychain integration
Listed in priority order (see also: Conclusion for gap analysis):
- Add comprehensive integration test suite (unblocks all refactoring and migration)
- Extract tool-router and migration trigger out of
server.ts(reduces God Class) - Expose
CONTEXT_SYNC_CACHE_TTLas an environment variable or config option - Add ESLint with recommended TypeScript rules
- Investigate OS keychain integration for Notion token storage
- Optimize git operations (native libgit2 binding vs subprocess calls)
src/
├── index.ts # Entry point
├── server.ts # MCP server orchestrator (2.2K LOC)
├── types.ts # Core type definitions
│
├── STORAGE LAYER
├── storage.ts # SQLite abstraction
├── schema.ts # Schema definitions
├── schema-migration.ts # v0→v1 migration
│
├── PROJECT MANAGEMENT
├── project-detector.ts # Tech stack detection
├── project-scanner.ts # Directory scanning
├── project-analyzers.ts # Code analysis
├── project-cache.ts # Detection caching
├── project-profiler.ts # Comprehensive profiling
├── project-metrics.ts # Metrics calculation
│
├── CONTEXT ENGINES
├── recall-engine.ts # Context retrieval (536 LOC)
├── remember-engine.ts # Context storage (597 LOC)
├── search-engine.ts # Full-text search
├── read-file-engine.ts # Safe file reading
├── structure-engine.ts # Workspace structure
│
├── GIT INTEGRATION
├── git-integration.ts # Git operations (629 LOC)
├── git-status-engine.ts # Status analysis
├── git-context-engine.ts # Git context retrieval
├── git-hook-manager.ts # Hook management (424 LOC)
│
├── NOTION INTEGRATION
├── notion-integration.ts # Notion API wrapper (544 LOC)
├── notion-handlers.ts # MCP request handlers
│
├── UTILITIES
├── path-normalizer.ts # Cross-platform paths
├── workspace-detector.ts # Workspace detection
├── context-layers.ts # Type definitions
│
└── CONTEXT MANAGEMENT
└── core-tools.ts # Tool definitions (300 LOC)
Context Sync is a modular MCP server with reasonable separation of concerns at the engine level. It integrates with 11 AI development tools and provides a working foundation for persistent context management. The Engine pattern gives individual components testability and replaceability in principle.
What's working well:
- ✅ Comprehensive graceful degradation (missing config → features disabled, not crashed)
- ✅ Multi-platform support (darwin, linux, win32)
- ✅ Auto-configuration system reduces setup friction
- ✅ Performance-conscious design (LRU statement cache, TTL-based detection cache)
- ✅ Parameterized SQL throughout (no injection risk)
What needs addressing before calling this production-ready:
- 🔴 No automated test suite — the single most important gap; refactoring and migration are unsafe without it
- 🔴
server.tsis a God Class (2,235 LOC, five responsibilities) — contradicts the Engine Pattern design ⚠️ Storage abstraction overstated —schema-migration.tsis SQLite-specific and would not swap cleanly⚠️ Hardcoded cache TTL — 3,600s (1 hour) not configurable⚠️ Plaintext Notion token — no OS keychain integration⚠️ No linter configured — ESLint/TSLint absent despite TypeScript strict mode
Priority order for improvements:
- Add integration test suite (unblocks everything else)
- Extract tool-router and migration trigger out of
server.ts - Expose
CONTEXT_SYNC_CACHE_TTLas a configuration option - Add ESLint with recommended TypeScript rules
- Investigate OS keychain for token storage
Date Created: 2026-02-23 Review Status: Architecture Analysis + Critical Review (2026-02-24), Consistency Audit fixes (2026-04-11) Next Steps: See RUST-MIGRATION-ASSESSMENT.md for migration feasibility analysis