Skip to main content
Glama

memory-agents-mcp

Unified MCP server for LAN agents (Hermes, Codex, Claude Code, ...) to share memory: native agent memory (memory_remember/memory_recall/ memory_forget/memory_list, backed by a memories table in Postgres + pgvector, embeddings via Ollama) plus a thin adapter over the existing Obsidian-vault memory-service (kb_search/kb_recall/kb_read_page/ kb_write_page/kb_ingest/kb_reindex, SCHEMA.md v1.5 zone/role rules enforced before every write).

Deployed on CT106 (192.168.1.110:8199, systemd) with Claude Code and Hermes connected — see docs/reports/phase4-deployment.md for the full tool catalog, connection commands, and a bug found/fixed during deploy. Progress by phase: openspec/changes/add-unified-memory-mcp/tasks.md. Runbooks: deploy/migrate the server — docs/runbooks/deploy.md; add a new agent — docs/runbooks/add-agent.md.

Design rationale: docs/adr/0001-unified-memory-mcp.md. Specs: openspec/changes/add-unified-memory-mcp/specs/mcp-server-core/spec.md, openspec/changes/add-unified-memory-mcp/specs/agent-memory/spec.md, openspec/changes/add-unified-memory-mcp/specs/kb-adapter/spec.md.

Run it

uv sync
cp config.example.toml config.toml   # then fill in real bearer tokens and Postgres DSN
uv run python -m migrations.migrate --config config.toml   # create/upgrade the memories table
uv run python -m memory_agents_mcp --config config.toml

Transport is streamable-HTTP over the LAN (no stdio). Logs go to stderr and the rotating file configured by log_file — never stdout.

Related MCP server: Markdown Memory Context MCP Server

Config

One TOML file (config.example.toml documents the schema). Key points:

  • [tokens] is a table of bearer-token -> agent_id. This is the only source of agent identity — a tool ever accepting an agent_id parameter ignores it. Unknown or missing tokens are rejected with 401 before any tool runs.

  • No sessions, no activation, no TTL for agent access: a token is valid until removed from the config file, regardless of how long the agent has been idle. (expires_at is a per-memory-record expiry field, not an access mechanism — implemented in Phase 2.)

  • [embedding] pins the model name and vector dimension (bge-m3 / 1024). A mismatch between this pin and what Ollama actually reports is a startup config error.

  • [postgres], [ollama], [memory_service] point at the shared infra (agent_memory DB on .111, Ollama on .110, memory-service on .200:8101) backing the memory_* and kb_* tools respectively.

  • [transport] allowed_hosts — Host-header values LAN agents connect through (e.g. the deploy host's real ip:port). Required once host != 127.0.0.1: MCP's DNS-rebinding protection stays on and only accepts these (localhost is always allowed too).

Agent memory (memory_* tools)

  • memory_remember(type, title, content, confidence=0.8, provenance=..., tags=[], visibility="shared", project=None, expires_at=None) — embeds title + content via Ollama and inserts one row. agent_id always comes from the caller's bearer token, never a parameter. Visibility defaults to shared (agents kept forgetting to pass it and got silently-private records); pass visibility="private" explicitly for a private one.

  • memory_recall(query, type=None, agent_id=None, project=None, since=None, as_of=None, limit=10) — semantic search. No agent_id filter: caller's own rows (private + shared) plus everyone else's shared rows. Explicit agent_id: only that agent's shared rows — their private rows are never reachable this way. Always excludes expired rows (expires_at IS NULL OR expires_at > now()); expiry never gates the rest of an agent's memory.

  • memory_forget(id) — deletes by id, only if the row's agent_id matches the caller; otherwise rejected and the row is untouched.

  • memory_list(project=None, limit=20) — caller's own recent memories (both visibilities), no semantic query.

Schema: migrations/001_memories.sql (apply with python -m migrations.migrate). Field shape ported from memanto's MemoryRecord — 13 memory types, confidence 0–1, provenance enum, tags, optional expires_at (ADR 0001, "Решение: судьба memanto").

Knowledge base (kb_* tools)

Thin adapter over the existing memory-service HTTP API (unrelated, unmodified service backing the user's Obsidian vault) — this project owns no vault data itself.

  • kb_search(query, max_results=None, min_similarity=None, filters=None) / kb_recall(topic, max_pages=None, min_similarity=None) / kb_read_page(path) — transparent passthrough (POST /search, POST /recall, GET /pages).

  • kb_write_page(path, content, reason, role="agent", page_type=None) — checks SCHEMA.md v1.5 zone/role rules (memory_agents_mcp/kb_zones.py, the one module to edit when those rules change) before any HTTP call; rejects edits touching the Sergey-only ## Заметки section for any role; auto-logs a POST /events entry the caller cannot skip.

  • kb_ingest(path, reason, role="agent")POST /ingest + auto-event.

  • kb_reindex(force=False)POST /reindex; registered as a tool only when admin = true in config, per spec ("absent from the tool list", not merely rejected).

Failure behavior

Dependency failures (Postgres/Ollama/memory-service unreachable, or an embedding-dimension mismatch) are soft-fail: logged loudly to stderr and the log file, but the server keeps running. This is a deliberate fix for a prior bug (memanto's hooks swallowing failures with zero signal) — "never break the host" must never mean "never be heard."

Memory Viewer (local GUI)

viewer/ is a local NiceGUI app over this server: run viewer.bat (or uv run python -m viewer) from the repo root — the UI opens in the browser on the port from viewer/config.toml (default 8299; copy viewer/config.example.toml and fill in the token/DSN first).

Tabs: Память агентов (semantic search via memory_recall + a no-SQL field-filter browser over Postgres that also shows private rows, record card, admin delete with confirmation), Vault (kb_search/kb_recall/ kb_read_page with markdown preview, kb_write_page/kb_ingest forms), Тулы (every MCP tool as a form, built from tools/list, raw JSON responses), Мониторинг (health of MCP/Postgres/Ollama/memory-service, the tool_calls journal, agent activity feed, CT106 logs over SSH), Настройки (all endpoints/token/DSN editable at runtime, applied without restart).

The server side journals every tool call into the tool_calls table (migration 003, soft-fail, retention tool_log_retention_days, default 30 days).

Tests

uv run pytest
A
license - permissive license
-
quality - not tested
B
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/Sergio-72/Memory_agents_mcp'

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