{"id":51699548,"url":"https://github.com/geanatz/curion","last_synced_at":"2026-07-16T09:04:58.154Z","repository":{"id":368292196,"uuid":"1267109413","full_name":"geanatz/curion","owner":"geanatz","description":"Curion is a project-local memory layer for AI coding agents, published as an MCP server for Claude Code, Codex, OpenCode, and other MCP clients.","archived":false,"fork":false,"pushed_at":"2026-06-29T23:39:14.000Z","size":4113,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T00:09:38.286Z","etag":null,"topics":["ai","ai-agents","ai-memory","claude","claude-code","codex","coding-agents","context-management","knowledge-base","llm","local-first","mcp","mcp-server","model-context-protocol","opencode","pi-coding-agent","project-memory","semantic-search"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@geanatz/curion","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/geanatz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"geanatz"}},"created_at":"2026-06-12T08:22:25.000Z","updated_at":"2026-06-29T23:39:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/geanatz/curion","commit_stats":null,"previous_names":["geanatz/curion"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/geanatz/curion","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geanatz%2Fcurion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geanatz%2Fcurion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geanatz%2Fcurion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geanatz%2Fcurion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geanatz","download_url":"https://codeload.github.com/geanatz/curion/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geanatz%2Fcurion/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35537785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-16T02:00:06.687Z","response_time":83,"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","ai-agents","ai-memory","claude","claude-code","codex","coding-agents","context-management","knowledge-base","llm","local-first","mcp","mcp-server","model-context-protocol","opencode","pi-coding-agent","project-memory","semantic-search"],"created_at":"2026-07-16T09:04:58.004Z","updated_at":"2026-07-16T09:04:58.148Z","avatar_url":"https://github.com/geanatz.png","language":"TypeScript","funding_links":["https://github.com/sponsors/geanatz"],"categories":["Extensions"],"sub_categories":[],"readme":"# Curion\n\n[![npm](https://img.shields.io/npm/v/@geanatz/curion)](https://www.npmjs.com/package/@geanatz/curion)\n![Node](https://img.shields.io/node/v/@geanatz/curion)\n[![CI](https://img.shields.io/github/actions/workflow/status/geanatz/curion/ci.yml?branch=main\u0026label=ci)](https://github.com/geanatz/curion/actions/workflows/ci.yml)\n[![provenance](https://img.shields.io/badge/provenance-verified-blue)](https://docs.npmjs.com/generating-provenance-statements)\n[![License](https://img.shields.io/github/license/geanatz/curion)](https://github.com/geanatz/curion/blob/main/LICENSE)\n\n\u003e **Project-local memory layer for AI agents, exposed as a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) stdio server.**\n\nCurion gives your AI agent a **persistent memory of the project it is working\nin**. Across sessions it can remember design decisions, architecture choices,\nteam conventions, and anything else you choose to store — and recall the\nrelevant pieces when you ask.\n\nIt runs as a local MCP stdio server that any compatible client can spawn.\nEach project has its own private store at `.curion/`; memories are never\nsent to a shared backend.\n\nThe public MCP API (the two tools, their strict input schemas, and the public\n`text` / `structuredContent` surfaces) is stable and frozen.\n\n---\n\n## Table of contents\n\n- [Why Curion](#why-curion)\n- [Quick start](#quick-start)\n- [Other MCP clients](#other-mcp-clients)\n- [Example prompts](#example-prompts)\n- [Key features](#key-features)\n- [Privacy \u0026 storage](#privacy--storage)\n- [Configuration essentials](#configuration-essentials)\n- [Troubleshooting](#troubleshooting)\n- [Documentation](#documentation)\n- [Support, security, and contributing](#support-security-and-contributing)\n\n---\n\n## Why Curion\n\n- **Persistent, project-local memory.** Design decisions, conventions, and\n  \"things to remember\" survive across sessions inside `.curion/`.\n- **Two tools, one surface.** `remember(text)` stores a piece of project\n  memory; `recall(text)` retrieves the relevant pieces. Each takes a single\n  `text` parameter — no kinds, states, filters, or knobs on the public API.\n- **Private by default.** Memory lives in your project. Memories are never\n  sent to a shared backend. Mark a project private with one line of JSON\n  and it will never be surfaced by cross-project retrieval.\n- **Pluggable providers.** OpenAI-compatible (default) or Anthropic. Add a\n  fallback provider, or enable opt-in semantic retrieval.\n- **Stable, frozen public API.** The two tools, their strict input schemas,\n  and the public `text` / `structuredContent` surfaces are stable and frozen.\n\n---\n\n## Quick start\n\nRequires **Node.js `\u003e= 22`** (matches the `engines.node` field in `package.json`).\n\n```sh\n# Recommended: install globally so the `curion` binary is on your PATH.\nnpm install -g @geanatz/curion\n```\n\nThe package installs a `curion` CLI binary which is the MCP stdio server\nentrypoint. When an MCP client spawns it, `curion` speaks JSON-RPC over\nstdin/stdout and writes all logs to stderr. It is **not** an interactive\nCLI — always start it through an MCP client that manages the stdio transport.\n\n\u003e **stdio transport only.** Curion only exposes the stdio transport. It does\n\u003e **not** open any network sockets and does **not** run as a long-lived\n\u003e process you start from a terminal. The MCP host (your client) spawns\n\u003e `curion` as a subprocess and is responsible for the network boundary.\n\u003e See [Security model](docs/privacy-storage.md#security-model).\n\n### Register with your MCP client\n\nClaude Code is the recommended MCP client. Registering Curion with\n`--scope project` keeps the configuration inside the repo (via\n`.mcp.json`), so every contributor gets the same server setup without\ntouching their global MCP config.\n\n```sh\nclaude mcp add --scope project --transport stdio curion -- curion\n```\n\nFor Codex CLI, OpenCode, Claude Desktop, and other clients, see\n[MCP client setup](docs/mcp-clients.md).\n\n### Provide a provider\n\nCurion has **no built-in provider defaults**. Configure a primary\nprovider in your shell environment before launching the MCP client\n(Curion does not load `.env` files):\n\n```sh\n# OpenAI-compatible (default)\nexport CURION_PRIMARY_API_KEY=sk-...\nexport CURION_PRIMARY_BASE_URL=https://api.openai.com/v1\nexport CURION_PRIMARY_MODEL=your-model-id\n\n# Anthropic\nexport CURION_PRIMARY_API_FORMAT=anthropic\nexport CURION_PRIMARY_API_KEY=sk-ant-...\nexport CURION_PRIMARY_MODEL=your-model-id\n```\n\nFull env-var reference: [Configuration](docs/configuration.md).\n\n---\n\n## Other MCP clients\n\nCurion works with any MCP client that can spawn a stdio server. Full\nconfiguration snippets and caveats:\n\n- **[Claude Code (recommended)](docs/mcp-clients.md#claude-code-recommended)** — `claude mcp add --scope project --transport stdio curion -- curion`.\n- **[OpenAI Codex CLI](docs/mcp-clients.md#openai-codex-cli)** — `config.toml` or `codex mcp add`.\n- **[OpenCode](docs/mcp-clients.md#opencode)** — `opencode.json`.\n- **[Claude Desktop](docs/mcp-clients.md#claude-desktop-generic--secondary)** — generic stdio client.\n- **[Pi Coding Agent](docs/mcp-clients.md#pi-coding-agent-no-native-mcp-support)** — Pi has no native MCP support; use Claude Code, Codex CLI, or OpenCode instead.\n- **[Any other stdio MCP client](docs/mcp-clients.md#other-mcp-clients-generic-stdio)** — spawn `curion` with provider env vars in the environment.\n\n---\n\n## Example prompts\n\nOnce your MCP client is connected, the agent can call `remember` and\n`recall` directly. The strings below are exactly what an agent would pass\nas the `text` parameter.\n\n**Store a design decision:**\n\n```text\nremember: \"We chose SQLite (better-sqlite3) over Postgres for the memory\nstore because the project is single-host and the binary footprint is\nsmaller. Migration to a hosted DB is not in scope.\"\n```\n\n**Store a convention:**\n\n```text\nremember: \"Conventions: TypeScript strict mode on, 2-space indent,\ndouble-quoted strings, Biome for lint+format. See CONTRIBUTING.md.\"\n```\n\n**Recall later:**\n\n```text\nrecall: \"Why did we pick SQLite over Postgres for the memory store?\"\n```\n\n**Ask about a convention:**\n\n```text\nrecall: \"What are the project's formatting and lint conventions?\"\n```\n\nThe agent receives a calm prose `text` content block plus a structured\ndiscriminated shape on `structuredContent`. Discriminate with\n`structuredContent.status` (`saved` / `answered` / `weak_match` /\n`no_memory` / `rejected` / `provider_error`). When\n`clarification_needed` is present, the agent must ask the user the\n`question` verbatim — see the\n[API reference](docs/reference.md#clarification_needed).\n\n---\n\n## Key features\n\n- **Two tools, one surface.** `remember(text)` stores a piece of project\n  memory; `recall(text)` retrieves the relevant pieces. Each takes a single\n  `text` parameter — no kinds, states, filters, or knobs on the public API.\n- **Raw input is never persisted.** Only controller-normalized summaries\n  and metadata (kind, confidence, safety flags, timestamps) land in the\n  local SQLite store.\n- **Project-local by default.** Memory lives in `.curion/` inside the\n  project. Memories are never sent to a shared backend.\n- **Pluggable providers.** OpenAI-compatible (default) or Anthropic.\n  Add a fallback provider, or enable opt-in semantic retrieval.\n- **Stable, frozen public API.** The two tools, their strict input schemas,\n  and the public `text` / `structuredContent` surfaces are stable and frozen.\n- **Reproducible installs.** The npm package is published with Trusted\n  Publishing and OIDC provenance (`publishConfig.provenance: true`); no\n  long-lived `NPM_TOKEN` secret is required.\n\nSee the full [API reference](docs/reference.md) for statuses, output shapes,\nand the `clarification_needed` contract.\n\n---\n\n## Privacy \u0026 storage\n\nEach project has its own `.curion/` directory. Memories are stored locally\nand are **never** sent to a shared backend.\n\n```\n\u003cprojectRoot\u003e/.curion/\n  curion.sqlite            # SQLite database (gitignored)\n  trace.sqlite             # Local trace database (gitignored, opt-out via env)\n  transformers-cache/      # Embedder cache when semantic retrieval is on\n  config.json              # Project config (e.g. { isPrivate: true })\n```\n\nWhen semantic retrieval is enabled, Curion may semantically search\nexternal **non-private** projects alongside the local project. **Private\nprojects are never surfaced.** Mark a project private with\n`.curion/config.json`:\n\n```json\n{ \"version\": 1, \"isPrivate\": true }\n```\n\nSee [Privacy \u0026 storage](docs/privacy-storage.md) for the full story,\nincluding the security model, trace redaction, and `.curion/config.json`\nsemantics.\n\n---\n\n## Configuration essentials\n\nCurion is configured entirely through environment variables passed by the\nparent process. It does **not** load `.env` files.\n\nThe minimum is a primary provider (`CURION_PRIMARY_API_KEY`,\n`CURION_PRIMARY_BASE_URL`, `CURION_PRIMARY_MODEL`, optionally\n`CURION_PRIMARY_API_FORMAT`). Optional knobs cover a fallback provider,\nsemantic retrieval (`CURION_SEMANTIC_ENABLED`), log level\n(`CURION_LOG_LEVEL`), and trace enable/disable\n(`CURION_TRACE_ENABLED`).\n\nSee [Configuration](docs/configuration.md) for the full variable list and\nexamples.\n\n---\n\n## Troubleshooting\n\n**Curion started but the agent can't see the tools.** The MCP host is the\nprocess boundary. Make sure the spawn succeeded (look at stderr) and that\nthe host's tool list refresh picked up the new server. With Claude Code,\nrun `claude mcp list` to confirm `curion` is registered.\n\n**\"No relevant memory found.\" but you know you stored something.** The\ncontroller only stores controller-normalized summaries, not raw input. If\nyour `remember` call was `rejected` (e.g. safety filter), no row was\nwritten. With `CURION_LOG_LEVEL=debug`, the recall-side retrieval logs\nthe candidate set, scores, and threshold decisions.\n\n**Tool returns `provider_error`.** The provider call failed. Check the\n`reason` field on `structuredContent`, confirm the env vars are present\nin the spawn environment (Curion does **not** load `.env` files), and\ncheck the provider's own status page.\n\n**Inspect the JSON-RPC stream.** The official\n[MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) is the\ncanonical tool for ad-hoc debugging — it spawns the stdio server, lets you\nlist tools, and lets you invoke `remember` / `recall` with arbitrary\n`text`:\n\n```sh\nnpx -y @modelcontextprotocol/inspector curion\n```\n\n**Anything written to stdout corrupts the protocol.** All logging travels\non stderr (see [Configuration → Logging](docs/configuration.md#logging)).\nIf you wrap or redirect `curion`, never redirect or capture stdout —\nredirect stderr instead. A single stray `console.log` from a wrapper will\nbreak every subsequent JSON-RPC frame.\n\n**Windows / `npx -y` gotchas.** If your MCP client does not resolve a\nbinary on `PATH` (common on Windows), use the `cmd /c npx` wrapper\ndescribed in [MCP client setup → Windows / `npx` wrapper](docs/mcp-clients.md#windows--npx-wrapper).\nFor project-local installs without a global `curion` on `PATH`, prefer\nthe **absolute path** to `node_modules/.bin/curion` rather than relying\non shell resolution — see the same page.\n\n---\n\n## Documentation\n\n- **[MCP client setup](docs/mcp-clients.md)** — Claude Code, Codex CLI,\n  OpenCode, Claude Desktop, Pi caveat, generic stdio, Windows `npx`\n  wrapper, absolute-path guidance.\n- **[Configuration](docs/configuration.md)** — primary/fallback provider\n  env vars, semantic retrieval, logging, trace toggle.\n- **[API reference](docs/reference.md)** — `remember` / `recall` tools,\n  output shapes, statuses, `clarification_needed`.\n- **[Privacy \u0026 storage](docs/privacy-storage.md)** — local store layout,\n  cross-project semantic search, private projects, trace, security model.\n- **[CHANGELOG](CHANGELOG.md)** — release notes (Keep a Changelog format).\n\n---\n\n## Support, security, and contributing\n\n- **Bug reports and feature requests:** open a GitHub issue at\n  [`github.com/geanatz/curion/issues`](https://github.com/geanatz/curion/issues).\n- **Security issues:** do **not** file a public issue — see\n  [SECURITY.md](SECURITY.md) for the private reporting channel. Expected\n  response time is 7 days.\n- **Contributing:** see [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow,\n  development setup, and testing expectations. By participating, you\n  agree to the [Code of Conduct](CODE_OF_CONDUCT.md).\n- **License:** [Apache License 2.0](LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeanatz%2Fcurion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeanatz%2Fcurion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeanatz%2Fcurion/lists"}