Skip to main content
Glama
1318176013

project-memory-mcp

by 1318176013

project-memory-mcp

A TypeScript MCP server for project memory: it stores manual project memories, retrieves them semantically, and tracks per-memory confidence. Metadata and vectors both live in PostgreSQL (via the pgvector extension), and embeddings come from an OpenAI-compatible API.

Architecture

  • MCP server exposes tools over stdio.

  • PostgreSQL stores projects, memories, confidence feedback, and memory embeddings (pgvector vector column). Semantic search is exact cosine KNN in SQL — at this server's scale (memories are project knowledge, not a code index) a dedicated vector DB added a second store to keep consistent for no retrieval benefit.

  • Embeddings are generated by a configurable OpenAI-compatible /v1/embeddings API.

  • PostgreSQL is an external service. This server only reads its address from config, and requires the pgvector extension (the migrations run CREATE EXTENSION IF NOT EXISTS vector).

Related MCP server: MCP Memory Server

Tools

These are the tools exposed over MCP (stdio and the HTTP /mcp endpoint). The server stores and retrieves manual project memories only; it never reads project source files. Clients contribute knowledge through add_memory.

Setup and health:

  • help: start here. Returns a guide to call order, tool arguments, how projectId works, and the scaffold (files + contents) to wire a project into the auto-memory workflow. Takes no arguments.

  • health_check: check PostgreSQL and embedding API connectivity.

  • register_project: register a project and obtain a server-generated projectId used to scope all other tools.

Retrieval:

  • search_knowledge: semantic search across project memories.

Memory management:

  • add_memory: add manual knowledge and index it.

  • list_memories: list memories with optional archived/kind/tag filters.

  • update_memory: update a memory and refresh its embedding.

  • archive_memory: archive a memory so it no longer appears in search results.

Confidence:

  • record_confidence_feedback: submit trust feedback for a memory.

  • get_confidence: read computed confidence for a memory.

  • list_confidence_feedback: list feedback records for audit.

  • list_suspect_confidence: list suspect or rejected memories.

Configuration

Service config controls infrastructure:

{
  "database": {
    "urlEnv": "DATABASE_URL"
  },
  "embedding": {
    "provider": "openai-compatible",
    "baseUrl": "https://api.example.com/v1",
    "apiKeyEnv": "EMBEDDING_API_KEY",
    "model": "embedding-model-name",
    "dimensions": 1536,
    "batchSize": 64
  }
}

Project config identifies the project:

{
  "projectId": "my-project",
  "name": "My Project"
}

projectId scopes all retrieval, memory, and confidence data. name is optional and used only for display. An optional root may be supplied for informational display in the capability manifest, but the server never reads project files — retrieval isolation is keyed solely on projectId.

Local Dependencies

PostgreSQL (with pgvector) is started separately. For local development only, this repo includes a commented docker-compose.yml that uses the pgvector/pgvector:pg16 image:

docker compose up -d postgres

Then set:

cp .env.example .env

Fill EMBEDDING_API_KEY and make sure DATABASE_URL points at your PostgreSQL service.

Install And Build

pnpm install
pnpm build

CLI

project-memory migrate \
  --service-config ./examples/project-memory.service.json \
  --project-config ./examples/project-memory.config.json

project-memory search "where is authentication handled?" \
  --service-config ./examples/project-memory.service.json \
  --project-config ./examples/project-memory.config.json

project-memory add-memory \
  --title "Use API embeddings" \
  --content "The first version uses an OpenAI-compatible embedding API instead of self-hosted embeddings." \
  --kind decision

project-memory feedback \
  --target-id mem_xxx \
  --signal contradict \
  --rationale "This advice conflicts with the current project convention."

project-memory confidence --target-id mem_xxx

Other CLI commands:

project-memory list-memories [--include-archived] [--kind <k>] [--tag <t>] [--limit <n>]
project-memory update-memory --id mem_xxx [--title ...] [--content ...] [--kind ...] [--tags a,b] [--source ...]
project-memory archive-memory --id mem_xxx
project-memory list-feedback [--target-id mem_xxx] [--limit <n>]
project-memory list-suspect

Confidence starts at 0.7. Feedback signals are support, confirm, dispute, contradict, obsolete, and uncertain: support/confirm raise confidence, while dispute/contradict/obsolete/uncertain lower it. Very low confidence records are marked suspect or rejected; rejected memories are excluded from retrieval, and suspect memories are heavily down-ranked.

MCP Client Example

There are two ways to connect, depending on where the server runs.

Local (stdio)

Use this when the server binary lives on the same machine as the MCP client, which spawns it as a child process over stdio:

{
  "mcpServers": {
    "project-memory": {
      "command": "node",
      "args": ["/path/to/project-memory-mcp/dist/index.js"],
      "env": {
        "PROJECT_MEMORY_SERVICE_CONFIG": "/path/to/project-memory.service.json",
        "PROJECT_MEMORY_PROJECT_CONFIG": "/path/to/project-memory.config.json",
        "DATABASE_URL": "postgres://project_memory:project_memory@localhost:5432/project_memory",
        "EMBEDDING_API_KEY": "your-api-key"
      }
    }
  }
}

Remote (HTTP)

When the server runs elsewhere — for example in a Docker container on another host — the client cannot spawn it over stdio. Connect over the Streamable HTTP /mcp endpoint instead. Both Claude Code and Codex support remote HTTP MCP servers natively; no stdio bridge is required.

The /mcp endpoint does not require the bearer token, so MCP clients connect without an Authorization header. The token only guards the read-only REST endpoints (see HTTP Endpoint).

Claude Code — add via the CLI (user scope is the most reliable for remote servers):

claude mcp add --transport http --scope user project-memory \
  https://your-host:8788/mcp

