Skip to content

777genius/infinity-context

Repository files navigation

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

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_core owns domain entities, application use cases and ports only;
  • infinity_context_server owns FastAPI routes, composition root, auth, config, admin CLI, worker CLI and eval CLI;
  • infinity_context_server also serves the optional local memory browser at /ui/;
  • infinity_context_adapters owns Postgres, optional Qdrant/OpenAI/Graphiti adapters and disabled noop adapters;
  • infinity_context_sdk owns HTTP client calls and typed error handling for other apps;
  • infinity_context_mcp owns the agent-facing MCP adapter over the HTTP API;
  • infinity_context_cli owns 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, and unknown documents are not embedded until reclassified.

Implemented API surface:

  • /v1/health, /v1/capabilities;
  • /v1/spaces, /v1/memory-scopes;
  • /v1/facts remember/list/get/versions/update/forget;
  • /v1/documents ingest/get/chunks/process/delete;
  • /v1/episodes transcript/event ingest for app or agent sessions;
  • /v1/search, /v1/context with cited top_evidence and answer_support diagnostics for source-grounded chat answers;
  • /v1/digest for source-bound Memory Digest reports;
  • /v1/thread-memory/status, /v1/thread-memory delete for thread-scoped cleanup;
  • /v1/suggestions create/list/approve/reject/expire for review-gated memory;
  • /v1/link-suggestions, /v1/context-link-suggestions, /v1/context-link-suggestions/review-batch, /v1/context-links for 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 when MEMORY_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 /v1 API;
  • 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-defaults and guarded admin 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, and quickstart --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 a one_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-level memory_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 call memory_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 for MEMORY_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 plus MEMORY_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 both MEMORY_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

About

Reliable memory and context infrastructure for AI coding agents: source-backed facts, review-gated learning, MCP/SDK/UI, and replaceable Qdrant/Graphiti retrieval.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors