ogham-mcp 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. ogham_mcp-0.3.0/.claude/settings.local.json +11 -0
  2. ogham_mcp-0.3.0/.dockerignore +13 -0
  3. ogham_mcp-0.3.0/.env.example +39 -0
  4. ogham_mcp-0.3.0/.github/workflows/docker-build.yml +62 -0
  5. ogham_mcp-0.3.0/.gitignore +34 -0
  6. ogham_mcp-0.3.0/.python-version +1 -0
  7. ogham_mcp-0.3.0/CHANGELOG.md +102 -0
  8. ogham_mcp-0.3.0/Dockerfile +27 -0
  9. ogham_mcp-0.3.0/LICENSE +21 -0
  10. ogham_mcp-0.3.0/PKG-INFO +340 -0
  11. ogham_mcp-0.3.0/README.md +299 -0
  12. ogham_mcp-0.3.0/docker-compose.yml +10 -0
  13. ogham_mcp-0.3.0/docs/database-platform-comparison.md +28 -0
  14. ogham_mcp-0.3.0/docs/embedding-provider-benchmarks.md +78 -0
  15. ogham_mcp-0.3.0/docs/openapi.json +792 -0
  16. ogham_mcp-0.3.0/pyproject.toml +71 -0
  17. ogham_mcp-0.3.0/skills/ogham-maintain/SKILL.md +79 -0
  18. ogham_mcp-0.3.0/skills/ogham-recall/SKILL.md +71 -0
  19. ogham_mcp-0.3.0/skills/ogham-research/SKILL.md +83 -0
  20. ogham_mcp-0.3.0/sql/generate_dimension_migration.py +143 -0
  21. ogham_mcp-0.3.0/sql/migrations/002_cognitive_scoring.sql +117 -0
  22. ogham_mcp-0.3.0/sql/migrations/003_confidence_scoring.sql +123 -0
  23. ogham_mcp-0.3.0/sql/migrations/004_embedding_gemma_switch.sql +123 -0
  24. ogham_mcp-0.3.0/sql/migrations/005_hybrid_search.sql +128 -0
  25. ogham_mcp-0.3.0/sql/migrations/006_batch_dedup.sql +36 -0
  26. ogham_mcp-0.3.0/sql/migrations/007_set_based_batch_update.sql +25 -0
  27. ogham_mcp-0.3.0/sql/migrations/008_memory_relationships.sql +115 -0
  28. ogham_mcp-0.3.0/sql/migrations/009_graph_explorer.sql +75 -0
  29. ogham_mcp-0.3.0/sql/migrations/010_impact_analysis.sql +61 -0
  30. ogham_mcp-0.3.0/sql/migrations/011_graph_centrality_boost.sql +202 -0
  31. ogham_mcp-0.3.0/sql/schema.sql +758 -0
  32. ogham_mcp-0.3.0/sql/schema_postgres.sql +731 -0
  33. ogham_mcp-0.3.0/sql/schema_selfhost_supabase.sql +759 -0
  34. ogham_mcp-0.3.0/src/ogham/__init__.py +0 -0
  35. ogham_mcp-0.3.0/src/ogham/app.py +3 -0
  36. ogham_mcp-0.3.0/src/ogham/backends/__init__.py +3 -0
  37. ogham_mcp-0.3.0/src/ogham/backends/postgres.py +577 -0
  38. ogham_mcp-0.3.0/src/ogham/backends/protocol.py +193 -0
  39. ogham_mcp-0.3.0/src/ogham/backends/supabase.py +457 -0
  40. ogham_mcp-0.3.0/src/ogham/cli.py +371 -0
  41. ogham_mcp-0.3.0/src/ogham/config.py +121 -0
  42. ogham_mcp-0.3.0/src/ogham/database.py +225 -0
  43. ogham_mcp-0.3.0/src/ogham/embedding_cache.py +99 -0
  44. ogham_mcp-0.3.0/src/ogham/embeddings.py +304 -0
  45. ogham_mcp-0.3.0/src/ogham/export_import.py +175 -0
  46. ogham_mcp-0.3.0/src/ogham/health.py +137 -0
  47. ogham_mcp-0.3.0/src/ogham/http_health.py +63 -0
  48. ogham_mcp-0.3.0/src/ogham/init_wizard.py +682 -0
  49. ogham_mcp-0.3.0/src/ogham/openapi.py +82 -0
  50. ogham_mcp-0.3.0/src/ogham/prompts.py +104 -0
  51. ogham_mcp-0.3.0/src/ogham/retry.py +64 -0
  52. ogham_mcp-0.3.0/src/ogham/server.py +67 -0
  53. ogham_mcp-0.3.0/src/ogham/tools/__init__.py +0 -0
  54. ogham_mcp-0.3.0/src/ogham/tools/memory.py +598 -0
  55. ogham_mcp-0.3.0/src/ogham/tools/stats.py +25 -0
  56. ogham_mcp-0.3.0/tests/__init__.py +0 -0
  57. ogham_mcp-0.3.0/tests/conftest.py +11 -0
  58. ogham_mcp-0.3.0/tests/test_backend_wiring.py +87 -0
  59. ogham_mcp-0.3.0/tests/test_cli.py +206 -0
  60. ogham_mcp-0.3.0/tests/test_embedding_cache.py +83 -0
  61. ogham_mcp-0.3.0/tests/test_export_import.py +411 -0
  62. ogham_mcp-0.3.0/tests/test_http_health.py +62 -0
  63. ogham_mcp-0.3.0/tests/test_integration.py +968 -0
  64. ogham_mcp-0.3.0/tests/test_openapi.py +51 -0
  65. ogham_mcp-0.3.0/tests/test_postgres_backend.py +21 -0
  66. ogham_mcp-0.3.0/tests/test_postgres_integration.py +152 -0
  67. ogham_mcp-0.3.0/tests/test_prompts.py +109 -0
  68. ogham_mcp-0.3.0/tests/test_retry.py +85 -0
  69. ogham_mcp-0.3.0/tests/test_tools.py +1271 -0
  70. ogham_mcp-0.3.0/uv.lock +2863 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "enableAllProjectMcpServers": true,