Or in ~/.claude.json:

{
  "mcpServers": {
    "project-memory": {
      "type": "http",
      "url": "https://your-host:8788/mcp"
    }
  }
}

Codex — in ~/.codex/config.toml:

[mcp_servers.project-memory]
url = "https://your-host:8788/mcp"

After connecting, call register_project once to obtain a projectId, then pass that projectId to search_knowledge, add_memory, and the other project-scoped tools.

HTTP Endpoint

The stdio MCP entry remains the default for local MCP clients. A network entry is also available for agents that can connect over HTTP:

pnpm start:http

Defaults:

http://127.0.0.1:8788

Useful endpoints:

GET  /                      Capability manifest: what this MCP is and what it can do.
GET  /help                  Usage guide: call order, tool arguments, and the auto-memory scaffold.
GET  /health                PostgreSQL and embedding API health.
GET  /status                Dependency health for the configured project.
GET  /tools                 Tool names and descriptions.
GET  /memories              List memories (query: includeArchived, kind, tag, limit, projectId).
GET  /confidence/suspect    List suspect or rejected memories.
GET  /confidence/feedback   List confidence feedback (query: targetId, limit, projectId).
POST /mcp                   MCP Streamable HTTP endpoint.
GET  /mcp                   MCP Streamable HTTP SSE stream when supported by the client.

Configure the bind address with:

PROJECT_MEMORY_HTTP_HOST=127.0.0.1
PROJECT_MEMORY_HTTP_PORT=8788
PROJECT_MEMORY_HTTP_TOKEN=change-me

When PROJECT_MEMORY_HTTP_TOKEN is set, the read-only REST endpoints require:

Authorization: Bearer <token>

Two endpoints are exempt from the token:

  • /health — so external health checks work without credentials.

  • /mcp — MCP Streamable HTTP clients (Claude Code, Codex) do not reliably forward custom headers on every request during the initialize/session handshake, so the MCP endpoint is reachable without the token. This is intended for the trusted deployment this server targets; do not expose /mcp to untrusted networks.

Example:

curl http://127.0.0.1:8788/ \
  -H "Authorization: Bearer $PROJECT_MEMORY_HTTP_TOKEN"

Docker Deployment

The deployment image runs only the Project Memory MCP HTTP server. PostgreSQL (with pgvector) and the embedding API remain external services.

Build:

docker build -t project-memory-mcp:local .

Run:

docker run --rm -p 8788:8788 \
  -e PROJECT_MEMORY_HTTP_TOKEN="change-me" \
  -e DATABASE_URL="postgres://user:password@postgres-host:5432/project_memory" \
  -e EMBEDDING_BASE_URL="https://api.example.com/v1" \
  -e EMBEDDING_MODEL="text-embedding-3-small" \
  -e EMBEDDING_DIMENSIONS="1536" \
  -e EMBEDDING_BATCH_SIZE="64" \
  -e EMBEDDING_API_KEY="your-key" \
  project-memory-mcp:local

Or use the deployment compose file:

PROJECT_MEMORY_HTTP_TOKEN="change-me" \
DATABASE_URL="postgres://user:password@postgres-host:5432/project_memory" \
EMBEDDING_BASE_URL="https://api.example.com/v1" \
EMBEDDING_MODEL="text-embedding-3-small" \
EMBEDDING_DIMENSIONS="1536" \
EMBEDDING_API_KEY="your-key" \
docker compose -f docker-compose.deploy.yml up -d

Health check:

curl http://127.0.0.1:8788/health

Capability manifest:

curl http://127.0.0.1:8788/ \
  -H "Authorization: Bearer change-me"

Operations

For production deployments, see docs/OPERATIONS.md. It covers:

  • Fresh deployment — empty PostgreSQL → running server, including how schema migrations run automatically at startup.

  • Backup / restore — all state is in PostgreSQL; a pg_dump is a complete backup (the pgvector vector column included).

  • Re-embedding — changing embedding.model or dimensions invalidates every stored vector; the doc gives the re-embed procedure.

  • Connection pool & timeout tuning — the PostgreSQL pool and the embedding HTTP request are both bounded so a slow dependency cannot hang requests. Defaults are conservative; override via env:

DATABASE_POOL_MAX=10                      # max pooled PostgreSQL connections
DATABASE_POOL_IDLE_TIMEOUT_MS=30000       # idle client eviction
DATABASE_POOL_CONNECTION_TIMEOUT_MS=10000 # fail fast if no connection acquired
EMBEDDING_REQUEST_TIMEOUT_MS=30000        # abort a hung embedding API call

These may also be set under database.pool and embedding.requestTimeoutMs in the service config.

Notes

This server is intentionally memory-centric: it stores manual project memories, retrieves them semantically, and tracks per-memory confidence from agent feedback.

Two earlier subsystems were removed once they proved to be write-only dead weight. PostgreSQL graph nodes/edges were only ever written, never read. A code/document indexing pipeline (scan → chunk → embed → store) was also removed: the server runs remotely and never has access to project source files, local agents read source directly, and search_knowledge only ever read memory vectors — never the chunk vectors the pipeline produced. Removing both kept the runtime lean and the responsibility singular.

Vector storage was then consolidated out of Qdrant into PostgreSQL via pgvector. Once code indexing was gone, the vector store held only memory vectors — a few hundred per project, filtered by projectId before any comparison — where exact cosine KNN in SQL is fast and accurate. The dedicated vector DB only added a second store to keep consistent (the dual-write orphan-handling that add/update/archive carried) for no retrieval benefit at that scale. If a large-scale code index ever returns, a dedicated vector DB may be worth reintroducing; at the current scope it is not.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/1318176013/project-memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server