{"id":47898109,"url":"https://github.com/ivkond/memoria","last_synced_at":"2026-04-04T03:56:26.524Z","repository":{"id":346633632,"uuid":"1190821768","full_name":"ivkond/memoria","owner":"ivkond","description":"The missing self-hosted memory backend for MCP clients.","archived":false,"fork":false,"pushed_at":"2026-04-02T08:43:10.000Z","size":453,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-04T03:56:21.055Z","etag":null,"topics":["ai-agents","fastmcp","mcp","mem0","memgraph","memory","model-context-protocol","python","qdrant","self-hosted"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivkond.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-24T16:47:06.000Z","updated_at":"2026-04-02T08:43:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ivkond/memoria","commit_stats":null,"previous_names":["ivkond/memoria"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ivkond/memoria","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivkond%2Fmemoria","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivkond%2Fmemoria/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivkond%2Fmemoria/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivkond%2Fmemoria/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivkond","download_url":"https://codeload.github.com/ivkond/memoria/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivkond%2Fmemoria/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31387024,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T01:22:39.193Z","status":"online","status_checked_at":"2026-04-04T02:00:07.569Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","fastmcp","mcp","mem0","memgraph","memory","model-context-protocol","python","qdrant","self-hosted"],"created_at":"2026-04-04T03:56:25.989Z","updated_at":"2026-04-04T03:56:26.517Z","avatar_url":"https://github.com/ivkond.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Memoria\n\n[![CI](https://github.com/ivkond/memoria/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ivkond/memoria/actions/workflows/ci.yml)\n[![Bandit](https://github.com/ivkond/memoria/actions/workflows/bandit.yml/badge.svg?branch=master)](https://github.com/ivkond/memoria/actions/workflows/bandit.yml)\n[![OSV-Scanner](https://github.com/ivkond/memoria/actions/workflows/osv-scanner.yml/badge.svg?branch=master)](https://github.com/ivkond/memoria/actions/workflows/osv-scanner.yml)\n[![Trivy](https://github.com/ivkond/memoria/actions/workflows/trivy.yml/badge.svg?branch=master)](https://github.com/ivkond/memoria/actions/workflows/trivy.yml)\n[![SonarCloud](https://sonarcloud.io/api/project_badges/measure?project=ivkond_memoria\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ivkond_memoria)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/ivkond/memoria/blob/master/LICENSE)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://github.com/ivkond/memoria/blob/master/pyproject.toml)\n\nThe missing self-hosted memory backend for MCP clients.\n\nCommunity-maintained MCP server for mem0 OSS.\n\nIf you like mem0 but need it in MCP clients today, Memoria closes that gap:\n- 🌐 Streamable HTTP MCP endpoint\n- 👤 Per-user memory scoping for trusted internal deployments\n- 🐳 Drop-in Docker setup with Qdrant\n- 🕸️ Optional graph memory via Memgraph\n\n\u003e Why this project exists: there is no official MCP server in mem0 OSS that you can run as a standalone service in your stack. Memoria gives you that bridge now.\n\n## ✨ What You Get\n\n- MCP tools for storing, searching, updating, and deleting memory\n- OIDC bearer token auth (Keycloak-compatible) with per-user scoping from token claims\n- Ownership checks for ID-based read/update/delete operations\n- Health endpoint with Qdrant, Memgraph, LLM, and embedder dependency checks\n- mem0-backed memory with pluggable LLM/embedder providers\n- Optional graph relations support when graph mode is enabled\n\n## 🚀 Quickstart (Docker, Recommended)\n\n```bash\n# Copy .env.example to .env and put rotated provider keys there first\ndocker compose up -d --build\n\n# Optional: start bundled Keycloak profile for local OIDC\ndocker compose --profile oidc up -d keycloak\n```\n\nAvailable endpoints:\n- MCP: `http://localhost:8080/mcp`\n- Health: `http://localhost:8080/health`\n- Memgraph Lab UI: `http://localhost:3000`\n\n## 🐍 Quickstart (Local Python)\n\n```bash\npython -m pip install -e .[dev]\npython -m memoria\n```\n\nDefaults:\n- MCP: `http://0.0.0.0:8080/mcp`\n- Health: `http://0.0.0.0:8080/health`\n\n## 🔌 Connect from an MCP Client\n\n### OIDC mode\n\n```json\n{\n  \"mcpServers\": {\n    \"memoria\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"http://localhost:8080/mcp\",\n      \"headers\": {\n        \"authorization\": \"Bearer \u003caccess_token\u003e\"\n      }\n    }\n  }\n}\n```\n\nWithout a bearer token, requests are rejected.\n\nFor local Keycloak profile, issuer is `http://localhost:18081/realms/memoria`.\n\nOAuth metadata layout, the fact that `/oauth/register` does not persist dynamic client registration, loopback redirect constraints, RS256/Keycloak assumptions, and other auth details are documented in [docs/auth.md](docs/auth.md).\n\n### `local` mode\n\nThis is the default for local development. In local mode Memoria skips client authentication entirely and scopes all tools to a fixed configured user id (`MEMORIA_LOCAL_USER_ID`, default `local-user`).\n\n```json\n{\n  \"mcpServers\": {\n    \"memoria\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"http://localhost:8080/mcp\"\n    }\n  }\n}\n```\n\n### `stub_auth` mode\n\nUse this only behind a trusted auth proxy or during migration. In this mode the client passes user identity via `x-user-id` instead of a bearer token.\n\n```json\n{\n  \"mcpServers\": {\n    \"memoria\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"http://localhost:8080/mcp\",\n      \"headers\": {\n        \"x-user-id\": \"alice\"\n      }\n    }\n  }\n}\n```\n\n## 🛡️ Security Boundary\n\nIn `oidc` mode, identity is derived from validated JWT claims (`sub` by default).\n\nIn `local` mode, Memoria does not authenticate the client and always uses `MEMORIA_LOCAL_USER_ID`. Use it only for local development.\n\n`stub_auth` mode remains available for migration only. In this mode `x-user-id` is an identity input, not authentication, and should be used only behind a trusted auth proxy/gateway.\n\nLocal Keycloak realm note:\n- `deploy/keycloak/realm.json` includes a `memoria-e2e` client with direct access grants enabled for local-test only automation.\n- Production realm imports should remove that client or disable direct access grants.\n\n## 🧰 MCP Tools\n\nAll tools are scoped to the current user identity from the bearer token, the configured local user id, or the `x-user-id` header depending on auth mode.\n\n| Tool | Required args | What it does | Returns |\n| --- | --- | --- | --- |\n| `add_memory` | `text` | Stores a new memory. If `messages` is omitted, the server wraps `text` into a single user message. | mem0 add response for the created memory item(s) |\n| `search_memories` | `query` | Runs semantic search over the current user's memories. Supports `limit`, `filters`, `threshold`, and `rerank`. | mem0 search response with matching results |\n| `get_memory` | `memory_id` | Returns one memory by ID if it belongs to the current user. | single memory object or `null` |\n| `get_memories` | none | Lists memories for the current user. Supports `limit` and `filters`. | mem0 list response with memory items |\n| `update_memory` | `memory_id`, `data` | Updates the text payload of an existing memory owned by the current user. | mem0 update response |\n| `delete_memory` | `memory_id` | Deletes one memory owned by the current user. | mem0 delete response |\n| `delete_all_memories` | none | Deletes all memories for the current user scope. | mem0 bulk delete response |\n| `list_entities` | none | Returns graph relations from mem0 when graph mode is enabled. Supports `limit`. | `{ user_id, relations, supported, detail }` |\n| `delete_entities` | none | Deletes entities for the current user. In mem0 OSS this is mapped to `delete_all_memories`. | `{ user_id, detail, result }` |\n\n## 🏗️ Architecture\n\nMemoria is intentionally simple:\n\n```text\nMCP client -\u003e FastMCP server -\u003e mem0 -\u003e Qdrant\n                                  |\n                                  +-\u003e Memgraph (optional graph memory)\n```\n\nThat keeps the deployment easy to reason about and straightforward to self-host.\n\n## ⚙️ Configuration\n\nStart from [.env.example](.env.example). Most local setups only need auth mode, provider keys, and either the default Docker services or a reachable Qdrant/LLM/embedder stack.\n\n### Server and auth\n\n| Var | Default | Required | Description |\n| --- | --- | --- | --- |\n| `MEMORIA_HOST` | `0.0.0.0` | no | Bind host for the HTTP server |\n| `MEMORIA_PORT` | `8080` | no | Bind port for the HTTP server |\n| `MEMORIA_MCP_PATH` | `/mcp` | no | MCP endpoint path |\n| `MEMORIA_PUBLIC_BASE_URL` | `http://localhost:8080` | no | Public base URL used in advertised MCP/OAuth metadata |\n| `MEMORIA_AUTH_MODE` | `local` | no | Auth mode: `local`, `stub_auth`, or `oidc` |\n| `MEMORIA_LOCAL_USER_ID` | `local-user` | no | Fixed user id used in `local` mode |\n| `MEMORIA_USER_HEADER_NAME` | `x-user-id` | no | Identity header used in `stub_auth` mode |\n| `MEMORIA_OIDC_ISSUER_URL` | none | in `oidc` mode | Expected token issuer and default upstream OIDC issuer |\n| `MEMORIA_OIDC_PUBLIC_ISSUER_URL` | none | no | Browser-facing issuer for advertised OAuth endpoints |\n| `MEMORIA_OIDC_JWKS_URL` | none | no | Optional internal JWKS URL for server-side verification |\n| `MEMORIA_OIDC_AUDIENCE` | none | in `oidc` mode | Expected access token audience |\n| `MEMORIA_OIDC_SUBJECT_CLAIM` | `sub` | no | Claim used as the per-user identity |\n| `MEMORIA_OIDC_REQUIRED_SCOPES` | none | no | Optional space-separated scopes enforced by the verifier |\n| `MEMORIA_OIDC_JWKS_CACHE_TTL_SECONDS` | `300` | no | JWKS cache TTL in seconds |\n| `MEMORIA_LOG_LEVEL` | `INFO` | no | Application log level |\n\n### Qdrant\n\n| Var | Default | Required | Description |\n| --- | --- | --- | --- |\n| `MEMORIA_QDRANT_HOST` | `qdrant` | no | Qdrant host when not using a full URL |\n| `MEMORIA_QDRANT_PORT` | `6333` | no | Qdrant port when not using a full URL |\n| `MEMORIA_QDRANT_URL` | none | no | Full Qdrant URL; overrides host/port mode |\n| `MEMORIA_QDRANT_API_KEY` | none | no | API key for managed Qdrant deployments |\n| `MEMORIA_QDRANT_COLLECTION_NAME` | `mem0` | no | Collection name used by mem0 |\n| `MEMORIA_QDRANT_EMBEDDING_DIMS` | `1536` | no | Embedding dimension size for the collection |\n| `MEMORIA_QDRANT_ON_DISK` | `false` | no | Enables on-disk Qdrant storage mode |\n\n### mem0, LLM, and embedder\n\n| Var | Default | Required | Description |\n| --- | --- | --- | --- |\n| `MEMORIA_MEM0_VERSION` | `v1.1` | no | mem0 API/config version passed to the SDK |\n| `MEMORIA_MEM0_HISTORY_DB_PATH` | `./data/mem0_history.db` | no | Local history DB path used by mem0 |\n| `MEMORIA_MEM0_LLM_PROVIDER` | `vllm` | no | LLM provider passed to mem0 |\n| `MEMORIA_MEM0_LLM_MODEL` | `gpt-4o-mini` | no | LLM model name |\n| `MEMORIA_MEM0_LLM_BASE_URL` | empty | no | Optional base URL override for the LLM provider |\n| `MEMORIA_MEM0_LLM_API_KEY` | `dummy` | no | LLM API key; local OpenAI-compatible stacks can use any non-empty value |\n| `MEMORIA_MEM0_EMBEDDER_PROVIDER` | `openai` | no | Embedder provider passed to mem0 |\n| `MEMORIA_MEM0_EMBEDDER_MODEL` | `text-embedding-3-small` | no | Embedder model name |\n| `MEMORIA_MEM0_EMBEDDER_BASE_URL` | empty | no | Optional base URL override for the embedder provider |\n| `MEMORIA_MEM0_EMBEDDER_API_KEY` | `dummy` | no | Embedder API key; local compatible stacks can use any non-empty value |\n\n### Optional graph mode\n\n| Var | Default | Required | Description |\n| --- | --- | --- | --- |\n| `MEMORIA_MEM0_ENABLE_GRAPH` | `false` | no | Enables graph memory support in mem0 |\n| `MEMORIA_MEM0_GRAPH_PROVIDER` | `memgraph` | no | Graph provider name |\n| `MEMORIA_MEM0_GRAPH_URL` | `bolt://memgraph:7687` | when graph enabled | Memgraph connection URL |\n| `MEMORIA_MEM0_GRAPH_USERNAME` | `memgraph` | when graph enabled | Memgraph username |\n| `MEMORIA_MEM0_GRAPH_PASSWORD` | `memgraph` | when graph enabled | Memgraph password |\n\n## ✅ Quality \u0026 Tests\n\nQuality checks:\n\n```bash\npython -m ruff check .\npython -m mypy src\n```\n\nUnit tests:\n\n```bash\npython -m pytest -q tests/unit --cov=src/memoria --cov-report=term-missing\n```\n\nE2E tests (Docker + Testcontainers):\n\n```bash\nRUN_E2E=1 python -m pytest -q tests/e2e\n```\n\n\u003cdetails\u003e\n\u003csummary\u003ePowerShell\u003c/summary\u003e\n\n```powershell\n$env:RUN_E2E='1'\npython -m pytest -q tests/e2e\n```\n\n\u003c/details\u003e\n\n## 📍 Positioning and Scope\n\n- This project is community-maintained.\n- It is focused on practical integration and fast self-hosting.\n- It does not claim affiliation with mem0.\n\n## 🧭 Roadmap\n\n- Planned role/scope-based authorization for MCP tools with read/write/admin separation\n- Planned production deployment presets, including Docker hardening and Kubernetes Helm charts\n- Planned observability package with structured logs, Prometheus metrics, and tracing\n- Planned integration examples for additional MCP clients and providers\n\n## 📄 License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivkond%2Fmemoria","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivkond%2Fmemoria","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivkond%2Fmemoria/lists"}