1. Getting Started
What is Sulci?
Sulci is a universal AI context layer. It captures knowledge from every AI interaction you have — across ChatGPT, Claude, Gemini, Perplexity, Cursor, and more — then stores it as structured knowledge atoms and surfaces relevant context wherever you need it.
Think of it as a shared brain for all your AI tools. Instead of re-explaining your project, preferences, and decisions to each tool separately, Sulci remembers everything and injects the right context automatically.
Quick start: The fastest way to get started is (1) install the MCP server for Claude Code or Cursor, (2) install the Chrome extension, and (3) start using your AI tools normally. Sulci captures and connects knowledge in the background.
How it works
- Capture — Sulci passively captures knowledge from your AI conversations via the Chrome extension, MCP server, or REST API.
- Extract — An LLM pipeline extracts structured knowledge atoms: facts, decisions, preferences, entities, and relationships.
- Store — Atoms are stored with vector embeddings, confidence scores, and source tracking in a local SQLite database or cloud.
- Surface — When you start a new conversation, Sulci queries your knowledge base and injects relevant context automatically.
Architecture overview
Sulci is a monorepo with these components:
- Core library (
packages/core/) — Models, storage, LLM extraction, scoring, conflict detection - REST API (
apps/api/) — FastAPI server on port 8080 - MCP server (
apps/mcp-server/) — For Claude Code, Cursor, and other MCP clients - Chrome extension (
extensions/chrome/) — Passive capture + context injection - Dashboard (
apps/dashboard/) — React knowledge explorer (Sulci Cortex) - API proxy (
apps/proxy/) — Transparent context injection for any API
2. Installation
MCP server (Claude Code)
Add the following to your ~/.claude/claude_code_config.json (or project-level .claude/claude_code_config.json):
{
"mcpServers": {
"sulci": {
"command": "/bin/sh",
"args": ["-c", "uvx sulci-mcp"],
"env": {
"SULCI_API_URL": "http://localhost:8080",
"SULCI_API_KEY": "your-api-key"
}
}
}
}
For Sulci Cloud, replace the env values:
"env": {
"SULCI_API_URL": "https://app.sulci.xyz",
"SULCI_API_KEY": "your-cloud-token"
}
macOS note: When Claude Desktop or Cursor first launches the MCP server, macOS may prompt you to allow uvx to access files. Click Allow for the server to start.
MCP server (Cursor)
Add to your Cursor MCP settings (.cursor/mcp.json):
{
"mcpServers": {
"sulci": {
"command": "/bin/sh",
"args": ["-c", "uvx sulci-mcp"],
"env": {
"SULCI_API_URL": "http://localhost:8080",
"SULCI_API_KEY": "your-api-key"
}
}
}
}
Chrome extension
- Download or clone the Sulci repository
- Open
chrome://extensionsin Chrome - Enable Developer mode (top right toggle)
- Click Load unpacked and select the
extensions/chrome/directory - Click the Sulci icon in your toolbar to configure Cloud or Self-hosted mode
Self-hosted server (Docker)
# Clone the repo
git clone https://github.com/jaimelopez89/sulci.git
cd sulci
# Start with Docker Compose
docker compose up -d
# The API runs on http://localhost:8080
# The dashboard runs on http://localhost:3000
Self-hosted server (from source)
# Install dependencies
make setup
# Seed demo data (optional)
make seed
# Start the API
make dev-api
# Start the dashboard (separate terminal)
make dev-dashboard
Cloud
Sign up at app.sulci.xyz to use the hosted version. No installation required — just connect your tools using the onboarding wizard.
3. Core Concepts
Knowledge atoms
A knowledge atom is the fundamental unit in Sulci. Each atom represents a single piece of knowledge extracted from a conversation, such as:
- Fact — "The project uses PostgreSQL 16 with pgvector"
- Decision — "We chose JWT over session-based auth for the API"
- Preference — "Always use TypeScript strict mode"
- Entity — "Sulci is a universal AI context layer"
- Relationship — "The API server depends on the core library"
- Context — "Current sprint focuses on Chrome extension features"
- Instruction — "Never commit .env files to git"
Each atom has:
| Field | Description |
|---|---|
content | Human-readable text describing the knowledge |
atom_type | One of: fact, decision, preference, entity, relationship, context, instruction |
subject | Main entity or topic (optional) |
predicate | Property or relationship (optional) |
object_value | Value or target (optional) |
confidence | Score from 0–1 indicating reliability |
source | Which tool captured this atom |
projects | Project scoping (auto-detected from working directory) |
flags | Semantic flags: CORE, DECISION, TECHNICAL, PREFERENCE (optional, can be combined) |
importance | Priority score 0–1. Auto-derived from type and flags. Atoms ≥ 0.75 are always injected as Core Knowledge. |
valid_until | ISO 8601 datetime after which the atom is considered expired and excluded from context |
supersedes_id | ID of an older atom this one replaces. The older atom is automatically expired on save. |
Projects
Knowledge atoms are scoped to projects. When you use an MCP-connected tool like Claude Code, the project is automatically detected from your working directory. This keeps knowledge from different codebases separate.
Global atoms (not scoped to any project) are available everywhere. You can move atoms between projects or make them global from the dashboard.
Confidence scoring
Each atom has a confidence score (0–1) that reflects how reliable the knowledge is. Confidence is influenced by:
- Source reliability — Direct user statements score higher than inferred context
- Verification — Verified atoms get a confidence boost
- Freshness — Recent atoms are weighted slightly higher
- Corroboration — Knowledge confirmed across multiple conversations scores higher
Conflict detection
Sulci automatically detects when new knowledge contradicts existing atoms. For example, if you previously decided to use REST but later discuss switching to GraphQL, Sulci flags this as a conflict. You can resolve conflicts from the dashboard or API.
Verification
Atoms that haven’t been verified or whose verification has expired appear in the verification queue. Periodically reviewing and confirming knowledge keeps your context accurate.
4. MCP Server
The MCP (Model Context Protocol) server exposes Sulci’s knowledge base to AI coding assistants like Claude Code and Cursor. It runs via stdio transport and is launched automatically by your editor.
Available tools
| Tool | Description |
|---|---|
query_context | Search for relevant knowledge atoms by natural language query |
add_knowledge | Store a new knowledge atom |
list_knowledge | Browse stored atoms with optional type/project filters |
list_projects | List all projects with atom counts |
list_conflicts | View knowledge conflicts needing resolution |
resolve_conflict | Resolve a conflict by choosing a winner |
verification_queue | Get atoms that need verification |
record_interaction | Record a conversation and extract atoms |
delete_knowledge | Delete a knowledge atom by ID |
Integration tools
When integrations are connected (Google Calendar, Slack, Google Docs), additional tools become available:
| Tool | Description |
|---|---|
calendar_today | Get today’s calendar events |
calendar_list_events | List upcoming events (up to 30 days) |
calendar_create_event | Create a new calendar event |
slack_list_channels | List accessible Slack channels |
slack_search_messages | Search Slack messages |
slack_post_message | Post a message to a Slack channel |
gdocs_search | Search Google Docs by title |
gdocs_read | Read a Google Doc’s content |
gdocs_create | Create a new Google Doc |
Usage with Claude Code
Once configured, the MCP server loads automatically when Claude Code starts. You’ll see Sulci tools listed when you type /mcp. Claude will automatically use query_context to retrieve relevant knowledge when it seems useful.
You can also explicitly ask Claude to save knowledge:
"Remember that we always use Bun instead of npm for this project"
Environment variables
| Variable | Default | Description |
|---|---|---|
SULCI_API_URL | http://localhost:8080 | Sulci API endpoint |
SULCI_API_KEY | — | API key or cloud auth token |
5. Chrome Extension
The Chrome extension provides two key features:
- Passive capture — Automatically captures knowledge from AI conversations
- Context injection — Queries Sulci and prepends relevant context to your messages before sending
Supported sites
- ChatGPT (chatgpt.com)
- Claude (claude.ai)
- Gemini (gemini.google.com)
- Perplexity (perplexity.ai)
Cloud vs self-hosted
Click the Sulci icon in your Chrome toolbar to choose between:
- Cloud mode — Sign in with your app.sulci.xyz account (Google or email/password). Supports multiple accounts.
- Self-hosted mode — Enter your server URL and API key to connect to a local Sulci instance.
Context injection
When enabled (default), the extension intercepts your message before sending and queries the Sulci API for relevant knowledge. If relevant atoms are found, a context block is prepended to your message:
---
[Sulci Context] Based on your knowledge base:
• The project uses PostgreSQL 16 with pgvector
• Authentication is handled via Supabase JWT
• Always use TypeScript strict mode
---
Your original message here...
You can toggle context injection on/off from the extension popup. Messages shorter than 20 characters are skipped automatically.
Note: Context injection requires an active API connection (cloud or self-hosted). A small feedback pill appears briefly when atoms are injected.
Capture toggles
You can enable or disable capture for each site individually from the extension popup. This is useful if you want to capture from ChatGPT but not from Claude, for example.
6. REST API
The REST API runs on port 8080 and provides full access to Sulci’s functionality.
Authentication
Two authentication modes:
- API key (self-hosted) — Set
SULCI_API_KEYenv var, then passAuthorization: Bearer <key>header - Supabase JWT (cloud) — Pass the Supabase access token as
Authorization: Bearer <jwt>. Tokens are obtained via the auth flow.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v1/health | Health check |
GET | /api/v1/stats | Usage statistics |
POST | /api/v1/context | Query relevant context for a given text |
GET | /api/v1/knowledge | List knowledge atoms (with filters) |
POST | /api/v1/knowledge | Create a new knowledge atom |
DELETE | /api/v1/knowledge/{id} | Delete a knowledge atom |
POST | /api/v1/interactions | Record a conversation and extract atoms |
GET | /api/v1/projects | List projects |
PUT | /api/v1/projects/{name} | Rename a project |
GET | /api/v1/conflicts | List knowledge conflicts |
POST | /api/v1/conflicts/{id}/resolve | Resolve a conflict |
GET | /api/v1/verification/queue | Get atoms needing verification |
Context query
POST /api/v1/context
Content-Type: application/json
Authorization: Bearer <token>
{
"query": "How is authentication handled?",
"top_k": 5
}
Returns relevant knowledge atoms ranked by a composite relevance score:
relevance = 0.5 × vector_similarity
+ 0.2 × freshness
+ 0.15 × confidence
+ 0.15 × frequency
Recording interactions
POST /api/v1/interactions
Content-Type: application/json
{
"source_tool": "chatgpt_extension",
"messages": [
{ "role": "user", "content": "How should we handle caching?" },
{ "role": "assistant", "content": "I recommend using Redis..." }
],
"metadata": { "captured_by": "chrome_extension" }
}
7. Dashboard (Cortex)
The Sulci Cortex dashboard is a React application that provides a visual interface for managing your knowledge base. It runs on port 3000 locally or is available at app.sulci.xyz for cloud users.
Knowledge explorer
Browse, search, and filter your knowledge atoms. View them as a list or as a knowledge graph showing relationships between entities.
Conflict resolution
When Sulci detects contradictory atoms, they appear in the conflicts panel. Choose which atom to keep — the other is deactivated but not deleted.
Integrations
Connect Google Calendar, Slack, and Google Docs from the Settings page. Once connected, your AI tools can read and write to these services via the MCP server.
Onboarding wizard
First-time users see an onboarding wizard that guides through:
- Choosing Cloud or Local mode
- Connecting your first AI tool (MCP config or Chrome extension)
- Verifying the connection works
Branding
The dashboard displays as Sulci Cortex with a mode badge:
- Sulci Local — Purple/indigo theme for self-hosted
- Sulci Cloud — Sky-blue theme for cloud users
8. Integrations
Google Calendar
Connect Google Calendar to let your AI tools see your schedule. Requires Google OAuth setup with the following scopes:
https://www.googleapis.com/auth/calendar.readonlyhttps://www.googleapis.com/auth/calendar.events
Google Docs
Search, read, and create Google Docs. Requires:
https://www.googleapis.com/auth/documentshttps://www.googleapis.com/auth/drive.readonly
Slack
Search messages, list channels, and post messages to Slack. Requires a Slack app with:
channels:readchat:writesearch:read
OAuth setup (cloud)
For Sulci Cloud, integrations are connected via the dashboard Settings page. Click “Connect” next to each service, authorize in the popup, and you’re done.
OAuth setup (self-hosted)
For self-hosted, you need to create OAuth credentials in the Google Cloud Console and Slack API dashboard, then set the following environment variables:
# Google integrations
SULCI_GOOGLE_CLIENT_ID=your-client-id
SULCI_GOOGLE_CLIENT_SECRET=your-client-secret
# Slack integration
SULCI_SLACK_CLIENT_ID=your-slack-client-id
SULCI_SLACK_CLIENT_SECRET=your-slack-client-secret
9. Configuration Reference
All Sulci configuration uses environment variables with the SULCI_ prefix.
Core settings
| Variable | Default | Description |
|---|---|---|
SULCI_API_KEY | — | API key for authentication (single-tenant mode) |
SULCI_DB_PATH | sulci.db | Path to the SQLite database file |
SULCI_MULTI_TENANT | false | Enable multi-tenant mode with Supabase JWT auth |
SULCI_LLM_PROVIDER | openai | LLM provider for extraction (openai, anthropic, local) |
SULCI_LLM_MODEL | — | Specific model to use for extraction |
OPENAI_API_KEY | — | OpenAI API key (for extraction and embeddings) |
Multi-tenant / Cloud settings
| Variable | Description |
|---|---|
SUPABASE_JWT_SECRET | Supabase JWT signing secret (for HS256) |
SUPABASE_URL | Supabase project URL |
SUPABASE_ANON_KEY | Supabase anonymous key |
VITE_SUPABASE_URL | Supabase URL for the dashboard frontend |
VITE_SUPABASE_ANON_KEY | Supabase anon key for the dashboard frontend |
Integration credentials
| Variable | Description |
|---|---|
SULCI_GOOGLE_CLIENT_ID | Google OAuth client ID |
SULCI_GOOGLE_CLIENT_SECRET | Google OAuth client secret |
SULCI_SLACK_CLIENT_ID | Slack app client ID |
SULCI_SLACK_CLIENT_SECRET | Slack app client secret |
Docker Compose
The docker-compose.yml at the project root starts the API, dashboard, and proxy:
# Start all services
docker compose up -d
# View logs
docker compose logs -f api
# Stop
docker compose down
For cloud deployment, a railway.toml is provided with build and start commands configured for Railway.
MCP JSON config examples
Claude Code (~/.claude/claude_code_config.json):
{
"mcpServers": {
"sulci": {
"command": "/bin/sh",
"args": ["-c", "uvx sulci-mcp"],
"env": {
"SULCI_API_URL": "http://localhost:8080",
"SULCI_API_KEY": "your-key"
}
}
}
}
Cursor (.cursor/mcp.json):
{
"mcpServers": {
"sulci": {
"command": "/bin/sh",
"args": ["-c", "uvx sulci-mcp"],
"env": {
"SULCI_API_URL": "http://localhost:8080",
"SULCI_API_KEY": "your-key"
}
}
}
}
10. Semantic Flags & Importance
What are semantic flags?
Flags are orthogonal labels that describe the nature of a knowledge atom, independent of its type. Any atom can carry zero or more flags:
| Flag | Meaning | Default importance |
|---|---|---|
CORE | Always-relevant foundational knowledge | 0.9 |
DECISION | An architectural or design decision | 0.85 |
TECHNICAL | Technical implementation detail | 0.75 |
PREFERENCE | User or team coding preference | 0.8 |
The LLM extractor assigns flags automatically based on content. You can also set them manually via the dashboard or API.
Importance scoring
Every atom has an importance score between 0.0 and 1.0. The default is 0.5. Importance is auto-derived from the atom type and flags at creation time:
- instruction type → 0.9
COREorDECISIONflags → 0.9 / 0.85PREFERENCEflag → 0.8TECHNICALflag → 0.75- All other atoms → 0.5
You can always override the score manually. The value must be between 0 and 1 (inclusive).
Tiered context injection (L1 / L2)
Context injection uses a two-tier model:
- L1 — Core Knowledge: atoms with
importance ≥ 0.75are always prepended to context, regardless of query similarity. They appear under a “Core knowledge (always relevant)” header. - L2 — Query-Matched: remaining atoms are retrieved by vector similarity to the current query. They appear under a “Query-matched context” header.
This guarantees that critical facts (architecture decisions, coding standards, hard constraints) are never absent from a conversation, even when the query doesn’t closely match their content.
Tip: Use the dashboard Context Sandbox to preview exactly which atoms would be injected for any query, with Core and Query-Matched sections shown separately.
Setting flags via the API
POST /api/v1/knowledge
Content-Type: application/json
{
"atom_type": "decision",
"content": "We use Bun instead of npm for all JS tooling in this project",
"flags": ["CORE", "DECISION"],
"importance": 0.9,
"projects": ["my-project"]
}
11. Temporal Validity & Supersession
Expiring atoms
Set a valid_until field (ISO 8601 datetime) on any atom to mark it as time-limited. Once the current time passes valid_until, the atom is considered expired and is automatically excluded from:
- Context queries (
/api/v1/context) - MCP
query_contexttool - Chrome extension context injection
- VS Code / Cursor sidebar results
Expired atoms are not deleted — they remain in the database and are visible in the dashboard (shown with strikethrough). You can revive them by clearing or extending valid_until.
Good uses for expiry
- Sprint goals and deadlines (“Current sprint ends 2026-04-30”)
- Temporary architectural decisions (“Using feature flag X until Q2 cleanup”)
- Meeting context (“Presenting Atlas demo on Friday”)
- Time-boxed constraints (“No DB migrations until the release freeze lifts”)
POST /api/v1/knowledge
{
"atom_type": "context",
"content": "Current sprint goal: ship the Stripe integration before 2026-04-30",
"valid_until": "2026-04-30T23:59:59Z"
}
Superseding atoms
When a decision changes, create a new atom and set supersedes_id to the ID of the outdated atom. Sulci will automatically set valid_until = now() on the old atom, effectively retiring it.
POST /api/v1/knowledge
{
"atom_type": "decision",
"content": "Migrated from RabbitMQ to Kafka for the event bus",
"supersedes_id": "atom_abc123",
"flags": ["DECISION"],
"importance": 0.9
}
The old “Using RabbitMQ” atom is expired immediately. Future context queries only return the new Kafka atom. No contradictions, no manual cleanup needed.
Note: The supersession chain is visible in the Sulci Cortex dashboard knowledge graph as temporal edges, so you can trace the history of any decision.