forgetful
Memory server
Created by Scott
Published in ScottRBK/forgetful. Publisher page
339 GitHub stars
What it is
Opensource Memory for Agents
AutoGineer overview, from the brain’s own files
Forgetful is a storage and retrieval tool designed as a Model Context Protocol (MCP) server. It provides AI agents with persistent, semantically searchable memory, enabling them to maintain context across sessions and different agentic applications. By imposing the Zettelkasten principle, Forgetful requires memories to be atomic, which facilitates the automatic construction of a knowledge graph through semantic embedding and linking. It supports flexible storage backends including SQLite for local development and PostgreSQL for production, and uses local embedding models to ensure privacy and performance. Beyond simple memory, it supports entities, projects, and procedural skills, allowing agents to coordinate tasks and maintain complex relationships between data points.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
Forgetful functions as an MCP server that exposes meta-tools to connected AI agents. When an agent records a memory, it must provide a title, content, and context, which the server then converts into semantic embeddings using local models. The system automatically links new memories to existing ones based on similarity scores, building a knowledge graph. It manages the agent's context window by enforcing a token budget and ranking retrieved information by importance. The system also supports entities and relationships, allowing for structured data management alongside unstructured memory notes.
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 10 |
| app | source-code | 153 |
| docs | docs | 46 |
| examples | examples | 1 |
| skills | agent-instructions | 13 |
| tests | tests | 182 |
| alembic | folder | 18 |
| benchmarks | folder | 6 |
| docker | folder | 5 |
| nix | folder | 1 |
| test_harness | folder | 12 |
Requirements
Runtimes: Python >=3.12
Databases: PostgreSQL, Qdrant, SQLite
API keys (by name): FORGETFUL_TOKEN
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 2 scripts. Review app/bootstrap.py, pyproject.toml before opening the folder in Claude Code. No step below turns a hook on for you.
app/bootstrap.py:python app/bootstrap.pypyproject.toml:hatch build hook vcs (hatch_build.py)
- Not scanned by AutoGineerThe author’s README also describes installing it with Docker Compose. Read its install section: AutoGineer did not scan that path. https://github.com/ScottRBK/forgetful/blob/9f85ddcf2ca1ae0264358e0b4b50860948ec1e03/README.md#option-3-docker-deployment-productionscale
- Not scanned by AutoGineerThe author’s README also describes installing it from a clone of its repository. Read its install section: AutoGineer did not scan that path. https://github.com/ScottRBK/forgetful/blob/9f85ddcf2ca1ae0264358e0b4b50860948ec1e03/README.md#quick-start
- Not scanned by AutoGineerIts dependencies are installed by pip or uv when you run it and were not scanned by AutoGineer (28 declared). https://pypi.org/project/forgetful-ai/
Created by Scott. Published in ScottRBK/forgetful. Licence: MIT License.
Usage
AutoGineer overview, from the brain’s own files
- Connect to AI agents via MCP (stdio or HTTP).
- Store atomic memories with context and tags.
- Query memories using natural language with semantic search.
- Manage projects and link memories to specific work streams.
- Track entities and their relationships for team or system context.
- Execute procedural skills stored as step-by-step instructions.
- “Create a memory about a technical decision.”
- The agent saves an atomic note linked to a project, which is then semantically indexed and linked to related past decisions.
- “Find information about a specific team member's role.”
- The agent retrieves the entity record for the person and any associated memories or relationship metadata.
Documentation by Scott
<h1 align="center">Forgetful</h1>
<p align="center"> <img src="https://img.shields.io/badge/python-3.12%2B-blue" alt="Python"> <img src="https://img.shields.io/badge/license-MIT-green" alt="License"> <img src="https://img.shields.io/badge/MCP-server-purple" alt="MCP"> <a href="https://github.com/jlowin/fastmcp"> <img src="https://img.shields.io/badge/FastMCP-powered-orange" alt="FastMCP"> </a> <a href="https://github.com/qdrant/fastembed"> <img src="https://img.shields.io/badge/FastEmbed-powered-orange" alt="FastEmbed"> </a> <a href="https://discord.gg/ngaUjKWkFJ"> <img src="https://img.shields.io/badge/Discord-Join%20Us-7289da?logo=discord&logoColor=white" alt="Discord"> </a> </p>
Forgetful is a storage and retrieval tool for AI Agents. Designed as a Model Context Protocol (MCP) server built using the FastMCP framework. Once connected to this service, MCP clients such as Coding Agents, Chat Bots or your own custom built Agents can store and retrieve information from the same knowledge base.
Table of Contents
Overview
Features
Quick Start
CLI
Usage Examples
How It Works
Configuration
Documentation
Contributing
License
Overview
A lot of us are using AI Agents now, especially in the realm of software development. The pace at which work and decisions are made can make it difficult for you to keep up from a notes and context persistence perspective.
So if you are following something like the BMAD Method for example and you want to take your brain storming session you've just had with Claude on your desktop/mobile and use it for the basis of your next Claude Code session, then having a shared knowledge base across the two agents can help with this.
This is just one example use case to illustrate the point, more and more agentic applications are going to surface and the use cases for sharing data across them is going to increase.
Knowledge bases are going to become a key infrastructure component for your interactions with AIs. There are many excellent knowledge base solutions available (many for free on github) and I would encourage you to check them out and find one that works for you (even if Forgetful doesn't) as I found from personal experience that interactions with my agents got easier and more rewarding once they knew more about me, my work and previous interactions that I had had with them or other AI systems.
What makes Forgetful different from other Memory based MCP services is that it is a rather opinionated view on how AI Agents such store and retrieve data.
Forgetful imposes the Zettelkasten principle when clients wish to record memories, that is each memory must be atomic (one concept per note). Along with the note (title and content), we also ask the client / agent to provide context around what it was doing when creating the note, along with keywords and tags. With this information we create semantic embeddings and store these to aid with later retrieval and in addition to this we also automatically link the memory to existing memories that have a particular similarity score, allowing for the automatic construction of a knowledge graph.
In this sense Forgetful becomes a little bit like Obsidian for AI Agents, where the auto linking nudges them in building up a graph of the knowledge.
We find, as do others (A-MEM: Agentic Memory or LLM Agents), all this helps in ensuring that when the agent requires relevant information from the memory system later, the correct information is returned.
In addition to just memories, Forgetful also has the concept of entities (think organisation, people, products), projects, documents, code artifacts, skills (procedural knowledge following the Agent Skills standard), and plans with tasks for multi-agent coordination, all of which can be associated with one or more memories.
Features
Configure either STDIO or HTTP transport mechanism (or stand up two services to support both)
Multiple Authentication supported, flows see FastMCP docs for full list
Meta Tool Discovery, only three tools exposed to client application to preserve context window.
Flexible Storage– SQLite (default, zero-config) or PostgreSQL (for scale and production deployments)
Stores memories as vectors and allowing memories to be retrieved from natural language queries from AI.
Cross Encoder reranking to improve recall and precision of memory retrieval.
Flexible ranking (embedding and cross encoder) providers, run everything locally without calls to the cloud thanks to FastEmbed
Automatic linking of semantically similar memories, automating the creation of the knowledge graph.
Plans and Tasks for multi-agent coordination -- structure work into plans with tasks that have acceptance criteria, state management with optimistic locking, and dependency tracking with cycle detection.
Skills for procedural memory -- store step-by-step instructions and agent capabilities with semantic search, import/export in Agent Skills SKILL.md format, and cross-referencing with memories.
For the complete roadmap, see Features Roadmap.
Quick Start
Option 1: PyPI (Recommended)
# Run directly with uvx (no installation needed)
uvx forgetful-ai
# Or install globally
uv tool install forgetful-ai
forgetfulData stored in platform-appropriate locations (~/.local/share/forgetful on Linux/Mac, AppData on Windows).
By default, runs with stdio transport for MCP clients. For HTTP:
uvx forgetful-ai --transport http --port 8020Option 2: From Source
git clone https://github.com/ScottRBK/forgetful.git
cd forgetful
# Install dependencies with uv
uv sync
# Run the server (uses SQLite by default)
uv run main.pyThe server starts with stdio transport. For HTTP: uv run main.py --transport http
Option 3: Docker Deployment (Production/Scale)
Forgetful provides two Docker deployment options:
SQLite with Docker (Simpler, Single-Container)
cd docker
cp .env.example .env
# Edit .env: Set DATABASE=SQLite and SQLITE_PATH=data/forgetful.db
docker compose -f docker-compose.sqlite.yml up -dThe SQLite database persists in the ./data directory on the host.
PostgreSQL with Docker (Recommended for multitenant)
See docker-compose.postgres.yml and .env.example
cd docker
cp .env.example .env
# Edit .env: Set DATABASE=Postgres and configure POSTGRES_* settings
docker compose -f docker-compose.postgres.yml up -dNote: If no .env file exists, the application uses defaults from app/config/settings.py.
For all configuration options, see Configuration Guide.
Connecting to An Agent
For detailed connection guides (Claude Code, Claude Desktop, other clients that support MCP), see Connectivity Guide.
Copilot CLI (includes custom agents and skills)
Gemini CLI (includes custom commands)
Opencode (includes custom commands and skills)
Add Forgetful to your MCP client configuration:
stdio transport (recommended for local use):
{
"mcpServers": {
"forgetful": {
"type": "stdio",
"command": "uvx",
"args": ["forgetful-ai"]
}
}
}HTTP transport (for Docker/remote):
{
"mcpServers": {
"forgetful": {
"type": "http",
"url": "http://localhost:8020/mcp"
}
}
}CLI
The forgetful command is also a full terminal client over the same tool registry the
MCP meta-tools use - against your local database by default, or a remote deployment
after auth login.
uv tool install forgetful-ai
# Curated verbs for daily use
forgetful memory save "Set generateResolvConf false to fix WSL2 DNS" \
--title "WSL2 DNS fix" --importance 7
forgetful memory search "wsl dns" -c "wsl networking" -n 5
forgetful memory get 812
forgetful memory recent -n 10 -p my-project
forgetful project list
# Generic passthrough to any available tool
forgetful tools list --category memory
forgetful tools info query_memory
forgetful call create_project --args '{"name": "Homelab", "description": "...", "project_type": "personal"}'
# Remote deployment (browser OAuth; saves FORGETFUL_SERVER to ~/.config/forgetful/.env)
forgetful auth login --server https://forgetful.example.com
forgetful auth status
forgetful memory search "wsl dns" -c "wsl networking" # now runs remotely
forgetful memory search "wsl dns" -c "wsl networking" --local # force local mode per invocation
# Scripting: --json emits machine-readable output
forgetful memory search "wsl dns" -c "wsl networking" --json | jq '.primary_memories[0].id'forgetful serve is the canonical way to run the MCP server (forgetful serve --transport http --port 8020); the bare forgetful / uvx forgetful-ai invocation and
the legacy --transport/--re-embed flags keep working indefinitely, so existing MCP
client configurations are unaffected. Headless environments can set FORGETFUL_TOKEN
(bearer) instead of the OAuth flow. See the
Configuration Guide for precedence rules, or walk
through the forgetful-cli-setup skill for install,
auth, and verification steps end-to-end.
Usage Examples
Forgetful exposes only 3 meta-tools to MCP clients. The tools available through
execute_forgetful_tool depend on the enabled feature flags. Use
discover_forgetful_tools for the current runtime catalog.
Example 1: Project-Scoped Memory
Create a memory linked to a project for better organization and scoped retrieval.
# Create project for organizing related knowledge
project = execute_forgetful_tool(
"create_project",
{
"name": "E-Commerce Platform Redesign",
"project_type": "work",
"status": "active"
}
)
# Create memory linked to project
memory = execute_forgetful_tool(
"create_memory",
{
"title": "Payment gateway: Stripe chosen over PayPal",
"content": "Selected Stripe for its API, fees, and fraud detection.",
"context": "Choosing the payment provider for the redesign",
"keywords": ["payment", "stripe", "paypal"],
"tags": ["payment", "decision"],
"importance": 9,
"project_ids": [project["id"]]
}
)
# Later, query within project scope
results = execute_forgetful_tool(
"query_memory",
{
"query": "payment processing implementation",
"query_context": "Implementing payments for the redesign",
"project_ids": [project["id"]]
}
)
# Returns: Stripe decision + auto-linked related memoriesExample 2: Knowledge Graph with Entities
Track people, organizations, and relationships - perfect for team and infrastructure management.
# New engineer joins your company
new_hire = execute_forgetful_tool(
"create_entity",
{
"name": "Jordan Taylor",
"entity_type": "Individual",
"description": "Backend Engineer - Payments Team",
"tags": ["engineering", "backend", "payments"]
}
)
# Get company entity (create if needed)
company = execute_forgetful_tool(
"create_entity",
{
"name": "TechFlow Systems",
"entity_type": "Organization",
"description": "SaaS platform company"
}
)
# Create employment relationship
execute_forgetful_tool(
"create_entity_relationship",
{
"from_entity_id": new_hire["id"],
"to_entity_id": company["id"],
"relationship_type": "works_for",
"metadata": {
"role": "Backend Engineer II",
"department": "Payments",
"start_date": "2025-01-20"
}
}
)
# Create memory about hiring
hire_memory = execute_forgetful_tool(
"create_memory",
{
"title": "Jordan Taylor hired - payments focus",
"content": "Jordan joins to build the Stripe integration and handle PCI compliance.",
"context": "Recording ownership and experience for the payments work",
"keywords": ["jordan", "stripe", "payments", "pci"],
"tags": ["team", "hiring", "payments"],
"importance": 7
}
)
# Link person to memory
execute_forgetful_tool(
"link_entity_to_memory",
{
"entity_id": new_hire["id"],
"memory_id": hire_memory["id"]
}
)
# Query Jordan's related knowledge
results = execute_forgetful_tool(
"query_memory",
{
"query": "Jordan payment implementation",
"query_context": "Finding ownership and experience for payments work"
}
)
# Returns: Hiring memory + linked entity + relationship contextTool Categories
The core catalog covers users, memories, projects, entities, code artifacts, and documents. Skills, files, plans, and tasks appear when their feature flags are enabled.
For complete documentation with extensive examples, see Complete Tool Reference.
How It Works
Atomic Memory Principle
Inspired by Zettelkasten, each memory stores one concept in ~300-400 words:
Easily titled – Forces clarity (200 char limit)
Self-contained – Understandable without external context
Linkable – Small units enable precise knowledge graphs
For detailed content, use Documents and extract 3-7 atomic memories that link to the parent document.
Automatic Knowledge Graph
When you create a memory:
Embedding generated – FastEmbed converts content to 384-dimensional vector
Similarity search – Finds related memories (similarity ≥0.7 by default)
Auto-linking – Creates bidirectional links to top 3-5 matches (configurable)
Graph traversal – Queries return primary results + 1-hop linked memories
Entities and Knowledge Graphs
Entities represent concrete, real-world things (people, organizations, teams, devices) that can be linked to memories:
Typed entities – Organizations, Individuals, Teams, Devices, Systems, or custom types
Relationships – Directional connections (e.g., "Person works_at Organization") with strength and metadata
Memory linking – Associate entities with relevant memories for context
Knowledge graph – Build networks showing how entities relate to each other and your knowledge base
Use entities for concrete things (Sarah Chen, TechFlow Systems, Cache Server 01) and memories for abstract concepts (architectural patterns, decisions, learnings).
Token Budget Management
Prevents context window overflow:
Configurable budget (default 8K tokens)
Search finds relevant memories; primary results are then sorted by importance (high first)
Equal-importance primary results keep their search order, even when nothing is truncated
Truncates gracefully if over budget
Respects max memory count (default 20)
This keeps query results within the LLM's context budget.
For vector search and optional cross-encoder reranking, see Search Documentation.
Configuration
No configuration required – Forgetful uses sensible defaults out of the box.
Key Settings (Optional)
MEMORY_TOKEN_BUDGET– Max tokens for query results (default:8000)EMBEDDING_MODEL– Embedding model (default:BAAI/bge-small-en-v1.5)MEMORY_NUM_AUTO_LINK– Auto-link count (default:3, set0to disable)MEMORY_SIMILARITY_THRESHOLD– Minimum cosine similarity for auto-links (default:0.7)SERVER_PORT– HTTP server port (default:8020)MAX_GRAPH_LIMIT– Upper bound for/api/v1/graph?limitand/api/v1/graph/subgraph?max_nodes(default:2000)
For all 40+ environment variables with detailed explanations, see Configuration Guide.
Documentation
Guides
Core Concepts – Memories vs Entities vs Documents explained
Complete Tool Reference – Runtime tools and examples
REST API Reference – HTTP endpoints for web UI integration
Configuration Guide – All environment variables explained
Connectivity Guide – Connect Claude and other MCP clients
Self-Hosting Guide – Deploy on a VPS with Docker
Nix Guide – Reproducible dev shell, builds and OCI image with Nix flakes
Search Documentation – Embedding pipeline and retrieval architecture
Embedding Migration – Switch embedding providers safely
Features Roadmap – Planned features and priorities
External Resources
MCP Protocol Specification – Model Context Protocol docs
pgvector – PostgreSQL vector extension
FastEmbed – Local embedding generation
Zettelkasten Principle – Atomic note-taking method
Contributing
We welcome contributions! Forgetful uses integration + E2E testing with Docker Compose orchestration.
See the contributor guide for:
Testing workflows (integration tests, E2E tests, GitHub Actions)
Development setup (local vs Docker)
CI/CD pipeline details
Release process
License
MIT License - see LICENSE for details.
CONTRIBUTING.md
Contributing to Forgetful
This guide covers contribution expectations, local development, testing, and releases.
Using AI tools
You're welcome to use coding agents, LLMs, and other AI tools when contributing. You are responsible for everything you submit. Before opening a pull request, read the full diff and make sure you understand how the changes work and why they are needed.
Check the output yourself. Run the relevant tests and checks, inspect their results, and explain in the PR how you verified the change. Be clear about anything you couldn't test. You should be able to explain your approach in your own words and answer questions during review.
The same responsibility applies to issues. Verify claims before posting and include a reproduction or other concrete evidence. Treat automated audit findings as leads to investigate before filing them.
Issues, pull requests, and review capacity
Please keep contributions focused and check existing issues and PRs first. Each submission takes time to review.
If an audit produces many findings, start with one summary issue containing the findings you have checked. Agree on scope and priorities with a maintainer before opening a batch of issues or pull requests.
Flooding the repository with unverified reports, duplicate issues, or bulk PRs without prior agreement is spam. We will close these submissions in bulk, without reviewing or responding to each one individually.
Development setup
You need Python 3.12 or newer and uv. The main CI test jobs use Python 3.13. These shell examples use Bash, including Bash in WSL.
git clone https://github.com/ScottRBK/forgetful.git
cd forgetful
uv sync --locked --all-extras --devRun the remaining commands from the repository root. Use uv run to run commands in the
project's Python environment without activating it manually.
Architecture
Before changing code, read the architecture overview. The detailed class map is supporting material; use the overview's advisories to read relevant sections rather than the whole file.
Run uv run pytest tests/architecture/ before submitting code changes; CI runs the same check.
It checks imports, verifies that every app module is scanned, and proves each rule rejects
forbidden dependencies; see the rules and validation notes.
After major code changes, check whether the architecture diagram or explanations need updating. Update them when the architecture has changed; small changes do not require regeneration. Preserve reviewed explanations that remain accurate. Keep the overview at most 500 lines, with no column-width limit, including Mermaid statements.
You do not need Mycelium to contribute or update the overview. If useful, the optional
Mycelium architecture skill and map-generation skill
are published in ScottRBK/mycelium. When refreshing the generated backup, run fresh
analysis, keep the JSON outside the repository, and export full detail to
docs/assets/mycelium_class_diagram.md with --max-classes 1000, --test-path tests, and
--test-path test_harness/runs. Verify nonempty diagrams and repeat-export consistency.
Running the source with Docker
You need Docker with the Compose plugin. The development Compose file builds the application from your checkout and runs PostgreSQL alongside it.
If docker/.env does not exist, copy the example:
cp docker/.env.example docker/.envEdit docker/.env before starting the containers. Keep DATABASE=Postgres and
POSTGRES_HOST=forgetful-db for this setup, and configure the database credentials.
The PostgreSQL container needs a nonempty POSTGRES_PASSWORD when creating its database.
See the configuration guide for the available settings.
Start the database and wait for it to be healthy, then build and start the application:
docker compose -f docker/docker-compose.yml up -d --wait forgetful-db
docker compose -f docker/docker-compose.yml up -d --build --wait forgetful-serviceWith the default port, the health endpoint is http://127.0.0.1:8020/health.
The first application startup may need to download local embedding and reranking models.
To inspect startup output:
docker compose -f docker/docker-compose.yml logs -f forgetful-serviceRe-run the application build command after source changes. The default configuration copies source into the image; it does not mount your checkout for live updates.
Testing
We focus on integration and end-to-end tests that cover critical workflows. Add regression coverage for changed behaviour, including a test that demonstrates a bug before fixing it.
The default embedding and reranking providers use local models. Tests that load these adapters need network access on first use, or an existing model cache. Shared E2E adapters follow your provider settings, so configuring a remote provider can make those tests call that service.
Integration tests
Most tests in tests/integration/ use in-memory stubs. Some, including the bootstrap and local
CLI tests, use real SQLite databases and local embeddings. This suite does not require Docker.
uv run pytest tests/integration/SQLite E2E tests
These tests exercise the application through MCP, HTTP, and CLI entry points using real SQLite. Most use an in-memory database; tests that need persistence use temporary files. Docker is not required.
uv run pytest tests/e2e_sqlite/PostgreSQL E2E tests
These tests require Docker with Compose and use PostgreSQL 16 with pgvector. The fixtures
start or reuse the container named forgetful-db, copying docker/.env.example to docker/.env
if that file is missing. The application runs inside the test process.
Use a disposable database: the fixtures delete application data before each test. They will
reuse an existing forgetful-db container, so check what it contains before running the suite.
Run these tests sequentially; concurrent runs would clear each other's data.
uv run pytest tests/e2e/ -m e2eThe fixtures leave the container running for later test runs. PostgreSQL tests are excluded
by default in pytest.ini; -m e2e selects them. Backup tests also need the client tools
described below. See the PostgreSQL test guide for fixture details.
Docker image checks
Run these checks against an image already present in your Docker daemon. They prepare model and tokenizer caches with network access, then test startup and search with networking disabled. They also check the installed version and that data survives restart and container recreation.
docker build -f docker/Dockerfile --build-arg VERSION=0.0.0+dev -t forgetful:offline-test .
FORGETFUL_TEST_IMAGE=forgetful:offline-test FORGETFUL_TEST_VERSION=0.0.0+dev \
uv run pytest tests/docker/ -vThe test skips when FORGETFUL_TEST_IMAGE is unset. It creates temporary containers and volumes
and removes them during cleanup.
User creation tests
test_user_creation_sqlite.py and test_user_creation_e2e.py share cases that check real duplicate
inserts, preservation of the existing user, recovery when another request creates the user first,
and propagation of unrelated database errors; only the timing of the competing lookup is arranged.
Backup and recovery tests
These tests use a temporary SQLite file or the PostgreSQL E2E database. They check that a backup restores memories, metadata, links, obsolete state, and searchable vectors. They also run the real CLI, fail the embedding provider after a saved batch or during the final search check, and verify that automatic recovery restores the original data.
The embedding provider returns fixed vectors, so these tests need no model downloads or API keys.
PostgreSQL requires pg_dump and psql compatible with the PostgreSQL 16 test server. CI installs
the client tools explicitly and fails if either is missing; local runs skip with an explanation.
uv run pytest tests/e2e_sqlite/test_backup_restore_sqlite.py -q --durations=5
uv run pytest tests/e2e/test_backup_recovery_e2e.py \
tests/e2e/test_zz_backup_restore_e2e.py -m e2e -q --durations=5To select a different disposable database on localhost, set PGPORT, POSTGRES_DB,
POSTGRES_USER, and POSTGRES_PASSWORD to match it. The PostgreSQL fixtures still check
for the forgetful-db Docker container.
Linting
Run Ruff before submitting changes:
uv tool run ruff check .GitHub Actions
The workflow files in .github/workflows/ define the checks and release
jobs. CI and PostgreSQL tests run on branch pushes and pull requests. A push to a branch with an
open PR can start both runs; newer runs cancel older runs for the same workflow and ref.
CI
ci.yml contains three jobs:
testruns architecture checks, integration tests, SQLite E2E tests, and Ruff on Ubuntu and Windows with Python 3.13.smoke-testruns after the test matrix succeeds. It builds the Python wheel, checks for migration files, and verifies installation and the CLI help command.docker-offlinebuilds an image and runs the Docker image checks described above.
PostgreSQL tests
e2e.yml runs the PostgreSQL suite on Ubuntu with Python 3.13.
It installs the PostgreSQL client tools and runs tests/e2e/ with -m e2e, including backup
and recovery checks. It also supports manual runs through workflow_dispatch.
Workflow definitions alone do not block merges. Maintainers must configure required status checks in GitHub branch rules, including the relevant matrix checks.
Docker image publishing
build.yml runs when a tag matching v* is pushed. Use a
semantic version such as v1.2.3. It builds the image, runs the Docker image checks against
that image, and publishes it to ghcr.io/scottrbk/forgetful only after those checks pass.
A stable release such as v1.2.3 produces 1.2.3, 1.2, and latest image tags.
Prerelease version tags retain their full version without updating the stable image tags.
The workflow keeps image provenance and does not cancel an in-progress publication.
Python package publishing
publish.yml runs when a GitHub release is published.
It builds the Python package with uv build and publishes to PyPI through the pypi GitHub
environment using trusted publishing. This workflow does not run the test suites itself.
Creating a release
These steps are for maintainers with permission to publish releases.
Merge the release changes and check out the commit you intend to release. Confirm that CI and the PostgreSQL suite passed for that commit.
Choose an unused semantic version, replace
vX.Y.Zbelow, then create and push the tag:RELEASE_TAG=vX.Y.Z git tag "$RELEASE_TAG" git push origin "$RELEASE_TAG"Check that the Build workflow succeeds and publishes the expected container image.
Publish a GitHub release for the same tag to trigger PyPI publishing, then check that the Publish to PyPI workflow succeeds.
To run a published image, use the SQLite or PostgreSQL Compose file. The README's Docker instructions describe their configuration.
472 files · 452 not served here
- .dockerignore (not served here)
- .github/ISSUE_TEMPLATE/bug_report.yml (not served here)
- .github/ISSUE_TEMPLATE/config.yml (not served here)
- .github/ISSUE_TEMPLATE/feature_request.yml (not served here)
- .github/PULL_REQUEST_TEMPLATE.md (not served here)
- .github/dependabot.yml (not served here)
- .github/workflows/build.yml (not served here)
- .github/workflows/ci.yml (not served here)
- .github/workflows/e2e.yml (not served here)
- .github/workflows/nix-cache.yml (not served here)
- .github/workflows/publish.yml (not served here)
- .gitignore (not served here)
- .python-version (not served here)
- AGENTS.md
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CLAUDE.md
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- LICENCE.md
- README.md
- SECURITY.md
- _typos.toml (not served here)
- alembic.ini (not served here)
- alembic/README (not served here)
- alembic/_db_helpers/__init__.py (not served here)
- alembic/_db_helpers/db_postgres_impl.py (not served here)
- alembic/_db_helpers/db_sqlite_impl.py (not served here)
- alembic/env.py (not served here)
- alembic/script.py.mako (not served here)
- alembic/versions/0c7b964dd1e7_initial_schema_with_entity_many_to_many.py (not served here)
- alembic/versions/20251216143413_add_aka_to_entities.py (not served here)
- alembic/versions/20260106_add_activity_log_table.py (not served here)
- alembic/versions/20260106_add_provenance_tracking_to_memories.py (not served here)
- alembic/versions/20260312_add_plans_tasks_criteria_dependencies.py (not served here)
- alembic/versions/20260315_add_files_table.py (not served here)
- alembic/versions/20260321_add_skills_table.py (not served here)
- alembic/versions/20260408_add_provenance_to_all_object_types.py (not served here)
- alembic/versions/20260704_add_memory_usage_tracking.py (not served here)
- alembic/versions/20260822_add_project_last_encoding_point.py (not served here)
- alembic/versions/20261008_add_plan_external_ref.py (not served here)
- alembic/versions/20261103_add_memory_search_tsv.py (not served here)
- app/__init__.py (not served here)
- app/bootstrap.py (not served here)
- app/config/__init__.py (not served here)
- app/config/auth.py (not served here)
- app/config/logging_config.py (not served here)
- app/config/plan_plugin.py (not served here)
- app/config/settings.py (not served here)
- app/config/write_plugin.py (not served here)
- app/events/__init__.py (not served here)
- app/events/event_bus.py (not served here)
- app/exceptions.py (not served here)
- app/middleware/__init__.py (not served here)
- app/middleware/auth.py (not served here)
- app/middleware/logging_middleware.py (not served here)
- app/models/__init__.py (not served here)
- app/models/activity_models.py (not served here)
- app/models/code_artifact_models.py (not served here)
- app/models/document_models.py (not served here)
- app/models/entity_models.py (not served here)
- app/models/file_models.py (not served here)
- app/models/graph_models.py (not served here)
- app/models/memory_models.py (not served here)
- app/models/models.py (not served here)
- app/models/plan_models.py (not served here)
- app/models/plan_plugin_models.py (not served here)
- app/models/project_models.py (not served here)
- app/models/skill_models.py (not served here)
- app/models/tool_registry_models.py (not served here)
- app/models/user_models.py (not served here)
- app/models/write_plugin_models.py (not served here)
- app/protocols/__init__.py (not served here)
- app/protocols/activity_protocol.py (not served here)
- app/protocols/backup_protocol.py (not served here)
- app/protocols/code_artifact_protocol.py (not served here)
- app/protocols/document_protocol.py (not served here)
- app/protocols/embedding_protocol.py (not served here)
- app/protocols/entity_protocol.py (not served here)
- app/protocols/executor.py (not served here)
- app/protocols/file_protocol.py (not served here)
- app/protocols/memory_protocol.py (not served here)
- app/protocols/plan_plugin_protocol.py (not served here)
- app/protocols/plan_protocol.py (not served here)
- app/protocols/project_protocol.py (not served here)
- app/protocols/skill_protocol.py (not served here)
- app/protocols/task_protocol.py (not served here)
- app/protocols/user_protocol.py (not served here)
- app/protocols/write_plugin_protocol.py (not served here)
- app/repositories/__init__.py (not served here)
- app/repositories/backup_adapter.py (not served here)
- app/repositories/embeddings/__init__.py (not served here)
- app/repositories/embeddings/bounded_executor.py (not served here)
- app/repositories/embeddings/embedding_adapter.py (not served here)
- app/repositories/embeddings/fastembed_offline.py (not served here)
- app/repositories/embeddings/reranker_adapter.py (not served here)
- app/repositories/postgres/__init__.py (not served here)
- app/repositories/postgres/activity_repository.py (not served here)
- app/repositories/postgres/code_artifact_repository.py (not served here)
- app/repositories/postgres/document_repository.py (not served here)
- app/repositories/postgres/entity_repository.py (not served here)
- app/repositories/postgres/file_repository.py (not served here)
- app/repositories/postgres/memory_repository.py (not served here)
- app/repositories/postgres/plan_repository.py (not served here)
- app/repositories/postgres/postgres_adapter.py (not served here)
- app/repositories/postgres/postgres_tables.py (not served here)
- app/repositories/postgres/project_reference.py (not served here)
- app/repositories/postgres/project_repository.py (not served here)
- app/repositories/postgres/skill_repository.py (not served here)
- app/repositories/postgres/task_repository.py (not served here)
- app/repositories/postgres/user_repository.py (not served here)
- app/repositories/sqlite/__init__.py (not served here)
- app/repositories/sqlite/activity_repository.py (not served here)
- app/repositories/sqlite/code_artifact_repository.py (not served here)
- app/repositories/sqlite/document_repository.py (not served here)
- app/repositories/sqlite/entity_repository.py (not served here)
- app/repositories/sqlite/file_repository.py (not served here)
- app/repositories/sqlite/memory_repository.py (not served here)
- app/repositories/sqlite/plan_repository.py (not served here)
- app/repositories/sqlite/project_reference.py (not served here)
- app/repositories/sqlite/project_repository.py (not served here)
- app/repositories/sqlite/skill_repository.py (not served here)
- app/repositories/sqlite/sqlite_adapter.py (not served here)
- app/repositories/sqlite/sqlite_tables.py (not served here)
- app/repositories/sqlite/task_repository.py (not served here)
- app/repositories/sqlite/user_repository.py (not served here)
- app/routes/__init__.py (not served here)
- app/routes/api/__init__.py (not served here)
- app/routes/api/activity.py (not served here)
- app/routes/api/auth.py (not served here)
- app/routes/api/capabilities.py (not served here)
- app/routes/api/code_artifacts.py (not served here)
- app/routes/api/documents.py (not served here)
- app/routes/api/entities.py (not served here)
- app/routes/api/files.py (not served here)
- app/routes/api/graph.py (not served here)
- app/routes/api/health.py (not served here)
- app/routes/api/memories.py (not served here)
- app/routes/api/plans.py (not served here)
- app/routes/api/projects.py (not served here)
- app/routes/api/skills.py (not served here)
- app/routes/api/tasks.py (not served here)
- app/routes/cli/__init__.py (not served here)
- app/routes/cli/auth_commands.py (not served here)
- app/routes/cli/context.py (not served here)
- app/routes/cli/local_executor.py (not served here)
- app/routes/cli/parser.py (not served here)
- app/routes/cli/paths.py (not served here)
- app/routes/cli/remote_executor.py (not served here)
- app/routes/cli/render.py (not served here)
- app/routes/cli/token_storage.py (not served here)
- app/routes/cli/verbs.py (not served here)
- app/routes/mcp/__init__.py (not served here)
- app/routes/mcp/code_artifact_tools.py (not served here)
- app/routes/mcp/document_tools.py (not served here)
- app/routes/mcp/entity_tools.py (not served here)
- app/routes/mcp/memory_tools.py (not served here)
- app/routes/mcp/meta_tools.py (not served here)
- app/routes/mcp/pagination.py (not served here)
- app/routes/mcp/project_tools.py (not served here)
- app/routes/mcp/scope_resolver.py (not served here)
- app/routes/mcp/skill_tools.py (not served here)
- app/routes/mcp/tool_adapters.py (not served here)
- app/routes/mcp/tool_metadata_registry.py (not served here)
- app/routes/mcp/tool_registry.py (not served here)
- app/routes/mcp/user_tools.py (not served here)
- app/routes/plan_plugin_responses.py (not served here)
- app/routes/write_plugin_responses.py (not served here)
- app/services/__init__.py (not served here)
- app/services/activity_service.py (not served here)
- app/services/backup_service.py (not served here)
- app/services/code_artifact_service.py (not served here)
- app/services/document_service.py (not served here)
- app/services/entity_service.py (not served here)
- app/services/entity_write_plugin_service.py (not served here)
- app/services/file_service.py (not served here)
- app/services/graph_service.py (not served here)
- app/services/memory_service.py (not served here)
- app/services/plan_service.py (not served here)
- app/services/plan_write_plugin_service.py (not served here)
- app/services/project_service.py (not served here)
- app/services/re_embedding_service.py (not served here)
- app/services/skill_service.py (not served here)
- app/services/task_service.py (not served here)
- app/services/user_service.py (not served here)
- app/services/write_plugin_service.py (not served here)
- app/utils/__init__.py (not served here)
- app/utils/embedding_helpers.py (not served here)
- app/utils/keyword_query.py (not served here)
- app/utils/provenance.py (not served here)
- app/utils/pydantic_helper.py (not served here)
- app/utils/rank_fusion.py (not served here)
- app/utils/repository_identity.py (not served here)
- app/utils/token_counter.py (not served here)
- app/version.py (not served here)
- architecture.md
- benchmarks/retrieval/README.md (not served here)
- benchmarks/retrieval/build_corpus.py (not served here)
- benchmarks/retrieval/corpus.jsonl (not served here)
- benchmarks/retrieval/eval_lib.py (not served here)
- benchmarks/retrieval/queries_curated.jsonl (not served here)
- benchmarks/retrieval/run_eval.py (not served here)
- default.nix (not served here)
- docker/.env.example (not served here)
- docker/Dockerfile (not served here)
- docker/docker-compose.postgres.yml (not served here)
- docker/docker-compose.sqlite.yml (not served here)
- docker/docker-compose.yml (not served here)
- docs/OFFLINE_SETUP.md (not served here)
- docs/api_reference.md
- docs/assets/mycelium_class_diagram.md (not served here)
- docs/concepts.md
- docs/configuration.md (not served here)
- docs/connectivity_guide.md (not served here)
- docs/copilot-cli/README.md (not served here)
- docs/copilot-cli/agents/forgetful-memory.agent.md (not served here)
- docs/copilot-cli/agents/knowledge-explorer.agent.md (not served here)
- docs/copilot-cli/agents/memory-curator.agent.md (not served here)
- docs/copilot-cli/skills/README.md (not served here)
- docs/dev/architecture-tests.md (not served here)
- docs/dev/cli_plan.md (not served here)
- docs/embedding_migration.md
- docs/features_roadmap.md
- docs/gemini-cli/README.md (not served here)
- docs/gemini-cli/commands/encode-repo.toml (not served here)
- docs/gemini-cli/commands/forgetful-setup.toml (not served here)
- docs/gemini-cli/commands/memory-explore.toml (not served here)
- docs/gemini-cli/commands/memory-list.toml (not served here)
- docs/gemini-cli/commands/memory-save.toml (not served here)
- docs/gemini-cli/commands/memory-search.toml (not served here)
- docs/images/Forgetful Architecture.drawio.png (not served here)
- docs/images/Forgetful Architecture.drawio_transparent.png (not served here)
- docs/images/avatar.png (not served here)
- docs/images/hero_banner.png (not served here)
- docs/images/layers.png (not served here)
- docs/nix.md
- docs/opencode/README.md (not served here)
- docs/opencode/commands/encode-repo.md (not served here)
- docs/opencode/commands/forgetful-setup.md (not served here)
- docs/opencode/commands/memory-explore.md (not served here)
- docs/opencode/commands/memory-list.md (not served here)
- docs/opencode/commands/memory-save.md (not served here)
- docs/opencode/commands/memory-search.md (not served here)
- docs/opencode/skills/README.md (not served here)
- docs/prompts/comprehensive_project_understanding_prompt.md (not served here)
- docs/prompts/custom_agent_integration.md (not served here)
- docs/prompts/example_system_prompt.md (not served here)
- docs/prompts/knowledge_base_bootstrap_prompt.md (not served here)
- docs/prompts/prompts_overview.md (not served here)
- docs/prompts/rapid_project_scan_prompt.md (not served here)
- docs/release_notes.md
- docs/search.md
- docs/self-hosting-guide.md
- docs/tool_reference.md
- examples/plan_policy.py (not served here)
- flake.lock (not served here)
- flake.nix (not served here)
- main.py (not served here)
- nix/test-fixtures.nix (not served here)
- org_knowledge_proposal.md
- pyproject.toml (not served here)
- pytest.ini (not served here)
- ruff.toml (not served here)
- shell.nix (not served here)
- skills/README.md (not served here)
- skills/forgetful-cli-setup/SKILL.md (not served here)
- skills/forgetful-context-gather/SKILL.md (not served here)
- skills/forgetful-encode-repo/SKILL.md (not served here)
- skills/forgetful-encode-repo/references/first-encode.md (not served here)
- skills/forgetful-encode-repo/references/refresh.md (not served here)
- skills/forgetful-entities/SKILL.md (not served here)
- skills/forgetful-explore/SKILL.md (not served here)
- skills/forgetful-files/SKILL.md (not served here)
- skills/forgetful-mcp-setup/SKILL.md (not served here)
- skills/forgetful-procedures/SKILL.md (not served here)
- skills/forgetful-recall/SKILL.md (not served here)
- skills/forgetful-remember/SKILL.md (not served here)
- test_harness/README.md (not served here)
- test_harness/__init__.py (not served here)
- test_harness/__main__.py (not served here)
- test_harness/config.py (not served here)
- test_harness/container.py (not served here)
- test_harness/docker/Dockerfile (not served here)
- test_harness/docker/opencode.json (not served here)
- test_harness/docker/runner.py (not served here)
- test_harness/prompts.py (not served here)
- test_harness/report.py (not served here)
- test_harness/server.py (not served here)
- test_harness/walkthrough.py (not served here)
- tests/__init__.py (not served here)
- tests/architecture/test_contracts.py (not served here)
- tests/backup_restore_cases.py (not served here)
- tests/docker/test_offline_image.py (not served here)
- tests/e2e/README.md (not served here)
- tests/e2e/conftest.py (not served here)
- tests/e2e/test_activity_user_scope_e2e.py (not served here)
- tests/e2e/test_api_activity.py (not served here)
- tests/e2e/test_api_memories_e2e.py (not served here)
- tests/e2e/test_auth_e2e.py (not served here)
- tests/e2e/test_auto_link_threshold_e2e.py (not served here)
- tests/e2e/test_backup_recovery_e2e.py (not served here)
- tests/e2e/test_cli_postgres_e2e.py (not served here)
- tests/e2e/test_code_artifact_tools_e2e.py (not served here)
- tests/e2e/test_cross_user_reference_checks_e2e.py (not served here)
- tests/e2e/test_document_tools_e2e.py (not served here)
- tests/e2e/test_embedding_concurrency.py (not served here)
- tests/e2e/test_entity_tools_e2e.py (not served here)
- tests/e2e/test_file_tools_e2e.py (not served here)
- tests/e2e/test_graph_e2e.py (not served here)
- tests/e2e/test_health_e2e.py (not served here)
- tests/e2e/test_hybrid_search_e2e.py (not served here)
- tests/e2e/test_link_memories_no_autolink_e2e.py (not served here)
- tests/e2e/test_memory_link_ownership_e2e.py (not served here)
- tests/e2e/test_memory_tools_e2e.py (not served here)
- tests/e2e/test_memory_usage_e2e.py (not served here)
- tests/e2e/test_memory_usage_tracking_disabled_e2e.py (not served here)
- tests/e2e/test_meta_tools_e2e.py (not served here)
- tests/e2e/test_obsolete_matches_e2e.py (not served here)
- tests/e2e/test_plan_external_ref_e2e.py (not served here)
- tests/e2e/test_plan_plugin_e2e.py (not served here)
- tests/e2e/test_plan_tools_e2e.py (not served here)
- tests/e2e/test_project_tools_e2e.py (not served here)
- tests/e2e/test_provenance_e2e.py (not served here)
- tests/e2e/test_re_embedding_e2e.py (not served here)
- tests/e2e/test_reranking_e2e.py (not served here)
- tests/e2e/test_retrieval_scores_e2e.py (not served here)
- tests/e2e/test_skill_tools_e2e.py (not served here)
- tests/e2e/test_task_tools_e2e.py (not served here)
- tests/e2e/test_user_creation_e2e.py (not served here)
- tests/e2e/test_user_tools_e2e.py (not served here)
- tests/e2e/test_zz_backup_restore_e2e.py (not served here)
- tests/e2e_provider_sessions/__init__.py (not served here)
- tests/e2e_provider_sessions/conftest.py (not served here)
- tests/e2e_provider_sessions/test_provider_sessions.py (not served here)
- tests/e2e_sqlite/conftest.py (not served here)
- tests/e2e_sqlite/test_api_activity_sqlite.py (not served here)
- tests/e2e_sqlite/test_api_auth.py (not served here)
- tests/e2e_sqlite/test_api_code_artifacts.py (not served here)
- tests/e2e_sqlite/test_api_documents.py (not served here)
- tests/e2e_sqlite/test_api_entities.py (not served here)
- tests/e2e_sqlite/test_api_files.py (not served here)
- tests/e2e_sqlite/test_api_graph.py (not served here)
- tests/e2e_sqlite/test_api_graph_limit_settings.py (not served here)
- tests/e2e_sqlite/test_api_memories.py (not served here)
- tests/e2e_sqlite/test_api_plans.py (not served here)
- tests/e2e_sqlite/test_api_projects.py (not served here)
- tests/e2e_sqlite/test_api_skills.py (not served here)
- tests/e2e_sqlite/test_api_task_actions.py (not served here)
- tests/e2e_sqlite/test_api_tasks.py (not served here)
- tests/e2e_sqlite/test_auth_cache_sqlite.py (not served here)
- tests/e2e_sqlite/test_auth_sqlite.py (not served here)
- tests/e2e_sqlite/test_auth_token_cache_sqlite.py (not served here)
- tests/e2e_sqlite/test_auto_link_threshold_sqlite.py (not served here)
- tests/e2e_sqlite/test_backup_restore_sqlite.py (not served here)
- tests/e2e_sqlite/test_cli_passthrough.py (not served here)
- tests/e2e_sqlite/test_cli_remote.py (not served here)
- tests/e2e_sqlite/test_cli_verbs.py (not served here)
- tests/e2e_sqlite/test_code_artifact_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_cross_user_reference_checks_sqlite.py (not served here)
- tests/e2e_sqlite/test_document_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_embedding_concurrency_sqlite.py (not served here)
- tests/e2e_sqlite/test_entity_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_feature_flags_sqlite.py (not served here)
- tests/e2e_sqlite/test_file_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_harness_server.py (not served here)
- tests/e2e_sqlite/test_health_sqlite.py (not served here)
- tests/e2e_sqlite/test_hybrid_search.py (not served here)
- tests/e2e_sqlite/test_link_memories_no_autolink_sqlite.py (not served here)
- tests/e2e_sqlite/test_memory_file_ids_sqlite.py (not served here)
- tests/e2e_sqlite/test_memory_link_ownership_sqlite.py (not served here)
- tests/e2e_sqlite/test_memory_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_meta_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_obsolete_matches_sqlite.py (not served here)
- tests/e2e_sqlite/test_plan_external_ref_storage.py (not served here)
- tests/e2e_sqlite/test_plan_plugin_storage.py (not served here)
- tests/e2e_sqlite/test_plan_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_project_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_provenance_sqlite.py (not served here)
- tests/e2e_sqlite/test_re_embedding_sqlite.py (not served here)
- tests/e2e_sqlite/test_reranking_concurrency_sqlite.py (not served here)
- tests/e2e_sqlite/test_reranking_sqlite.py (not served here)
- tests/e2e_sqlite/test_retrieval_scores_sqlite.py (not served here)
- tests/e2e_sqlite/test_scoped_permissions_sqlite.py (not served here)
- tests/e2e_sqlite/test_skill_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_task_tools_sqlite.py (not served here)
- tests/e2e_sqlite/test_token_scope_fail_open_sqlite.py (not served here)
- tests/e2e_sqlite/test_user_creation_sqlite.py (not served here)
- tests/e2e_sqlite/test_user_tools_sqlite.py (not served here)
- tests/integration/conftest.py (not served here)
- tests/integration/entity_plugin_helpers.py (not served here)
- tests/integration/plan_plugin_helpers.py (not served here)
- tests/integration/test_auth.py (not served here)
- tests/integration/test_auth_cache.py (not served here)
- tests/integration/test_auth_factory.py (not served here)
- tests/integration/test_auth_info.py (not served here)
- tests/integration/test_auth_token_cache.py (not served here)
- tests/integration/test_azure_embedding_concurrency.py (not served here)
- tests/integration/test_azure_embeddings_adapter.py (not served here)
- tests/integration/test_backup_service.py (not served here)
- tests/integration/test_bootstrap.py (not served here)
- tests/integration/test_capabilities.py (not served here)
- tests/integration/test_cli_dispatch.py (not served here)
- tests/integration/test_cli_local_executor.py (not served here)
- tests/integration/test_cli_remote_executor.py (not served here)
- tests/integration/test_cli_verbs_mapping.py (not served here)
- tests/integration/test_code_artifact_service.py (not served here)
- tests/integration/test_config_precedence.py (not served here)
- tests/integration/test_dns_record_security.py (not served here)
- tests/integration/test_document_service.py (not served here)
- tests/integration/test_entity_plugin_cli.py (not served here)
- tests/integration/test_entity_plugin_phases.py (not served here)
- tests/integration/test_entity_plugin_runtime.py (not served here)
- tests/integration/test_entity_plugin_transports.py (not served here)
- tests/integration/test_entity_service.py (not served here)
- tests/integration/test_event_bus.py (not served here)
- tests/integration/test_fastembed_concurrency.py (not served here)
- tests/integration/test_fastembed_offline.py (not served here)
- tests/integration/test_file_service.py (not served here)
- tests/integration/test_graph_service_plan_task.py (not served here)
- tests/integration/test_harness_cli.py (not served here)
- tests/integration/test_harness_config.py (not served here)
- tests/integration/test_harness_container.py (not served here)
- tests/integration/test_harness_report.py (not served here)
- tests/integration/test_harness_walkthrough.py (not served here)
- tests/integration/test_http_reranker_adapter.py (not served here)
- tests/integration/test_keyword_query.py (not served here)
- tests/integration/test_local_reranker_concurrency.py (not served here)
- tests/integration/test_memory_fts_unicode.py (not served here)
- tests/integration/test_memory_null_transports.py (not served here)
- tests/integration/test_memory_null_updates.py (not served here)
- tests/integration/test_memory_plugin_phases.py (not served here)
- tests/integration/test_memory_score_serialization.py (not served here)
- tests/integration/test_memory_service.py (not served here)
- tests/integration/test_memory_usage_tracking.py (not served here)
- tests/integration/test_memory_write_plugin.py (not served here)
- tests/integration/test_meta_tools_docstrings.py (not served here)
- tests/integration/test_obsolete_warning_gate.py (not served here)
- tests/integration/test_obsolete_warning_settings.py (not served here)
- tests/integration/test_ollama_embeddings_adapter.py (not served here)
- tests/integration/test_onnx_providers.py (not served here)
- tests/integration/test_openai_embedding_concurrency.py (not served here)
- tests/integration/test_openai_embeddings_adapter.py (not served here)
- tests/integration/test_plan_plugin_baseline.py (not served here)
- tests/integration/test_plan_plugin_cli.py (not served here)
- tests/integration/test_plan_plugin_runtime.py (not served here)
- tests/integration/test_plan_plugin_transports.py (not served here)
- tests/integration/test_plan_service.py (not served here)
- tests/integration/test_project_service.py (not served here)
- tests/integration/test_provenance.py (not served here)
- tests/integration/test_rank_fusion.py (not served here)
- tests/integration/test_re_embedding_service.py (not served here)
- tests/integration/test_rest_auth.py (not served here)
- tests/integration/test_retrieval_benchmark_lib.py (not served here)
- tests/integration/test_rrf_tie_break.py (not served here)
- tests/integration/test_scope_resolver.py (not served here)
- tests/integration/test_service_activity_events.py (not served here)
- tests/integration/test_skill_frontmatter_quoting.py (not served here)
- tests/integration/test_skill_service.py (not served here)
- tests/integration/test_targeted_rebuild_sqlite.py (not served here)
- tests/integration/test_task_service.py (not served here)
- tests/integration/test_token_scope_fail_open.py (not served here)
- tests/integration/test_tool_registry.py (not served here)
- tests/integration/test_trace_context_security.py (not served here)
- tests/integration/test_unobsolete_memory.py (not served here)
- tests/integration/test_user_service.py (not served here)
- tests/integration/test_write_plugin_cli.py (not served here)
- tests/integration/test_write_plugin_runtime.py (not served here)
- tests/integration/test_write_plugin_transports.py (not served here)
- tests/plan_external_ref_cases.py (not served here)
- tests/plan_plugin_cases.py (not served here)
- tests/user_creation_cases.py (not served here)
- uv.lock (not served here)
Advantages
- Automatic knowledge graph construction through semantic linking of atomic memories. evidence: README.md
- Maintains context window efficiency via configurable token budgets and importance-based ranking. evidence: README.md
- Flexible deployment options ranging from zero-config local SQLite to scalable PostgreSQL. evidence: README.md
Limitations
- Requires adherence to the Zettelkasten principle, which may be restrictive for some workflows. evidence: README.md
- Limits the number of tools exposed to the agent to preserve context window, potentially hiding advanced functionality. evidence: README.md
Security
Risk level: Medium risk
This brain runs
Agent instructions that run or fetch something (34)
AGENTS.md:Run `uv run pytest tests/architecture/` to check and prove the agreed import boundaries.AGENTS.md:**Location**: `tests/integration/` **Purpose**: Test business logic with stubbed I/O (no real database required) **Run locally**:AGENTS.md:uv run pytest tests/integration/AGENTS.md:These tests use in-memory stubs and run fast (~seconds).AGENTS.md:**Location**: `tests/e2e_sqlite/` **Purpose**: Test complete stack with in-memory SQLite **Requirements**: None (no Docker required) **Run locally**:AGENTS.md:uv run pytest tests/e2e_sqlite/AGENTS.md:**Location**: `tests/e2e/` **Purpose**: Test complete stack with real PostgreSQL **Requirements**: PostgreSQL running in Docker **Run locally**:AGENTS.md:uv run pytest -m e2eAGENTS.md:Ensure that you run ruff following any changes and address any issues raisedAGENTS.md:uv tool run ruff check .skills/forgetful-cli-setup/SKILL.md:The CLI is the shell-native surface: same tool registry as MCP, reachable by anything that can run a command.skills/forgetful-cli-setup/SKILL.md:After changing embedding provider or model: `forgetful re-embed --dry-run` to preview, then `forgetful re-embed` (batch size tunable via `--batch-size`).skills/forgetful-context-gather/SKILL.md:Run MCP-flavored gathers in the main conversation.skills/forgetful-context-gather/SKILL.md:Done when: every angle has run and its outcome is recorded.skills/forgetful-encode-repo/SKILL.md:this skill moves it, and only after a run has reviewed every change up to the new commit.skills/forgetful-encode-repo/SKILL.md:Run git in the repository being encoded (the current directory unless the user named one).skills/forgetful-encode-repo/SKILL.md:**HEAD**: `git rev-parse HEAD`.skills/forgetful-encode-repo/SKILL.md:Unless the user names another range end, this is the end commit: everything this run writes describes it.skills/forgetful-encode-repo/SKILL.md:**Clean worktree**: `git status --porcelain` prints nothing.skills/forgetful-encode-repo/SKILL.md:**Project**: `git remote get-url origin` → `owner/repo` → `list_projects` with `repo_name`.skills/forgetful-encode-repo/SKILL.md:Checks: the checkpoint is a commit here when `git rev-parse --verify --quiet <sha>^{commit}` prints the stored value itself;skills/forgetful-encode-repo/SKILL.md:`git merge-base --is-ancestor <sha> <end>` succeeds when it is an ancestor.skills/forgetful-encode-repo/SKILL.md:Done when: the branch decision is written, and each value in it comes from a command or tool result in this run.skills/forgetful-encode-repo/SKILL.md:**Retrieval**: when the run wrote knowledge, `query_memory` scoped to the project with `strict_project_filter` true and the questions this encoding should answer (how the system fits together, each changed area under its current name).skills/forgetful-encode-repo/SKILL.md:**Pinning**: `git rev-parse HEAD` still matches Step 1, `git status --porcelain` still prints nothing, and `get_project` still shows the checkpoint read in Step 1.skills/forgetful-encode-repo/SKILL.md:Advance the checkpoint only when the run recorded no gaps and the range leaves no unreviewed commit (see user ranges in Step 2).skills/forgetful-encode-repo/SKILL.md:Build it from tool results in this run: an ID or count appears only when a response confirmed it, and a read that failed is reported as unknown.skills/forgetful-encode-repo/SKILL.md:Correct the call against the operation's schema and run it again;skills/forgetful-mcp-setup/SKILL.md:**stdio** — the client spawns the server per session: command `uvx forgetful-ai` (equivalently `forgetful serve --transport stdio`).skills/forgetful-mcp-setup/SKILL.md:Recognised scopes in verified token `scope`/`scp` claims can narrow MCP access further;· uses the networkskills/forgetful-mcp-setup/SKILL.md:Run Forgetful MCP calls in the main conversation — subagents do not inherit MCP tool access.skills/forgetful-procedures/SKILL.md:All skill operations run through the standard invocation surface below, the same as every other domain.skills/forgetful-recall/SKILL.md:Run it as a deliberate step, then continue into normal recall as the task demands.skills/forgetful-remember/SKILL.md:Derive the candidate from the repo: `git remote get-url origin` → `owner/repo` → `list_projects` with `repo_name`.
MCP servers (2)
README.md(forgetful):uvx forgetful-aiREADME.md(forgetful):http://localhost:8020/mcp· uses the network
Install scripts (1)
app/bootstrap.py:python app/bootstrap.py
Package scripts (1)
pyproject.toml(build-hook):hatch build hook vcs (hatch_build.py)
- Medium risk: runs-mcp-server-unpinned-runner (README.md:159)
- Medium risk: runs-instruction-instruction-network (skills/forgetful-mcp-setup/SKILL.md:51)
- Low risk: scripts-present (app/bootstrap.py)
- Low risk: network-instructions (skills/forgetful-cli-setup/SKILL.md:25)
Attribution and licence
- Created by
- Scott
- Declared authors
- Scott (declared in pyproject.toml)
- Publisher
- Scott Raisbeck (Community)
- Source
- ScottRBK/forgetful · commit 9f85ddc
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Scott.
Install from source
452 of its files are not served here, so there is no ZIP. ScottRBK/forgetful at 9f85ddc