# Context Library

> Open-source MCP context persistence layer for AI sessions. Append-only handoffs, pgvector semantic search, OAuth2 auth. Model-agnostic.

- **Type:** MCP server
- **Install:** `agentstack add mcp-onideus-context-library`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [onideus](https://agentstack.voostack.com/s/onideus)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [onideus](https://github.com/onideus)
- **Source:** https://github.com/onideus/context-library

## Install

```sh
agentstack add mcp-onideus-context-library
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Context Library

[](https://github.com/onideus/context-library/actions/workflows/ci.yml)
[](https://github.com/onideus/context-library/actions/workflows/image.yml)
[](https://github.com/onideus/context-library/releases/latest)
[](LICENSE)

A personal MCP server that provides persistent operational context, task management, knowledge capture, artifact tracking, and semantic search across AI assistant sessions. Model-agnostic, Docker-ready, designed for single-user cognitive infrastructure.

## What It Does

AI assistants lose all context between conversations. Context Library solves this by providing MCP tools that any compatible assistant can use to store and retrieve operational state, track tasks, capture permanent knowledge, and search across accumulated history.

The server name is configurable via the `SERVER_NAME` environment variable (default: `context-library`). Name it whatever fits your mental model.

## Deployment Tiers

Context Library is designed to be deployed incrementally. Each tier adds functionality on top of the previous one, using Docker Compose file stacking.

### Tier 1: Core (Handoffs Only)

The simplest deployment. Stores and retrieves operational context as append-only JSON files. No database required.

```bash
docker compose up -d
```

**Available tools:** `store_handoff`, `get_latest_handoff`, `patch_handoff`, `list_handoffs`, `get_handoff`

> Handoff files are retained indefinitely by default (`RETENTION_COUNT=0`). For long-lived deployments, set `RETENTION_COUNT` to a positive number (e.g., `5000`) to cap disk growth — older handoffs are pruned along with their search-index entries. The tradeoff: higher retention keeps more history searchable; lower retention keeps the disk footprint tight. Compaction (automatic after each store) reduces per-file size either way.

### Tier 2: + PostgreSQL (Tasks + Knowledge + Artifacts + Full-Text Search)

Adds structured task management, permanent knowledge capture, generated-output tracking, and full-text search. Requires PostgreSQL 16 with pgvector.

```bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml up -d
```

**Additional tools:** `create_task`, `get_task`, `list_tasks`, `update_task`, `search_tasks`, `create_note`, `get_note`, `list_notes`, `search_notes`, `update_note`, `delete_note`, `store_artifact`, `get_artifact`, `list_artifacts`, `search_artifacts`, `update_artifact`

### Tier 3: + Embeddings (Semantic Search)

Adds vector-based semantic search across all stored content using a Text Embeddings Inference (TEI) server. Use the `--profile` flag to select GPU or CPU runtime.

**GPU (desktop with NVIDIA GPU):**
```bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml -f docker-compose.embeddings.yml --profile embeddings-gpu up -d
```

**CPU (NAS or any machine without GPU):**
```bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml -f docker-compose.embeddings.yml --profile embeddings-cpu up -d
```

With no `--profile` flag, neither TEI service starts — the application degrades gracefully (semantic search falls back to FTS).

**Additional tools:** `search_context`, `reindex`

The TEI server can run on a separate machine — just point `EMBEDDING_URL` to its address. This is the recommended setup if your main server doesn't have a GPU.

#### Optional: Cross-Encoder Reranker

For improved retrieval precision, an optional cross-encoder reranker rescores candidates after RRF fusion. It runs as a second TEI instance:

```bash
# Add to your compose command:
--profile reranker-gpu   # or reranker-cpu
```

When the reranker is not configured or unreachable, `search_context` falls back to RRF-only ordering. Set `RERANKER_URL` in your `.env` to enable it.

#### Embedding Server Platform Options

| Platform | Profile / Method | GPU Acceleration |
|---|---|---|
| **Linux/Windows (NVIDIA GPU)** | `--profile embeddings-gpu` | CUDA (compute capability 7.5+) |
| **Linux/Windows (no GPU)** | `--profile embeddings-cpu` | None (CPU only, x86_64) |
| **Apple Silicon / ARM servers (Docker)** | `--profile embeddings-arm64` | None (CPU only, native ARM) |
| **macOS Apple Silicon (native)** | Homebrew: `text-embeddings-inference` | Metal (via native binary only) |

> **Apple Silicon note:** macOS does not support GPU passthrough into Docker containers. Running TEI in Docker on M-series Macs will be CPU-bound and slow. For CPU-only Docker deployment on Apple Silicon, use `--profile embeddings-arm64`. For Metal GPU acceleration, install TEI natively via Homebrew and run it outside of Docker:
>
> ```bash
> brew tap huggingface/tap
> brew install huggingface/tap/text-embeddings-inference
> text-embeddings-router --model-id nomic-ai/nomic-embed-text-v2-moe --port 8090
> ```
>
> Then set `EMBEDDING_URL=http://host.docker.internal:8090` (Docker) or `EMBEDDING_URL=http://localhost:8090` (local dev) so Context Library can reach it.

### Tier 4: + Entity Extraction (Knowledge Graph)

Adds background extraction of entity triples (subject → relation → object) from handoffs and notes into a queryable knowledge graph. Extraction runs against an external LLM provider — either a local Ollama instance or an Anthropic/OpenAI-compatible API.

```bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml -f docker-compose.entities.yml up -d
```

Extraction is disabled by default (`ENTITY_EXTRACTION_ENABLED=false`) and is fully fire-and-forget: if the provider is unreachable, handoff and note writes still succeed and a warning is logged. Ollama itself is not managed by Compose — point `OLLAMA_BASE_URL` at wherever it runs.

**Additional tools:** `extract_entities`, `run_extraction`, `compare_extractions`, `list_extraction_runs`, `browse_entities`, `entity_relations`

## Architecture

- **Server:** Hono 4.x + StreamableHTTP MCP transport (Node.js 22, TypeScript)
- **Storage (Tier 1):** Append-only JSON files in `./data/handoffs/`
- **Database (Tier 2):** PostgreSQL 16 with pgvector extension
- **Content primitives:** Handoffs (ephemeral session state), Tasks (lifecycle-managed action items), Notes (permanent knowledge — decisions, patterns, insights), Artifacts (generated outputs with lifecycle state and execution ordering)
- **Embeddings (Tier 3):** Text Embeddings Inference with nomic-embed-text-v2-moe (768 dims), optional cross-encoder reranker
- **Search:** Hybrid retrieval (vector + FTS with RRF fusion), optional cross-encoder reranking, entity-aware context envelopes, search alias expansion, date-range filtering
- **Auth:** Handled externally by [mcp-auth-proxy](https://github.com/sigbit/mcp-auth-proxy) — the server itself is unauthenticated and trusts its network boundary

Each component degrades gracefully when unavailable. If Postgres is down, handoffs still work. If the embedding server is unreachable, task, note, and artifact search still works via full-text search; failed embeddings are queued for automatic retry when TEI comes back.

## The Autonomous Pipeline Pattern

The four content primitives (handoffs, tasks, notes, artifacts) are enough substrate to run an autonomous build pipeline against your own repositories. A planning session stores `ready` artifacts. A separate interceptor process polls `list_artifacts`, claims work by transitioning status to `executing`, runs the artifact content as a prompt against a target repo, opens a PR, gates the merge behind adversarial review + CI, and writes a digest note back to Context Library.

The reference implementation is private. What is documented here is the pattern — the contracts between planner, artifact store, interceptor, and review gate — so you can build your own on top of a Tier 2+ deployment. See [docs/pipeline/](docs/pipeline/README.md) for the full write-up: lifecycle rules, governance model, replication spec, and worked example.

## MCP Tools

| Tool | Tier | Description |
|---|---|---|
| `store_handoff` | Core | Full-state capture at session boundaries (append-only) |
| `get_latest_handoff` | Core | Retrieve most recent handoff with pre-computed fields |
| `patch_handoff` | Core | Partial update with merge semantics |
| `list_handoffs` | Core | Browse historical handoffs by date with metadata |
| `get_handoff` | Core | Retrieve a specific historical handoff by filename |
| `create_task` | Postgres | Create task with scope, priority, tags, dates |
| `get_task` | Postgres | Retrieve task by UUID |
| `list_tasks` | Postgres | Paginated filtering with status, scope, priority, tags |
| `update_task` | Postgres | Field updates + lifecycle actions (complete/cancel/defer/reopen) |
| `search_tasks` | Postgres | Full-text search with PostgreSQL FTS |
| `create_note` | Postgres | Capture permanent knowledge (decisions, patterns, insights) |
| `get_note` | Postgres | Retrieve note by UUID |
| `list_notes` | Postgres | Browse notes with scope, domain, and tag filters |
| `search_notes` | Postgres | Full-text search across note titles and content |
| `update_note` | Postgres | Update note fields; re-embeds on content change |
| `delete_note` | Postgres | Permanently delete a note and its embedding |
| `store_artifact` | Postgres | Capture a generated output (CC prompt, research, template) with lifecycle state |
| `get_artifact` | Postgres | Retrieve artifact by UUID (full content + pointer + metadata) |
| `list_artifacts` | Postgres | Browse artifacts with type, status, scope, and tag filters; execution_order-aware sort |
| `search_artifacts` | Postgres | Full-text search across artifact titles and content |
| `update_artifact` | Postgres | Update artifact fields; enforces status transitions; re-embeds on content change |
| `search_context` | Embeddings | Hybrid semantic search (vector + FTS with RRF fusion) across all content types |
| `reindex` | Embeddings | Rebuild semantic search index for handoffs, tasks, notes, and artifacts |
| `extract_entities` | Entities | Trigger entity extraction on a single content item |
| `run_extraction` | Entities | Batch-extract entities from multiple content items |
| `compare_extractions` | Entities | Compare two extraction runs (e.g., different providers or models) |
| `list_extraction_runs` | Entities | List recent entity extraction runs with stats |
| `browse_entities` | Entities | Browse the extracted entity graph with type and name filters |
| `entity_relations` | Entities | Retrieve the relation graph for a specific entity |

The server also registers three MCP prompts as workflow entry points: `session_start` (load handoff state at conversation start), `architect` (load prior design decisions before architecture discussions), and `plan` (load task and artifact state before planning).

## Health Checks

The server exposes two health endpoints:

- **`GET /health`** — Basic liveness check. Returns server status, version, and uptime.
- **`GET /health/ready`** — Readiness check. Verifies the data directory is writable. Returns `"ok"` (HTTP 200) or `"degraded"` (HTTP 503) accordingly.

Both return JSON. Use `/health` for uptime monitoring and `/health/ready` after deployment to confirm the server can write data.

```bash
curl http://localhost:3100/health
# {"status":"ok","version":"0.10.0","uptime":42}

curl http://localhost:3100/health/ready
# {"status":"ok","writable":true,"uptime":42}
```

## Quick Start

### Prerequisites

- Docker and Docker Compose
- For local development without Docker: Node.js 22+
- For external access: an OIDC provider (Auth0, Google, etc.) and a reverse proxy or tunnel
- For Tier 3 embeddings: an NVIDIA GPU (Linux/Windows), or Apple Silicon Mac with Homebrew, or any CPU (slower)

### Setup

```bash
git clone https://github.com/onideus/context-library.git
cd context-library
cp .env.example .env
# Edit .env with your configuration
```

> **Data directory ownership:** The container runs as `appuser` (UID 999). If you're migrating data from an existing deployment or running on a NAS, ensure the `data/` directory is owned by the correct UID:
>
> ```bash
> sudo chown -R 999:999 ./data
> ```
>
> Without this, the server will fail with `EACCES: permission denied` when writing handoff files. The `proxy-data/` and `proxy-certs/` directories (used by `mcp-auth-proxy`) do not need this — the proxy runs as root.

### Local Development

```bash
npm install
npm run dev          # Start with hot reload (tsx watch)
npm test             # Run test suite
npm run build        # TypeScript compile
```

The server starts on `http://localhost:3100` by default. The MCP endpoint is at `http://localhost:3100/mcp`. Verify it's running:

```bash
curl http://localhost:3100/health
```

## Connecting MCP Clients

Once Context Library is running (either via `npm run dev` or Docker), you can connect any MCP-compatible client. The server uses **Streamable HTTP** transport on a single endpoint: `http://localhost:3100/mcp`.

### Roo Code (VS Code)

Roo Code is the most common local setup. Open your MCP settings (click the MCP icon in the Roo Code panel, then **Edit Global MCP** or **Edit Project MCP**) and add:

```json
{
  "mcpServers": {
    "context-library": {
      "type": "streamable-http",
      "url": "http://localhost:3100/mcp"
    }
  }
}
```

For project-level configuration, create `.roo/mcp.json` in your project root with the same content. Project-level configs override global settings and can be committed to version control so your whole team shares the same MCP setup.

Save the file and Context Library should appear in the MCP servers list with a connected status. Roo Code will discover all available tools automatically.

### Claude Code (Terminal)

```bash
claude mcp add context-library --transport http http://localhost:3100/mcp
```

This registers the server globally. Claude Code will connect on next launch.

### Claude Desktop

Add to your Claude Desktop config file:

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**Windows (Store):** `%LOCALAPPDATA%\Packages\Claude_\LocalCache\Roaming\Claude\claude_desktop_config.json`

Claude Desktop does not natively support remote HTTP MCP servers. Use [mcp-remote](https://github.com/geelen/mcp-remote) as a stdio bridge:

```json
{
  "mcpServers": {
    "context-library": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:3100/mcp"]
    }
  }
}
```

Restart Claude Desktop after saving.

### Claude.ai (Hosted)

Claude.ai requires the server to be publicly accessible with OAuth authentication. See [External Access with Auth Proxy](#external-access-with-auth-proxy) below.

### Other MCP Clients

Any client that supports Streamable HTTP transport can connect to `http://localhost:3100/mcp`. This includes VS Code with GitHub Copilot, Cursor, Windsurf, Continue, and others. Consult your client's documentation for the MCP server configuration format — typically you need to specify the URL and transport type (`streamable-http` or `streamableHttp` depending on the client).

### Verifying the Connection

After connecting, ask your AI assistant to call `get_latest_handoff`. If it returns a handoff (or an empty-state response on first use), the connection is working. You can also hit the health endpoint directly:

```bash
curl http://localhost:3100/health
# {"status":"ok","version":"0.10.0","uptime":42}
```

## External Access with Auth Proxy

To expose Context Library to the internet (required for Claude.ai and other hosted MCP clients), use the auth compose overlay. It bundles [mcp-auth-proxy](https://github.com/sigbit/mcp-auth-proxy) (OAuth 2.1 gateway) and a [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) connector so the full ingress chain is managed as a single stack:

```
Internet → cloudflared → mcp-auth-proxy:443 → context-library:3100
```

### Auth Proxy Setup

```bash
docker compose \
  -f docker-compose.yml \
  -f docker-compose.postgres.yml \
  -f docker-compose.auth.yml \
  up -d
```

Fo

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [onideus](https://github.com/onideus)
- **Source:** [onideus/context-library](https://github.com/onideus/context-library)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-onideus-context-library
- Seller: https://agentstack.voostack.com/s/onideus
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
