Scoped Environments
Scopes let you maintain separate indexed snapshots of your projects per environment. Index your develop branches into one scope, prod into another, and query them independently through the MCP server.
Why Scopes
Without scopes, kc-graph init creates one graph per project. When you switch branches and sync, the graph overwrites. With scopes, each environment gets its own isolated storage:
# Index the same project under two scopes
git checkout develop
kc-graph init --global --scope develop
git checkout main
kc-graph init --global --scope prodNow you have two independent graphs for the same project. The AI connected to the develop scope sees only develop code. No cross-contamination.
Quick Start
# Set your active scope
kc-graph scope use develop
# Index projects (scope is inherited from active scope)
kc-graph init --global ~/work/api-gateway
kc-graph init --global ~/work/auth-service
kc-graph init --global ~/work/web-app
# Start MCP server for this scope
kc-graph mcp --globalOr pass --scope explicitly on each command:
kc-graph init --global --scope develop ~/work/api-gateway
kc-graph mcp --global --scope developConfigure Claude Code:
claude mcp add kc-graph -- kc-graph mcp --global --scope developScope Resolution
When you run any command, kc-graph determines the scope using this priority:
| Priority | Source | Example |
|---|---|---|
| 1 (highest) | --scope flag | kc-graph sync --scope prod |
| 2 | KC_GRAPH_SCOPE env var | KC_GRAPH_SCOPE=staging kc-graph sync |
| 3 | Active scope in config.json | Set via kc-graph scope use develop |
| 4 (lowest) | Default | "default" |
If you never use --scope and never set an active scope, everything goes into the default scope. This is identical to how kc-graph worked before scopes existed.
Managing Scopes
Show active scope
kc-graph scope
# Active scope: developSet active scope
kc-graph scope use develop
# Active scope set to: developAll subsequent commands use develop unless overridden with --scope.
Reset to default
kc-graph scope reset
# Active scope reset to: defaultOr equivalently:
kc-graph scope use defaultList scopes
kc-graph scope list --globalOutput:
SCOPE PROJECTS LAST SYNC
* develop 5 10m ago
staging 3 1d ago
default 5 2h ago* marks the active scope.
Without --global, lists local scopes in the current project's .kc-graph/.
Delete a scope
kc-graph scope delete staging --global --force
# Scope 'staging' deleted.--force is required to confirm deletion. The default scope cannot be deleted.
Scope Naming
Scope names must:
- Start with a lowercase letter
- Contain only lowercase letters, numbers, and hyphens
- Be 1-50 characters
Valid: develop, prod, feature-x, release-v2
Invalid: Develop, my_scope, 2024-release, my scope
Storage Layout
Each scope is a self-contained directory:
~/.kc-graph/ # global root
config.json # { "activeScope": "develop" }
default/
scope.json
registry.json
projects/<id>/chunks/...
develop/
scope.json
registry.json
projects/<id>/chunks/...Local storage follows the same pattern:
.kc-graph/
default/
scope.json
meta.json, map.json, chunks/
develop/
scope.json
meta.json, map.json, chunks/Scope + Global/Local Matrix
Scopes work with both local and global storage:
| Command | Storage Location |
|---|---|
kc-graph init | .kc-graph/default/ |
kc-graph init --scope develop | .kc-graph/develop/ |
kc-graph init --global | ~/.kc-graph/default/projects/<id>/ |
kc-graph init --global --scope develop | ~/.kc-graph/develop/projects/<id>/ |
Same for sync, mcp, view, watch, status, setup.
Strict Isolation
Scopes are strictly isolated. An MCP server running under develop scope has zero visibility into default or any other scope. No fallback, no mixing.
# This MCP server ONLY sees projects indexed under 'develop'
kc-graph mcp --global --scope developIf a project exists in default but not in develop, it simply doesn't exist for that MCP server.
Bulk Sync
Sync all projects in a scope at once without specifying paths:
# Sync all globally registered projects in the active scope
kc-graph sync --global
# Sync all projects in a specific scope
kc-graph sync --global --scope developOutput:
[scope: develop] Syncing 5 projects...
[scope: develop] api-gateway: +2, ~1
[scope: develop] auth-service: up to date
[scope: develop] payment-service: ~3
[scope: develop] web-app: +1
[scope: develop] admin-panel: up to date
[scope: develop] Done. +3 added, ~4 updated, -0 removedTo sync a single project, pass the path:
kc-graph sync --global --scope develop ~/work/api-gatewayBranch Safety
When you index a project, kc-graph records the current git branch. On sync, if the branch has changed, you get a warning:
Warning: api-gateway was indexed on 'develop' but is currently on 'main'
Use --force to sync anyway, or switch to 'develop' first.This prevents accidentally indexing the wrong branch into a scope. Use --force to override:
kc-graph sync --global --scope develop --forceNon-git projects skip this check entirely.
Output Prefix
When using a non-default scope, all command output is prefixed with the scope name:
[scope: develop] Indexing ~/work/api-gateway ...
[scope: develop] Done in 1.2sWhen the scope is default, no prefix is shown. This way existing output is unchanged for users who don't use scopes.
Environment Variable
Set KC_GRAPH_SCOPE to override the active scope for a session or in CI:
export KC_GRAPH_SCOPE=staging
kc-graph sync --global # uses 'staging' scope
kc-graph mcp --global # serves 'staging' scope--scope flag still takes highest priority if both are set.
Viewing Scoped Graphs
View a single project:
kc-graph view --scope developView all projects in a scope with a project switcher dropdown:
kc-graph view --global --scope developThe viewer loads the first project and shows a dropdown in the sidebar to switch between projects. Switching fetches the graph on demand — no page reload needed.
Removing Projects
Remove a project's indexed data from a scope:
# Remove local project
kc-graph remove --force
# Remove a specific global project
kc-graph remove ~/work/api-gateway --global --scope develop --force
# Remove entire scope (all projects)
kc-graph scope delete develop --global --force--force is required for both commands.
Static MCP Mode
If your indexed projects are stable and won't change, disable the auto-reload check for zero overhead:
kc-graph mcp --global --no-reloadThe MCP server loads graphs once at startup and never checks for updates. Use this in CI or when serving a fixed snapshot.
Programmatic API
All scope functions are exported from the kc-graph package:
import {
resolveScope,
validateScopeName,
getActiveScope,
setActiveScope,
resetActiveScope,
listScopes,
scopeExists,
deleteScope,
ensureScopeDir,
scopePath,
detectGitBranch,
DEFAULT_SCOPE,
} from 'kc-graph';Resolve scope with priority chain
const scope = resolveScope('develop'); // explicit
const scope = resolveScope(); // env > config > "default"Manage active scope
setActiveScope('develop');
console.log(getActiveScope()); // "develop"
resetActiveScope();
console.log(getActiveScope()); // "default"List and inspect scopes
const scopes = listScopes(true); // global scopes
for (const s of scopes) {
console.log(`${s.name}: ${s.projectCount} projects, active=${s.active}`);
}Use with storage APIs
import { initProject, syncProject, resolveStore, loadAllGlobalProjects } from 'kc-graph';
// Init with scope
await initProject({ root: '/path/to/project', global: true, scope: 'develop' });
// Sync with scope
await syncProject({ root: '/path/to/project', global: true, scope: 'develop' });
// Load all projects in a scope
const projects = loadAllGlobalProjects('develop');