infinity-context
Health Warn
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Reliable memory and context infrastructure for AI coding agents: source-backed facts, review-gated learning, MCP/SDK/UI, and replaceable Qdrant/Graphiti retrieval.
Infinity Context
Reliable memory and context infrastructure for AI coding agents.
Infinity Context helps AI coding agents keep project knowledge across sessions
without turning random chat history into permanent truth. It captures decisions,
documents, tasks, source references, agent events and reviewable suggestions,
then serves compact, cited context back through HTTP, SDK, MCP and a local UI.
The difference is trust. Every durable memory has a canonical lifecycle in
Postgres: source evidence, versions, scopes, deletes, idempotency and review
state. Vector and graph engines make recall better, but they never become hidden
truth. If Qdrant, Graphiti or an LLM returns something stale, Infinity Context
revalidates it before it reaches the agent prompt.
This is not a demo memory store. The repo already includes the reusable core,
FastAPI server, Postgres lifecycle, optional Qdrant and Graphiti adapters, SDK,
MCP adapter, CLI, local memory browser, service-token auth, workers, diagnostics,
smoke flows and prompt-impacting quality evals.
What You Get
- Cited agent memory for architecture decisions, docs, tasks, captures and
transcripts. - Scoped recall across spaces, memory scopes and threads, so one project does
not leak into another. - Review-gated learning where agents can suggest memories and relations, but
humans control what becomes canonical. - Current-state filtering for updates, deletes, restricted data and stale
derived indexes. - Self-hosted runtime with local Docker profiles, service tokens, CLI,
browser UI, SDK and MCP adapter. - Replaceable retrieval with Postgres as the source of truth and Qdrant,
Graphiti, Cognee or provider adapters behind ports.
Why Teams Choose It
- Safer than plain vector memory. A vector hit is only a candidate until it is
hydrated through canonical facts, source refs and visibility rules. - More controllable than automatic chat memory. Prompt memory is evidence,
not instruction, and suggested memory can be reviewed before it affects future
agents. - Better fit for coding work. The model is built around projects, documents,
decisions, source evidence, thread cleanup, digest reports and agent tooling. - Stable enough for real workflows. Additive migrations, transactional
outbox, token hashing, circuit diagnostics, import-boundary tests, API tests,
worker tests and golden evals are part of the shipped system.
Positioning
Use Mem0-style tools when you mostly need
quick personalization memory. Use Zep when you want a
managed enterprise context graph. Use
LangGraph memory primitives
when your memory should stay inside one agent framework.
Use Infinity Context when the hard problem is trustworthy project memory for
coding agents: source-backed facts, scoped recall, current-state filtering,
review workflows, self-hosted data and portable adapters.
Project State
Infinity Context is a working standalone service and library stack. It supports
local developer setups, self-hosted team deployments and client integrations
through HTTP, SDK or MCP.
Runtime architecture:
Infinity Context = Postgres canonical truth + Qdrant RAG + optional Graphiti graph + SDK/MCP/UI
Trust model:
- Clean Architecture;
- SOLID;
- simple DDD;
- port/adapter boundaries;
- Postgres as canonical truth;
- Qdrant and Graphiti as derived indexes;
- prompt memory is evidence, never instruction.
Docs
- Core runtime implementation plan
- Local install and Memory Digest plan
- Global architecture plan
- Client compatibility notes
- Client integration run notes
Package Layout
packages/
infinity_context_core/
infinity_context_server/
infinity_context_adapters/
infinity_context_sdk/
infinity_context_mcp/
infinity_context_cli/
tests/
unit/
integration/
e2e/
fixtures/
Client applications should consume this project through HTTP or SDK, not by importing provider-specific adapters.
What Ships Today
Infinity Context ships as a reusable service and library stack:
infinity_context_coreowns domain entities, application use cases and ports only;infinity_context_serverowns FastAPI routes, composition root, auth, config, admin CLI, worker CLI and eval CLI;infinity_context_serveralso serves the optional local memory browser at/ui/;infinity_context_adaptersowns Postgres, optional Qdrant/OpenAI/Graphiti adapters and disabled noop adapters;infinity_context_sdkowns HTTP client calls and typed error handling for other apps;infinity_context_mcpowns the agent-facing MCP adapter over the HTTP API;infinity_context_cliowns local install/runtime UX and calls the HTTP API instead of importing server internals;- Postgres is canonical truth for spaces, memory_scopes, facts, source refs, fact versions, episodes, documents, chunks, suggestions, outbox and idempotency;
- Qdrant vectors and Graphiti graph memory are derived projections behind ports;
- Qdrant adapter creates its collection on first upsert/search when enabled;
- Graphiti adapter is optional and requires Neo4j credentials when enabled;
- context/search hydrate graph/vector candidates through Postgres before rendering;
- prompt memory is rendered as evidence, never as instructions.
- prompt context is grouped by memory_scope id and caps chunk evidence per source so
one long document cannot consume the whole memory block; - document/chunk classification is enforced in the prompt path:
restricted
memory is stored canonically but excluded from context by default, andunknowndocuments are not embedded until reclassified.
Implemented API surface:
/v1/health,/v1/capabilities;/v1/spaces,/v1/memory-scopes;/v1/factsremember/list/get/versions/update/forget;/v1/documentsingest/get/chunks/process/delete;/v1/episodestranscript/event ingest for app or agent sessions;/v1/search,/v1/contextwith citedtop_evidenceandanswer_support
diagnostics for source-grounded chat answers;/v1/digestfor source-bound Memory Digest reports;/v1/thread-memory/status,/v1/thread-memorydelete for thread-scoped cleanup;/v1/suggestionscreate/list/approve/reject/expire for review-gated memory;/v1/link-suggestions,/v1/context-link-suggestions,/v1/context-link-suggestions/review-batch,/v1/context-linksfor reviewable memory relations and status-filtered review history;/v1/diagnostics/adapters,/outbox,/memory-scope/{memory_scope_id}with production-safe metadata only;- optional client-compatible
/api/v1/interview-memory/ingest,/context, session status and delete routes whenMEMORY_LEGACY_CLIENT_ENABLED=true.
Local browser UI:
- open
http://127.0.0.1:7788/ui/after the server starts; - enter the service token from local config, for example
~/.infinity-context/.env; - browse graph nodes for facts, suggestions, sources, kinds, tags and statuses;
- review pending suggestions and relation suggestions with approve/reject/edit actions;
- build source-bound digest and recall results through the existing
/v1API; - disable with
MEMORY_UI_ENABLED=false.
Operational pieces:
- transactional outbox for derived graph/vector side effects;
- outbox worker that re-reads canonical rows and handles disabled adapters safely;
- idempotency keys are scoped by operation and memory_scope/thread boundary, so
client-provided retry keys cannot collide across memory scopes; - admin commands for doctor, invariant check, projection repair dry-run and dead-job replay;
- admin service-token create/list/revoke stores token hashes only; raw token is printed once on creation;
- database service tokens support expiry and last-used tracking without storing raw tokens;
infinity_context_server.db upgrade,admin seed-defaultsand guardedadmin reset-local;- schema upgrade is additive for local databases and repairs missing
fact/document/chunk classification columns without dropping canonical data; - document delete hides chunks immediately and also deletes active facts whose
current evidence only points to the deleted document or its chunks; - redacted memory_scope export removes fact/chunk text and source quote previews;
- small golden eval for prompt-impacting context behavior;
- quality golden eval for recall, precision, stale/delete filtering, memory_scope/thread
isolation, restricted-memory hiding, prompt-injection evidence handling and token budget safety; - import-boundary, API, worker, SDK and review-gated suggestion tests.
Local Run
One-command local install:
curl -fsSL https://raw.githubusercontent.com/777genius/infinity-context/main/scripts/install.sh | bash
Safer inspectable install:
curl -fsSL https://raw.githubusercontent.com/777genius/infinity-context/main/scripts/install.sh -o install.sh
bash install.sh --no-start
After install:
export PATH="$HOME/.infinity-context/bin:$PATH"
infinity-context quickstart --agent codex --open-ui
Manual local controls remain available:
infinity-context up --lite
infinity-context status
infinity-context doctor
infinity-context mcp-config --agent codex
infinity-context digest "current architecture decisions" --space default --memory_scope default
infinity-context quickstart initializes local config, starts the lite Docker
runtime, waits for readiness and writes an MCP config under~/.infinity-context/generated/. quickstart and mcp-config keep the local
service token out of generated agent config by default and point the MCP adapter
at the private ~/.infinity-context/.env token file instead. Use--include-token only when intentionally writing a private local config file.infinity-context ui prints the local memory browser URL,infinity-context ui --open opens it in your browser, andquickstart --open-ui opens the visual memory browser immediately after setup.infinity-context doctor also verifies the generated MCP config and /ui/
browser entrypoint. The browser starts with a quick Capture panel for text notes
and file evidence, including a first-memory rail for the current memory scope,
capture count, file count, pending reviews and graph nodes. Direct local browser
links are available as /ui/#capture and /ui/#review, then the browser shows
overview, graph, review, operations and timeline.
Both quickstart --json and doctor --json include a local_experience
summary with status, ui_url, visual_memory_ready, mcp_ready,ready_agents, a first-use readiness score, the first Capture surface and aone_minute_path checklist with human labels, short descriptions,blocked_by or degraded_reason diagnostics, and Capture/Review deep links.
When the runtime is available, the Capture summary is derived from/v1/capabilities, so it only advertises active modalities: for example, local
audio/video metadata is shown separately from API-backed transcription. A fresh
local setup should reach status=ready;configured_not_started means the MCP config was generated but the local runtime
still needs infinity-context up --lite. If Docker is running on a different
published port than the configured API URL, status --json and doctor --json
include docker_published_api_urls and suggested_api_url diagnostics instead
of silently failing with only ConnectError.
The fastest local proof for the first-memory flow is:
make infinity-context-local-visual-smoke
It starts the lite stack if needed, writes a Codex MCP config without embedding
the raw token, checks MCP memory_status, saves a sandbox Capture, waits for
consolidation, and verifies that pending review plus the Capture are visible in
the local memory browser.
Agent-assisted local setup is also available through MCP, but it is off by
default so agents do not create files or start background services unexpectedly:
export MEMORY_MCP_LOCAL_RUNTIME_ENABLED=true
export MEMORY_MCP_LOCAL_RUNTIME_HOME="$HOME/.infinity-context"
export MEMORY_MCP_LOCAL_RUNTIME_REPO_DIR="$(pwd)"
Then an agent can call memory_obsidian_prepare for the safe first-use flow:
dry-run local config, vault folders and plugin install, then apply after user
approval. It never starts Docker or runs mutating sync. Lower-levelmemory_local_runtime_status, memory_local_runtime_init,memory_local_runtime_doctor and dry-run memory_local_runtime_start remain
available for diagnostics. A real Docker start still requires a separate
explicit gate:
export MEMORY_MCP_LOCAL_RUNTIME_START_ENABLED=true
Obsidian connector verification:
make infinity-context-obsidian-test
make infinity-context-obsidian-ui-e2e
infinity-context-obsidian-test covers the Python connector, live HTTP sync smoke,
MCP stdio setup/sync smoke, and plugin typecheck/build without opening Obsidian.infinity-context-obsidian-ui-e2e opens the real desktop Obsidian app and runs the
full WDIO plugin suite. Vaults with a custom Obsidian config folder are supported
through --obsidian-config-dir or MEMORY_MCP_OBSIDIAN_CONFIG_DIR.
Install once:
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev,qdrant,openai,graphiti,mcp]'
The Docker compose file has two practical profiles:
lite Postgres + Infinity Context Server, provider adapters disabled.
full Postgres + Qdrant + Neo4j + Infinity Context Server + workers, with OpenAI embeddings and Graphiti enabled.
Both profiles run separate projection and extraction workers. The extraction
worker only claims workload_class=extraction jobs, so file parsing can be
scaled independently from vector, graph and auto-memory projection work.MEMORY_EXTRACTION_WORKER_LIMIT controls how many outbox jobs are claimed per
poll. MEMORY_EXTRACTION_WORKER_CONCURRENCY controls how many claimed
extraction jobs run at once in one process, and defaults to 1 for conservative
parser/provider resource isolation.
Recommended local proof:
make infinity-context-up-lite
make infinity-context-smoke
make infinity-context-mcp-smoke
make infinity-context-local-visual-smoke
infinity-context-smoke covers the SDK lifecycle path plus MemoryScope snapshot thread transfer.
Full provider mode needs OpenAI for embeddings and Graphiti. Do not paste the
key into commands that will be saved in shell history. Read it silently or use
an ignored local env file:
read -s OPENAI_API_KEY
export OPENAI_API_KEY
export MEMORY_OPENAI_API_KEY="$OPENAI_API_KEY"
make infinity-context-up-full
make infinity-context-smoke-full
Small-team self-hosting uses a production-oriented Compose file with a built
image, server deploy profile, explicit migrations and persistent volumes:
cp .env.selfhost.example .env.selfhost
docker compose --env-file .env.selfhost -f docker-compose.selfhost.yml up -d --build
make infinity-context-selfhost-smoke
See docs/self-hosted-team-deployment.md for the runbook, full provider mode
and backup notes.
MEMORY_OPENAI_API_KEY is used by the Infinity Context embeddings adapter.OPENAI_API_KEY is also required because Graphiti reads the standard OpenAI
environment variable internally.
For a fully isolated paid canary, use a fresh Compose project and temporary
Docker volumes. The script starts isolated Postgres, Qdrant and Neo4j, runs
migrations, seeds defaults, starts the server, verifies Graphiti/Qdrant/OpenAI
behavior, then tears everything down:
make infinity-context-clean-full-smoke
If the key is not already exported in the current shell, use the interactive
wrapper. It reads the key with terminal echo disabled and passes it only through
the canary process environment:
make infinity-context-full-provider-canary-interactive
For local defaults, copy .env.example to .env and adjust non-secret provider
flags. Secrets should stay in your shell, .env.local, .env.full, or another
ignored file. Cognee is available as an optional adapter boundary, while the
default RAG path is Qdrant directly and the default temporal fact path is
Graphiti directly.
Common local targets are available in Makefile, for example make infinity-context-lint,make infinity-context-test-unit, make infinity-context-eval, make infinity-context-db-upgrade,make infinity-context-seed-defaults, make infinity-context-doctor, make infinity-context-up,make infinity-context-server, make infinity-context-up-lite, make infinity-context-up-full,make infinity-context-clean-full-smoke, make infinity-context-auto-memory-eval,make infinity-context-auto-memory-quality and make infinity-context-mcp-smoke.
Memory Digest can be called through API, SDK, MCP or CLI. It is derived evidence,
not canonical memory, and pending suggestions are clearly marked as non-canonical.
For exact lookups or write/update/forget flows, agents should still callmemory_search or memory_get_fact.
GitHub Actions runs the same prompt-impacting gate on push and pull requests:make PYTHON=python RUFF=ruff infinity-context-test-quality. Keep quality changes green
there before relying on memory in an agent prompt path.
Policy modes:
MEMORY_POLICY_MODE=disabled # no server writes or retrieval
MEMORY_POLICY_MODE=manual_only # explicit API writes, retrieval for reviewed/manual memory
MEMORY_POLICY_MODE=suggestions # review-gated memory mode
MEMORY_POLICY_MODE=active_context # active prompt-context mode
Auto-memory capture defaults are conservative:
MEMORY_CAPTURE_MODE=retrieve_only # no automatic capture writes
MEMORY_CAPTURE_MODE=capture_only # store captures, no suggestions
MEMORY_CAPTURE_MODE=suggest # captures can become pending suggestions
MEMORY_AUTO_APPLY_SAFE_ENABLED=false # separate switch for direct safe apply
MEMORY_CAPTURE_EXTRACTOR_PROVIDER=rule_based # rule_based, noop, or openai
MEMORY_CAPTURE_EXTERNAL_AI_ENABLED=false # external extractor egress kill switch
MEMORY_CAPTURE_EXTRACTOR_MODEL=gpt-4.1-mini # used only by the OpenAI extractor
MEMORY_MAX_PENDING_CAPTURES_PER_MEMORY_SCOPE=5000 # hook-loop ingress guard
MEMORY_MAX_PENDING_SUGGESTIONS_PER_MEMORY_SCOPE=500 # review queue ingress guard
MEMORY_AUTO_MEMORY_MODE is accepted as a compatibility alias forMEMORY_CAPTURE_MODE on both Infinity Context Server and plugin hooks. When both are set,MEMORY_AUTO_MEMORY_MODE wins.
Media extraction has product-plan usage guards in addition to parser limits:
MEMORY_PRODUCT_PLAN_TIER=free
MEMORY_PLAN_MEDIA_ANALYSIS_SECONDS_PER_MONTH=36000 # 10 hours
Audio/video uploads can pass estimated_media_seconds so Infinity Context can reserve
monthly media-analysis quota before enqueueing extraction. Clients can poll/v1/asset-extractions/{job_id} for progress and /v1/usage?space_slug=...
for the current plan meter.
Long extraction jobs refresh their lease while parsing and honor cancellation
requests through MEMORY_EXTRACTION_CANCELLATION_POLL_SECONDS plusMEMORY_EXTRACTION_HEARTBEAT_SECONDS; these values are also exposed by/v1/capabilities.
rule_based keeps consolidation local and deterministic. openai is available
behind MemoryExtractorPort, but it requires bothMEMORY_CAPTURE_EXTERNAL_AI_ENABLED=true and MEMORY_OPENAI_API_KEY; otherwise
startup or consolidation fails closed without sending capture text to a provider.
Auto-memory quality is checked by make infinity-context-auto-memory-quality, which
includes deterministic golden capture metrics for review gating, redaction,
duplicate suppression, replay idempotency and auto_apply_safe safety.
The Python SDK exposes create_capture, get_capture, list_captures,consolidate_capture, purge_capture and capture_diagnostics, so clients
should not hand-roll capture payloads.
Data classification:
public # embeddable and renderable evidence
internal # embeddable and renderable evidence
unknown # canonical storage and keyword recall, no embeddings by default
restricted # canonical storage only, excluded from context by default
Worker and operational commands:
MEMORY_SERVICE_TOKEN=local-dev-token .venv/bin/python -m infinity_context_server.worker --once
MEMORY_SERVICE_TOKEN=local-dev-token .venv/bin/python -m infinity_context_server.doctor
MEMORY_SERVICE_TOKEN=local-dev-token .venv/bin/python -m infinity_context_server.admin repair-projections --space project-alpha --memory_scope default --dry-run
MEMORY_SERVICE_TOKEN=local-dev-token .venv/bin/python -m infinity_context_server.admin import-memory_scope --space project-alpha --memory_scope default --file memory_scope-export.json --dry-run
MEMORY_SERVICE_TOKEN=local-dev-token .venv/bin/python -m infinity_context_server.eval run --suite small-golden
MEMORY_SERVICE_TOKEN=local-dev-token .venv/bin/python -m infinity_context_server.eval run --suite quality-golden
Service tokens:
MEMORY_SERVICE_TOKEN=root-token .venv/bin/python -m infinity_context_server.admin token create --description app
MEMORY_SERVICE_TOKEN=root-token .venv/bin/python -m infinity_context_server.admin token create --space space_project_alpha --description project-alpha --expires-at 2026-12-31T23:59:59+00:00
MEMORY_SERVICE_TOKEN=root-token .venv/bin/python -m infinity_context_server.admin token create --space space_project_alpha --memory_scope memory_scope_default --description project-alpha-default
MEMORY_SERVICE_TOKEN=root-token .venv/bin/python -m infinity_context_server.admin token list
MEMORY_SERVICE_TOKEN=root-token .venv/bin/python -m infinity_context_server.admin token revoke --token-id tok_...
The static MEMORY_SERVICE_TOKEN is a root token. Database service tokens are
stored as hashes only. A token created with --space is scoped to that space
id or slug and cannot access another space or unscoped diagnostics/list routes.
Add repeatable --memory_scope values to restrict a token to specific memory_scope ids
or external refs inside the allowed space.
Expired or revoked database tokens are rejected immediately. Token list output
contains ids, descriptions, scope, timestamps and status, never raw token values.
Graphiti local enablement requires Graphiti runtime dependencies plus Neo4j:
MEMORY_GRAPHITI_ENABLED=true \
MEMORY_GRAPHITI_NEO4J_URI=bolt://127.0.0.1:7687 \
MEMORY_GRAPHITI_NEO4J_USER=neo4j \
MEMORY_GRAPHITI_NEO4J_PASSWORD=<password> \
MEMORY_GRAPHITI_BUILD_INDICES=true \
MEMORY_SERVICE_TOKEN=local-dev-token \
.venv/bin/python -m infinity_context_server.main
The client compatibility gateway is opt-in for older client integrations that
still call /api/v1/interview-memory/*. New integrations should prefer the
canonical /v1/* API or infinity_context_sdk.
MEMORY_DEFAULT_SPACE_SLUG=client-app \
MEMORY_LEGACY_CLIENT_ENABLED=true \
make infinity-context-up-lite
Smoke the client compatibility gateway directly:
curl -X POST http://127.0.0.1:7788/api/v1/interview-memory/context \
-H "Authorization: Bearer local-dev-token" \
-H "Content-Type: application/json" \
-d '{
"session_id": "session-123",
"current_request": {
"id": "req-1",
"label": "request",
"text": "What memory is available for this session?"
}
}'
Other apps can use canonical ids or external scope refs. External refs are the
recommended integration shape for app sessions because the server resolves them
to canonical space_id/memory_scope_id/thread_id behind the API boundary:
curl -X POST http://127.0.0.1:7788/v1/episodes \
-H "Authorization: Bearer local-dev-token" \
-H "Content-Type: application/json" \
-d '{
"space_slug": "project-alpha",
"memory_scope_external_ref": "default",
"thread_external_ref": "session-123",
"source_type": "system_audio",
"source_external_id": "event-123",
"text": "Candidate prefers FIFO queue for event processing.",
"idempotency_key": "event-123"
}'
curl -X POST http://127.0.0.1:7788/v1/context \
-H "Authorization: Bearer local-dev-token" \
-H "Content-Type: application/json" \
-d '{
"space_slug": "project-alpha",
"memory_scope_external_ref": "default",
"thread_external_ref": "session-123",
"query": "What did the candidate prefer for event processing?",
"token_budget": 512
}'
SDK example:
from infinity_context_sdk import InfinityContextClient
client = InfinityContextClient(token="local-dev-token")
client.remember_fact(
space_id="space_project_alpha",
memory_scope_id="memory_scope_default",
text="Postgres is canonical truth.",
kind="architecture_decision",
source_refs=[{"source_type": "manual", "source_id": "note-1"}],
)
client.ingest_episode(
space_slug="project-alpha",
memory_scope_external_ref="default",
thread_external_ref="session-123",
source_type="system_audio",
source_external_id="event-123",
text="Candidate prefers FIFO queue for event processing.",
idempotency_key="event-123",
)
context = client.build_context(
space_slug="project-alpha",
memory_scope_external_ref="default",
thread_external_ref="session-123",
query="event processing preference",
token_budget=512,
)
typed_context = client.build_typed_context(
space_slug="project-alpha",
memory_scope_external_ref="default",
thread_external_ref="session-123",
query="event processing preference",
token_budget=512,
)
assert typed_context.answer_support.status in {"strong", "partial", "missing"}
suggestion = client.create_suggestion(
space_id="space_project_alpha",
memory_scope_id="memory_scope_default",
candidate_text="Qdrant is a derived index.",
kind="architecture_decision",
safe_reason="review_required",
source_refs=[{"source_type": "manual", "source_id": "note-2"}],
)
client.approve_suggestion(suggestion["data"]["id"], reason="reviewed")
Local Verification
python -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
.venv/bin/ruff check .
.venv/bin/python -m pytest
.venv/bin/python -m infinity_context_server.eval run --suite small-golden
.venv/bin/python -m infinity_context_server.eval run --suite quality-golden
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found