Coding (overview)¶
semvec.coding is the persistent-memory layer for coding agents. There are three usage paths depending on how you run the agent — pick by use case, not by preference. Every path uses the same underlying CodingEngine and LiteralCache; the wrapping changes.
Pick a path¶
| You want to… | Path | Pulls in | Persistence is |
|---|---|---|---|
| Use Claude Code as your coding agent | MCP server + lifecycle hooks | [coding] (FastMCP) |
Automatic — SessionStart loads, PreCompact saves |
| Use Cursor as your coding agent | MCP server, no hooks | [coding] (FastMCP) |
Manual via the agent — Cursor Rule asks the agent to call pss_save() |
| Build custom tooling — batch transcript ingestion, scripted code analysis, internal CLI | Direct CodingEngine |
[coding] (FastMCP optional, cryptography if you encrypt snapshots) |
You call engine.save_state() |
| Run a multi-tenant server that exposes coding memory over HTTP | REST API (semvec[api]) |
[api] (FastAPI, uvicorn) |
Per-session SQLite/Postgres, Ed25519 JWT-gated |
The four paths can mix freely — e.g. an MCP-driven IDE on the developer's laptop talks to a REST-hosted Semvec service for shared team memory, while a nightly batch job uses the in-process CodingEngine to ingest CI transcripts.
Path 1 — MCP server + Claude Code lifecycle hooks¶
The recommended setup if you use Claude Code. The MCP server exposes the six pss_* tools, and the two lifecycle hooks (SessionStart, PreCompact) take care of state loading and persistence automatically — the agent never has to remember to save.
{
"mcpServers": {
"semvec": {
"command": "python",
"args": ["-m", "semvec.coding.mcp_server"],
"env": {"SEMVEC_STATE_DIR": ".semvec"}
}
},
"hooks": {
"SessionStart": [{"command": "python -m semvec.coding.hooks.session_start", "timeout": 10000}],
"PreCompact": [{"command": "python -m semvec.coding.hooks.pre_compact", "timeout": 30000}]
}
}
→ Full step-by-step: Claude Code guide.
Path 2 — MCP server in Cursor¶
If your editor speaks MCP but has no equivalent of Claude Code's lifecycle hooks. Same six tools; persistence becomes the agent's responsibility, driven by a Cursor Rule. Works in Cursor 0.45+.
{
"mcpServers": {
"semvec": {
"command": "python",
"args": ["-m", "semvec.coding.mcp_server"],
"env": {"SEMVEC_STATE_DIR": ".semvec"}
}
}
}
→ Full step-by-step: Cursor guide.
Path 3 — Direct CodingEngine for custom tooling¶
When you're not driving the engine from an agent at all — e.g. a CI job that ingests a transcript dump, a script that runs anti-resonance checks against a feature spec, an internal CLI that prints pss_get_context output to a developer's terminal.
from semvec.coding import CodingEngine
engine = CodingEngine(
state_dir=".semvec",
embedder=my_embedder, # required — no hash fallback
workspace_dir=".",
context_budget=6000,
)
engine.load_state()
# Ingest a Claude Code JSONL transcript
stats = engine.ingest_transcript("session.jsonl")
# {'conversation_chunks': N, 'code_changes': M, 'test_failures': K, 'errors': J}
# Or write into the engine programmatically
engine.register_code_change("auth.py", "JWT validation", "def verify(token)")
engine.record_error("TypeError: None has no attribute 'split'", source="runtime_error")
# Build a context block for any LLM you control
context = engine.get_compacted_context(
"implement password reset flow",
invariants=["never log plaintext passwords"],
test_summary="12 passed / 0 failed",
git_diff="…",
)
engine.save_state()
This is the lowest-overhead path; no MCP server, no FastAPI, no JWT verification. Use it when you own the LLM call yourself.
→ API: semvec.coding reference.
Path 4 — REST API for multi-tenant servers¶
When the same LiteralCache has to be reachable from multiple developer machines, multiple agents, or a backend service. The semvec[api] extra ships a FastAPI server that wraps the literal-cache surface (and the full multi-agent stack — see Cortex guide). Auth is the same Ed25519 JWT used by the in-process licensing system.
pip install "semvec[api]"
export SEMVEC_LICENSE_KEY="eyJhbGciOiJFZERTQSI..."
export DATABASE_URL="postgresql://user:pw@host/semvec"
semvec serve --host 0.0.0.0 --port 8080
# Store a verbatim code entity
curl -X POST http://localhost:8080/v1/session/abc/entities \
-H "Authorization: Bearer $SEMVEC_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"kind": "decision", "key": "use mpnet 768d", "value": "for German content"}'
# List / keyword-query entities
curl "http://localhost:8080/v1/session/abc/entities?q=mpnet" \
-H "Authorization: Bearer $SEMVEC_LICENSE_KEY"
# Run a turn (uses the same backing session as the literal cache)
curl -X POST http://localhost:8080/v1/run \
-H "Authorization: Bearer $SEMVEC_LICENSE_KEY" \
-H "Content-Type: application/json" \
-d '{"session_id": "abc", "query": "what did we decide about embedders?"}'
The literal-cache endpoints are documented in the REST API reference. The full session / run / state endpoints sit alongside them — the same SemvecState is the backing store, so anything you store via /v1/session/{id}/entities is queryable via /v1/state/context.
→ Full endpoint list: REST API reference. CLI flags: CLI reference.
What every path requires¶
- An explicit embedder.
CodingEngine, the MCP server, the hooks, and the REST API all refuse silent hash-based fallbacks. Pass anembedder(in-process), setSEMVEC_EMBED_MODEL(subprocess paths), or pre-build a SentenceTransformer (REST API). - A persistent state directory. Set
SEMVEC_STATE_DIR(default.semvec). For multi-machine teams, decide whether to commit.semvec/to git (shared memory) or.gitignoreit (per-clone memory). For the REST API, the equivalent is the SQLite/PostgresDATABASE_URL. - An embedder dimension that matches your existing snapshots. Switching from MiniLM (384 d) to mpnet (768 d) on an existing project requires you to re-ingest history; the engine refuses to mix dimensions. See Embedders.
Headline features¶
| Feature | What it does | Where in the API |
|---|---|---|
LiteralCache |
Verbatim multi-session structured memory: decisions, invariants, error patterns, test history, code structures | api/coding.md#literalcache |
CodePointerIndex |
Semantic-similarity index over (file_path, signature, intent) triples |
api/coding.md#codepointer-codepointerindex |
NegativeAttractorSet |
Anti-resonance — flag proposals that resemble past failures, with severity decay | api/coding.md#negativeattractor-negativeattractorset |
PromptBuilder |
Token-budgeted Markdown context block, dropping low-priority sections under tight budgets | api/coding.md#promptbuilder |
TranscriptParser |
Parse Claude Code JSONL transcripts into typed chunks (CONVERSATION, CODE_CHANGE, TEST_FAILURE, ERROR) |
api/coding.md#transcriptparser-transcriptchunk-chunktype |
Where to next¶
- Claude Code guide — full lifecycle-hook setup.
- Cursor guide — MCP-only setup with a Cursor Rule.
semvec.codingAPI reference — every class and method.- Embedders — pick the right model.
- REST API reference — the multi-tenant path.