3
+ "enabledMcpjsonServers": [
4
+ "ogham"
5
+ ],
6
+ "permissions": {
7
+ "allow": [
8
+ "mcp__ogham__health_check"
9
+ ]
10
+ }
11
+ }
@@ -0,0 +1,13 @@
1
+ .venv/
2
+ .env
3
+ .git/
4
+ .ruff_cache/
5
+ __pycache__/
6
+ *.pyc
7
+ *.pyo
8
+ tests/
9
+ docs/
10
+ *.md
11
+ !README.md
12
+ .pytest_cache/
13
+ starter.md
@@ -0,0 +1,39 @@
1
+ # Required
2
+ SUPABASE_URL=https://your-project.supabase.co
3
+ SUPABASE_KEY=your-service-role-key
4
+
5
+ # Embedding provider: "ollama" (default), "openai", "mistral", or "voyage"
6
+ EMBEDDING_PROVIDER=ollama
7
+
8
+ # Embedding dimensions — auto-set per provider if omitted:
9
+ # ollama: 512, openai: 1024, mistral: 1024, voyage: 1024
10
+ # Override only if using a non-default model with different dimensions.
11
+ # EMBEDDING_DIM=512
12
+
13
+ # Ollama settings (default)
14
+ # Use localhost for native install, host.docker.internal for Docker
15
+ OLLAMA_URL=http://localhost:11434
16
+ OLLAMA_EMBED_MODEL=embeddinggemma
17
+
18
+ # OpenAI settings (if EMBEDDING_PROVIDER=openai)
19
+ # OPENAI_API_KEY=sk-...
20
+
21
+ # Mistral settings (if EMBEDDING_PROVIDER=mistral)
22
+ # MISTRAL_API_KEY=your-mistral-key
23
+ # MISTRAL_EMBED_MODEL=mistral-embed
24
+
25
+ # Voyage settings (if EMBEDDING_PROVIDER=voyage)
26
+ # VOYAGE_API_KEY=your-voyage-key
27
+ # VOYAGE_EMBED_MODEL=voyage-4-lite
28
+
29
+ # Search defaults
30
+ # Threshold depends on embedding provider — each clusters vectors differently:
31
+ # Ollama (embeddinggemma): 0.7 — tight clustering, scores run 0.8-0.9
32
+ # Mistral (mistral-embed): 0.6 — tight clustering, similar to Ollama
33
+ # Voyage (voyage-4-lite): 0.45 — moderate spread
34
+ # OpenAI (text-embedding-3-small): 0.35 — widest spread, scores run 0.5-0.6
35
+ DEFAULT_MATCH_THRESHOLD=0.7
36
+ DEFAULT_MATCH_COUNT=10
37
+
38
+ # Memory profile (Severance-style partitioning: "lumon", "personal", "projects", etc)
39
+ DEFAULT_PROFILE=default
@@ -0,0 +1,62 @@
1
+ # Multi-platform Docker build for linux/amd64 + linux/arm64.
2
+ #
3
+ # TODO(public launch): Restrict GHCR push to tags only. Currently pushes on
4
+ # every main commit for testing during private development. Change the Login
5
+ # and Build steps back to: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
6
+
7
+ name: Docker Build
8
+
9
+ on:
10
+ push:
11
+ branches: [main]
12
+ tags: ["v*"]
13
+ pull_request:
14
+ branches: [main]
15
+
16
+ permissions:
17
+ contents: read
18
+ packages: write
19
+
20
+ jobs:
21
+ build:
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - name: Checkout
26
+ uses: actions/checkout@v4
27
+
28
+ - name: Set up QEMU
29
+ uses: docker/setup-qemu-action@v3
30
+
31
+ - name: Set up Docker Buildx
32
+ uses: docker/setup-buildx-action@v3
33
+
34
+ - name: Login to GHCR
35
+ if: github.event_name == 'push'
36
+ uses: docker/login-action@v3
37
+ with:
38
+ registry: ghcr.io
39
+ username: ${{ github.repository_owner }}
40
+ password: ${{ secrets.GITHUB_TOKEN }}
41
+
42
+ - name: Extract metadata
43
+ id: meta
44
+ uses: docker/metadata-action@v5
45
+ with:
46
+ images: ghcr.io/${{ github.repository }}
47
+ tags: |
48
+ type=semver,pattern={{version}}
49
+ type=semver,pattern={{major}}.{{minor}}
50
+ type=raw,value=latest,enable={{is_default_branch}}
51
+ type=sha,prefix=,format=short
52
+
53
+ - name: Build and push
54
+ uses: docker/build-push-action@v6
55
+ with:
56
+ context: .
57
+ platforms: linux/amd64,linux/arm64
58
+ push: ${{ github.event_name == 'push' }}
59
+ tags: ${{ steps.meta.outputs.tags }}
60
+ labels: ${{ steps.meta.outputs.labels }}
61
+ cache-from: type=gha
62
+ cache-to: type=gha,mode=max
@@ -0,0 +1,34 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ *.egg
8
+
9
+ # Environment
10
+ .env
11
+ .env.local
12
+
13
+ # IDE
14
+ .vscode/
15
+ .idea/
16
+ *.swp
17
+ *.swo
18
+
19
+ # OS
20
+ .DS_Store
21
+ Thumbs.db
22
+
23
+ # Testing
24
+ .pytest_cache/
25
+ .coverage
26
+ htmlcov/
27
+
28
+ # MCP config (local per-machine)
29
+ .mcp*.json
30
+
31
+ # UV
32
+
33
+ # Docker
34
+ .worktrees/
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,102 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
+
7
+ ## [0.3.0] - 2026-03-07 — Relationship Graph
8
+
9
+ ### Added
10
+ - **Relationship graph** — `memory_relationships` table with typed, weighted edges (`similar`, `supports`, `contradicts`, `related`, `follows`, `derived_from`). Built entirely in PostgreSQL with recursive CTEs — no separate graph database or LLM needed
11
+ - **Auto-linking** — new memories are automatically linked to similar existing memories on store via HNSW vector search (threshold 0.85, max 5 links). One database round-trip, no LLM in the write path
12
+ - `explore_knowledge` tool — hybrid search seeds + recursive CTE graph traversal. Finds memories by meaning, then expands via relationship edges to pull in connected context
13
+ - `find_related` tool — traverses the graph outward from a known memory ID for impact analysis
14
+ - `store_decision` tool — stores architectural decisions with structured metadata (rationale, alternatives) and `supports` edges to related memories
15
+ - `link_unlinked` tool — backfills auto-links for memories that predate the relationship graph. Configurable threshold and batch size
16
+ - `store_memory` gains `auto_link` parameter (default `True`) and returns `links_created` count
17
+ - Stress test script (`tests/bench_stress.py`) — imports 1000+ memories, verifies dedup, backfills auto-links, benchmarks graph operations at scale
18
+ - Benchmark coverage for auto-link, explore graph, and get related operations
19
+
20
+ ### Fixed
21
+ - `link_unlinked_memories` RPC infinite loop — `PERFORM` discarded return value, causing memories with no similar neighbors to be reprocessed indefinitely. Fixed with `SELECT INTO` and conditional increment
22
+
23
+ ### Schema Changes
24
+ - Run `sql/migrations/008_memory_relationships.sql`, `009_graph_explorer.sql`, `010_impact_analysis.sql` in order, or re-run `sql/schema.sql` for fresh installs
25
+ - New table: `memory_relationships` (source_id, target_id, relationship, strength, metadata)
26
+ - New enum: `relationship_type`
27
+ - New RPCs: `auto_link_memory`, `link_unlinked_memories`, `explore_memory_graph`, `get_related_memories`
28
+
29
+ ## [0.2.1] - 2026-03-05 — Supabase Best Practices
30
+
31
+ ### Changed
32
+ - **RLS hardened** — `FORCE ROW LEVEL SECURITY` on `memories` and `profile_settings`, deny `anon` role access by default
33
+ - **Composite index** — replaced separate `profile` and `created_at` indexes with `(profile, created_at DESC)` for faster filtered queries
34
+ - **Keyset pagination** — `get_all_memories_full` and `get_all_memories_content` now use cursor-based pagination instead of OFFSET
35
+ - **Batch re-embed** — `re_embed_all` uses new `batch_update_embeddings` RPC (batches of 50) instead of individual updates
36
+
37
+ ### Added
38
+ - `batch_update_embeddings` RPC function for efficient bulk embedding updates
39
+ - `CHECK` constraint on `profile_settings.ttl_days` (`>= 1` or NULL)
40
+ - RLS policies on `profile_settings` table
41
+
42
+ ### Schema Changes
43
+ - Run `sql/migrate_best_practices.sql` to upgrade existing installs
44
+
45
+ ## [0.2.0] - 2026-03-05 — Quality of Life Release
46
+
47
+ ### Added
48
+ - **LRU embedding cache** with configurable max size (`EMBEDDING_CACHE_MAX_SIZE`, default 1000) and `get_cache_stats()` tool for monitoring
49
+ - **Memory expiration** with profile-bound TTLs — `set_profile_ttl()` sets days until memories expire, `cleanup_expired()` permanently removes them
50
+ - **Profile settings table** (`profile_settings`) for storing per-profile TTL configuration
51
+ - **MCP prompts** — `summarize-recent`, `find-decisions`, `profile-overview`, `cleanup-check`
52
+ - **HTTP health endpoint** — optional `GET /health` on configurable port (`ENABLE_HTTP_HEALTH`, `HEALTH_PORT`)
53
+ - **CLI tool** — `ogham` command with subcommands: serve, health, profiles, stats, search, list, cleanup, export, import, openapi
54
+ - **OpenAPI spec generation** — `ogham openapi` generates `docs/openapi.json` from MCP tool definitions
55
+ - **Export/import** — `export_profile()` exports as JSON or Markdown, `import_memories_tool()` imports with dedup
56
+
57
+ ### Changed
58
+ - `match_memories`, `get_profile_counts`, `get_memory_stats_sql` RPCs now filter expired memories
59
+ - `list_recent_memories` now filters expired memories and returns `expires_at`
60
+ - `store_memory` now computes `expires_at` from profile TTL when set
61
+ - Entry point changed: `ogham` now runs CLI (use `ogham serve` for MCP server, or `ogham-serve`)
62
+ - Embedding cache changed from unbounded dict to OrderedDict-based LRU
63
+
64
+ ### Schema Changes
65
+ - New table: `profile_settings` (profile, ttl_days, created_at, updated_at)
66
+ - New column: `memories.expires_at` (timestamptz, nullable)
67
+ - New RPCs: `cleanup_expired_memories()`, `count_expired_memories()`
68
+ - Run `sql/migrate_expiration.sql` to upgrade existing installs
69
+
70
+ ## [0.1.1] - 2026-03-05
71
+
72
+ ### Added
73
+ - `health_check` tool for diagnosing connection issues
74
+ - Startup validation -- exits with clear errors if Supabase or Ollama aren't reachable
75
+ - Retry with exponential backoff on transient failures (embedding: 3 attempts, DB reads: 2)
76
+ - Input validation for content, threshold, and limit parameters
77
+ - Embedding cache (SHA256-keyed) to skip re-embedding identical content
78
+ - SQL aggregation functions (`get_profile_counts`, `get_memory_stats_sql`) replacing Python-side counting
79
+ - Progress reporting for `re_embed_all`
80
+ - Tool execution timing logged to stderr
81
+
82
+ ### Fixed
83
+ - `update_memory` / `store_memory` crash when Supabase returns empty results
84
+ - `delete_memory` / `update_memory` could affect memories in other profiles
85
+
86
+ ### Changed
87
+ - `get_stats()` returns `total` instead of `total_memories`
88
+ - OpenAI is now an optional dependency (`uv sync --extra openai`)
89
+ - New RPC functions required -- re-run `sql/schema.sql`
90
+
91
+ ## [0.1.0] - 2026-03-05
92
+
93
+ ### Added
94
+ - Initial release
95
+ - MCP server with stdio transport
96
+ - Supabase PostgreSQL + pgvector backend
97
+ - Ollama and OpenAI embedding providers
98
+ - Memory profiles (Severance-style partitioning)
99
+ - Semantic search with cosine similarity
100
+ - Tag and source filtering
101
+ - Docker and native (UV) deployment options
102
+ - Support for Claude Desktop, Cursor, Claude Code, VS Code, Codex, Windsurf
@@ -0,0 +1,27 @@
1
+ # --- Stage 1: Build ---
2
+ FROM python:3.13-slim AS builder
3
+
4
+ COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
5
+
6
+ WORKDIR /app
7
+
8
+ COPY pyproject.toml uv.lock .python-version ./
9
+ RUN uv sync --frozen --no-dev --no-editable --no-install-project --extra all
10
+
11
+ COPY src/ src/
12
+ RUN uv sync --frozen --no-dev --no-editable --extra all
13
+
14
+ # --- Stage 2: Runtime ---
15
+ FROM python:3.13-slim
16
+
17
+ WORKDIR /app
18
+
19
+ COPY --from=builder /app/.venv /app/.venv
20
+ COPY src/ ./src/
21
+
22
+ ENV PATH="/app/.venv/bin:$PATH"
23
+ ENV PYTHONDONTWRITEBYTECODE=1
24
+ ENV PYTHONUNBUFFERED=1
25
+ ENV OLLAMA_URL=http://host.docker.internal:11434
26
+
27
+ ENTRYPOINT ["ogham"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kevin Burns
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,340 @@
1
+ Metadata-Version: 2.4
2
+ Name: ogham-mcp
3
+ Version: 0.3.0
4
+ Summary: Shared memory MCP server — persistent, searchable, cross-client
5
+ Project-URL: Homepage, https://ogham-mcp.dev
6
+ Project-URL: Repository, https://github.com/ogham-mcp/ogham-mcp
7
+ Project-URL: Documentation, https://ogham-mcp.dev
8
+ Author: Kevin Burns
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agents,ai,embeddings,mcp,memory,pgvector,supabase
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.13
17
+ Requires-Dist: fastmcp>=2.14
18
+ Requires-Dist: ollama>=0.4
19
+ Requires-Dist: openai>=1.0
20
+ Requires-Dist: pydantic-settings>=2.0
21
+ Requires-Dist: python-dotenv>=1.0
22
+ Requires-Dist: supabase>=2.0
23
+ Requires-Dist: typer>=0.12
24
+ Provides-Extra: all
25
+ Requires-Dist: mistralai>=1.0; extra == 'all'
26
+ Requires-Dist: psycopg-pool>=3.1; extra == 'all'
27
+ Requires-Dist: psycopg[binary]>=3.1; extra == 'all'
28
+ Requires-Dist: voyageai>=0.3; extra == 'all'
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.9; extra == 'dev'
33
+ Provides-Extra: mistral
34
+ Requires-Dist: mistralai>=1.0; extra == 'mistral'
35
+ Provides-Extra: postgres
36
+ Requires-Dist: psycopg-pool>=3.1; extra == 'postgres'
37
+ Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
38
+ Provides-Extra: voyage
39
+ Requires-Dist: voyageai>=0.3; extra == 'voyage'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # Ogham MCP
43
+
44
+ *Ogham* (pronounced "OH-um") -- persistent, searchable shared memory for AI coding agents. Works across clients.
45
+
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
47
+ [![Docker](https://img.shields.io/badge/Docker-ghcr.io%2Fogham--mcp%2Fogham--mcp-blue)](https://github.com/ogham-mcp/ogham-mcp/pkgs/container/ogham-mcp)
48
+
49
+ ## The problem
50
+
51
+ AI coding agents forget everything between sessions. Switch from Claude Code to Cursor to Kiro to OpenCode and context is lost. Decisions, gotchas, architectural patterns -- gone. You end up repeating yourself, re-explaining your codebase, re-debugging the same issues.
52
+
53
+ Ogham gives your agents a shared memory that persists across sessions and clients.
54
+
55
+ ## Quick start
56
+
57
+ ### 1. Set up your database
58
+
59
+ **Supabase** (free tier works): create a project at [supabase.com](https://supabase.com), then run `sql/schema.sql` in the SQL editor.
60
+
61
+ **Postgres** ([Neon](https://neon.tech), self-hosted, etc.): run `sql/schema_postgres.sql` against your database. Needs PostgreSQL 15+ with pgvector.
62
+
63
+ ### 2. Install
64
+
65
+ ```bash
66
+ # From PyPI (recommended)
67
+ claude mcp add ogham -- uvx ogham-mcp
68
+
69
+ # Before PyPI publish, install from GitHub
70
+ uvx --from git+https://github.com/ogham-mcp/ogham-mcp.git ogham init
71
+ claude mcp add ogham -- uvx --from git+https://github.com/ogham-mcp/ogham-mcp.git ogham-serve
72
+ ```
73
+
74
+ The `ogham init` wizard walks you through database setup, embedding provider, and writes MCP client configs. Run it before adding the server to your client.
75
+
76
+ ### 3. Configure
77
+
78
+ ```bash
79
+ # Supabase
80
+ export SUPABASE_URL=https://your-project.supabase.co
81
+ export SUPABASE_KEY=your-service-role-key
82
+ export EMBEDDING_PROVIDER=openai # or ollama, mistral, voyage
83
+ export OPENAI_API_KEY=sk-... # for your chosen provider
84
+
85
+ # Or Postgres (Neon, self-hosted)
86
+ export DATABASE_BACKEND=postgres
87
+ export DATABASE_URL=postgresql://user:pass@host/db
88
+ export EMBEDDING_PROVIDER=openai
89
+ export OPENAI_API_KEY=sk-...
90
+ ```
91
+
92
+ Or skip the manual setup and run the interactive wizard:
93
+
94
+ ```bash
95
+ ogham init
96
+ ```
97
+
98
+ It walks you through database connection, embedding provider, schema migration, and writes MCP client configs for Claude Code, Cursor, VS Code, and others.
99
+
100
+ ### 4. Use it
101
+
102
+ Tell your agent to remember something, then ask about it later -- from the same client or a different one. It works because they all hit the same database.
103
+
104
+ ## Installation methods
105
+
106
+ | Method | Command | When to use |
107
+ |--------|---------|-------------|
108
+ | **uvx** (recommended) | `uvx ogham-mcp` | PyPI is published, quick setup |
109
+ | **uvx from GitHub** | `uvx --from git+https://github.com/ogham-mcp/ogham-mcp.git ogham-serve` | Before PyPI, testing from source |
110
+ | **Docker** | `docker pull ghcr.io/ogham-mcp/ogham-mcp` | Isolation, self-hosted |
111
+ | **Git clone** | `git clone` + `uv sync` | Development, contributions |
112
+
113
+ ### Claude Code
114
+
115
+ ```bash
116
+ # From PyPI
117
+ claude mcp add ogham -- uvx ogham-mcp
118
+
119
+ # From GitHub (before PyPI) -- run ogham init first to configure your database and provider
120
+ claude mcp add ogham -- uvx --from git+https://github.com/ogham-mcp/ogham-mcp.git ogham-serve
121
+ ```
122
+
123
+ ### OpenCode
124
+
125
+ Add to `~/.config/opencode/opencode.json`:
126
+
127
+ ```json
128
+ {
129
+ "mcp": {
130
+ "ogham": {
131
+ "type": "local",
132
+ "command": ["uvx", "ogham-mcp"],
133
+ "environment": {
134
+ "SUPABASE_URL": "https://your-project.supabase.co",
135
+ "SUPABASE_KEY": "{env:SUPABASE_KEY}",
136
+ "EMBEDDING_PROVIDER": "openai",
137
+ "OPENAI_API_KEY": "{env:OPENAI_API_KEY}"
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### Docker
145
+
146
+ ```bash
147
+ docker run --rm \
148
+ -e SUPABASE_URL=https://your-project.supabase.co \
149
+ -e SUPABASE_KEY=your-key \
150
+ -e EMBEDDING_PROVIDER=openai \
151
+ -e OPENAI_API_KEY=sk-... \
152
+ ghcr.io/ogham-mcp/ogham-mcp
153
+ ```
154
+
155
+ ### From source
156
+
157
+ ```bash
158
+ git clone https://github.com/ogham-mcp/ogham-mcp.git
159
+ cd ogham-mcp
160
+ uv sync
161
+ uv run ogham --help
162
+ ```
163
+
164
+ ## Entry points
165
+
166
+ Ogham has two entry points:
167
+
168
+ - **`ogham`** -- the CLI. Use this for `ogham init`, `ogham health`, `ogham search`, and other commands you run yourself. Running `ogham` with no arguments starts the MCP server.
169
+ - **`ogham-serve`** -- starts the MCP server directly. This is what MCP clients should call. When you run `uvx ogham-mcp`, it invokes `ogham-serve`.
170
+
171
+ ## CLI
172
+
173
+ ```bash
174
+ ogham init # Interactive setup wizard
175
+ ogham health # Check database + embedding provider
176
+ ogham search "query" # Search memories from the terminal
177
+ ogham store "some fact" # Store a memory
178
+ ogham list # List recent memories
179
+ ogham profiles # List profiles and counts
180
+ ogham stats # Profile statistics
181
+ ogham export -o backup.json # Export memories
182
+ ogham import backup.json # Import memories
183
+ ogham cleanup # Remove expired memories
184
+ ogham serve # Start MCP server (default)
185
+ ogham openapi # Generate OpenAPI spec
186
+ ```
187
+
188
+ ## Configuration
189
+
190
+ | Variable | Required | Default | Description |
191
+ |----------|----------|---------|-------------|
192
+ | `DATABASE_BACKEND` | No | `supabase` | `supabase` or `postgres` |
193
+ | `SUPABASE_URL` | If supabase | -- | Your Supabase project URL |
194
+ | `SUPABASE_KEY` | If supabase | -- | Supabase secret key (service_role) |
195
+ | `DATABASE_URL` | If postgres | -- | PostgreSQL connection string |
196
+ | `EMBEDDING_PROVIDER` | No | `ollama` | `ollama`, `openai`, `mistral`, or `voyage` |
197
+ | `EMBEDDING_DIM` | No | `512` | Vector dimensions -- must match your schema (see below) |
198
+ | `OPENAI_API_KEY` | If openai | -- | OpenAI API key |
199
+ | `MISTRAL_API_KEY` | If mistral | -- | Mistral API key |
200
+ | `VOYAGE_API_KEY` | If voyage | -- | Voyage AI API key |
201
+ | `OLLAMA_URL` | No | `http://localhost:11434` | Ollama server URL |
202
+ | `OLLAMA_EMBED_MODEL` | No | `embeddinggemma` | Ollama embedding model |
203
+ | `MISTRAL_EMBED_MODEL` | No | `mistral-embed` | Mistral embedding model |
204
+ | `VOYAGE_EMBED_MODEL` | No | `voyage-4-lite` | Voyage embedding model |
205
+ | `DEFAULT_MATCH_THRESHOLD` | No | `0.7` | Similarity threshold (see below) |
206
+ | `DEFAULT_MATCH_COUNT` | No | `10` | Max results per search |
207
+ | `DEFAULT_PROFILE` | No | `default` | Memory profile name |
208
+
209
+ ### Embedding providers
210
+
211
+ | Provider | Default dimensions | Recommended threshold | Notes |
212
+ |----------|-------------------|----------------------|-------|
213
+ | OpenAI | 512 (schema default) | 0.35 | Set `EMBEDDING_DIM=512` explicitly -- OpenAI defaults to 1024 |
214
+ | Ollama | 512 | 0.70 | Tight clustering, scores run 0.8-0.9 |
215
+ | Mistral | 1024 | 0.60 | Fixed 1024 dims, can't truncate. Schema must be `vector(1024)` |
216
+ | Voyage | 512 (schema default) | 0.45 | Moderate spread |
217
+
218
+ `EMBEDDING_DIM` must match the `vector(N)` column in your database schema. The default schema uses `vector(512)`. If you use Mistral, you need to alter the column to `vector(1024)` before storing anything.
219
+
220
+ Each provider clusters vectors differently, so the similarity threshold matters. Start with the recommended value and adjust based on your results.
221
+
222
+ ## MCP tools
223
+
224
+ ### Memory operations
225
+
226
+ | Tool | Description | Key parameters |
227
+ |------|-------------|----------------|
228
+ | `store_memory` | Store a new memory with embedding | `content` (required), `source`, `tags[]`, `auto_link` |
229
+ | `store_decision` | Store an architectural decision | `decision`, `reasoning`, `alternatives[]`, `tags[]` |
230
+ | `update_memory` | Update content of existing memory | `memory_id`, `content`, `tags[]` |
231
+ | `delete_memory` | Delete a memory by ID | `memory_id` |
232
+ | `reinforce_memory` | Increase confidence score | `memory_id` |
233
+ | `contradict_memory` | Decrease confidence score | `memory_id` |
234
+
235
+ ### Search
236
+
237
+ | Tool | Description | Key parameters |
238
+ |------|-------------|----------------|
239
+ | `hybrid_search` | Combined semantic + full-text search (RRF) | `query`, `limit`, `threshold`, `tags[]` |
240
+ | `list_recent` | List recent memories | `limit`, `profile` |
241
+ | `find_related` | Find memories related to a given one | `memory_id`, `limit` |
242
+
243
+ ### Knowledge graph
244
+
245
+ | Tool | Description | Key parameters |
246
+ |------|-------------|----------------|
247
+ | `link_unlinked` | Auto-link memories by embedding similarity | `threshold`, `limit` |
248
+ | `explore_knowledge` | Traverse the knowledge graph | `memory_id`, `depth`, `direction` |
249
+
250
+ ### Profiles
251
+
252
+ | Tool | Description | Key parameters |
253
+ |------|-------------|----------------|
254
+ | `switch_profile` | Switch active memory profile | `profile` |
255
+ | `current_profile` | Show active profile | -- |
256
+ | `list_profiles` | List all profiles with counts | -- |
257
+ | `set_profile_ttl` | Set auto-expiry for a profile | `profile`, `ttl_days` |
258
+
259
+ ### Import / export
260
+
261
+ | Tool | Description | Key parameters |
262
+ |------|-------------|----------------|
263
+ | `export_profile` | Export all memories in active profile | `format` (`json` or `markdown`) |
264
+ | `import_memories_tool` | Import memories with deduplication | `data`, `dedup_threshold` |
265
+
266
+ ### Maintenance
267
+
268
+ | Tool | Description | Key parameters |
269
+ |------|-------------|----------------|
270
+ | `re_embed_all` | Re-embed all memories (after switching providers) | -- |
271
+ | `cleanup_expired` | Remove expired memories (TTL) | -- |
272
+ | `health_check` | Check database and embedding connectivity | -- |
273
+ | `get_stats` | Memory counts, profiles, activity | -- |
274
+ | `get_cache_stats` | Embedding cache hit rates | -- |
275
+
276
+ ## Skills
277
+
278
+ Ogham ships with three workflow skills in `skills/` that teach AI assistants how to orchestrate the MCP tools above. Install them in Claude Code, Cursor, or any client that supports skills.
279
+
280
+ | Skill | Triggers on | What it does |
281
+ |-------|-------------|-------------|
282
+ | `ogham-research` | "remember this", "store this finding", "save what we learned" | Checks for duplicates via hybrid_search before storing. Auto-tags with a consistent scheme (`type:decision`, `type:gotcha`, etc.). Uses `store_decision` for architectural choices. |
283
+ | `ogham-recall` | "what do I know about X", "find related", "context for this project" | Chains hybrid_search, find_related, and explore_knowledge to surface connections. Bootstraps session context at project start. |
284
+ | `ogham-maintain` | "memory stats", "clean up my memory", "export my brain" | Runs health_check, get_stats, cleanup_expired, re_embed_all, link_unlinked. Warns before irreversible operations. |
285
+
286
+ The skills orchestrate existing MCP tools -- they don't replace them. The MCP server must be connected for skills to work.
287
+
288
+ To install (Claude Code):
289
+
290
+ ```bash
291
+ cp -r skills/ogham-research skills/ogham-recall skills/ogham-maintain ~/.claude/skills/
292
+ ```
293
+
294
+ ## Database setup
295
+
296
+ Ogham works with Supabase or vanilla PostgreSQL. Run the schema file that matches your setup:
297
+
298
+ | File | Use case |
299
+ |------|----------|
300
+ | `sql/schema.sql` | [Supabase](https://supabase.com) Cloud |
301
+ | `sql/schema_selfhost_supabase.sql` | Self-hosted Supabase with RLS |
302
+ | `sql/schema_postgres.sql` | Vanilla PostgreSQL / [Neon](https://neon.tech) (no RLS) |
303
+
304
+ Supabase and Neon both include pgvector out of the box -- no extra setup needed. If you're self-hosting Postgres, you need PostgreSQL 15+ with the [pgvector](https://github.com/pgvector/pgvector) extension installed. We develop and test against PostgreSQL 17.
305
+
306
+ For Postgres, set `DATABASE_BACKEND=postgres` and `DATABASE_URL=postgresql://...` in your environment.
307
+
308
+ ## Architecture
309
+
310
+ Ogham runs as an MCP server over stdio. Your AI client connects to it like any other MCP tool.
311
+
312
+ ```
313
+ AI Client (Claude Code, Cursor, Kiro, OpenCode, ...)
314
+ |
315
+ | stdio (MCP protocol)
316
+ |
317
+ Ogham MCP Server
318
+ |
319
+ | HTTPS (Supabase REST API) or direct connection (Postgres)
320
+ |
321
+ PostgreSQL + pgvector
322
+ ```
323
+
324
+ Memories are stored as rows with vector embeddings. Search combines pgvector cosine similarity with PostgreSQL full-text search using Reciprocal Rank Fusion (RRF).
325
+
326
+ The knowledge graph uses a `memory_relationships` table with recursive CTEs for traversal -- no separate graph database.
327
+
328
+ ## Documentation
329
+
330
+ Full docs and integration guides at [ogham-mcp.dev](https://ogham-mcp.dev).
331
+
332
+ ## Credits
333
+
334
+ Inspired by [Nate B Jones](https://www.youtube.com/watch?v=2JiMmye2ezg) and his work on persistent AI memory.
335
+
336
+ Named after [Ogham](https://en.wikipedia.org/wiki/Ogham), the ancient Irish alphabet carved into stone -- the original persistent memory.
337
+
338
+ ## License
339
+
340
+ MIT