nacre
Provides a self-hosted knowledge index with document-level permissions, enabling AI agents to retrieve exactly the documents they are authorized to see via MCP. Supports OAuth 2.1, custom embedding models, and runs inside your network.
README
<div align="center"> <img src="docs/assets/nacre-mark.svg" width="72" alt="Nacre"> <h1>Nacre</h1> <p><strong>Your index. Your access rules. Your perimeter.<br> Agents see exactly what they're allowed to see.</strong></p> <p> <a href="https://nacre.work">nacre.work</a> · <a href="./docs">Docs</a> · <a href="./docs/quickstart.md">Quickstart</a> · <a href="https://github.com/nacre-work/nacre/discussions">Discussions</a> </p> </div>
Nacre is a self-hosted knowledge index with fine-grained access control. Agents reach it over MCP, applications over a REST API. No chat interface, no company assistant — just the context layer underneath them.
Why
Vector search is a solved problem. What isn't solved: making sure an agent querying a company index sees exactly the documents the requesting user is cleared for — and being able to prove it to an auditor.
- Permissions that inherit. Workspaces → layers, with
read/write/admininherited top-down.writedoes not implyread;adminimplies both. Document-level grants and deny rules are commercial — this build refuses them and says so, rather than accepting a rule it cannot propagate. - Filtering happens inside the index. Access filters are applied during
HNSW traversal, not after ranking, so
top_kreturns k permitted results rather than k minus whatever got stripped out. - MCP as a first-class surface. Streamable HTTP per the 2026-07-28 spec, OAuth 2.1 with PKCE and CIMD. Local STDIO for developer agents.
- Bring your own models. Embeddings through any OpenAI-compatible endpoint, bound per layer, swappable with zero-downtime reindexing.
- Stays inside your network. Docker Compose, no phone-home.
Quickstart
git clone https://github.com/nacre-work/nacre && cd nacre
cp .env.example .env
docker compose --profile minimal up -d
Full walkthrough: docs/quickstart.md.
Layout
packages/api REST API and authorization service
packages/mcp MCP server (Streamable HTTP + STDIO)
packages/worker indexing pipeline: parse, chunk, embed
packages/core data model, permission resolver, shared types
packages/sdk TypeScript SDK
packages/admin community admin UI
services/parser Python sidecar: bytes → {text, blocks, metadata}
docs/ specifications — normative, and ahead of the code
State
Early, and it runs. The loop works end to end and has been driven by hand
against a real PostgreSQL and a real Qdrant: create an organization, create a
layer, grant someone read, ingest a document, poll the job to indexed,
search and get the chunk back — and search as someone without the grant and get
nothing while the vectors are still sitting in the index. Both surfaces work,
REST and MCP over Streamable HTTP and STDIO alike. Revoking a grant removes the
document from results, and the recomputation that refreshes the index tags runs
in the worker with a metric on how far behind it is.
What is not built: no login — tokens are signed with a shared secret and issued
by the init command, so there is no user-facing authentication yet; no
reranking on the search path; no garbage collection for tombstoned vectors; and
the SDK and admin UI are empty packages. docker compose up has not been run
from a clean checkout, though its profiles are validated in CI.
docs/ is the specification, and it still runs ahead of the code in places —
start with docs/authz.md, which everything else depends on.
Invariants
Six rules. Breaking any of them is a security incident, not a bug. Details in docs/authz.md.
- The organization comes from the token and nowhere else.
- Access filtering is a pre-filter, never a post-filter.
- A failure to evaluate permissions denies access.
- "No permission" and "no such object" return identical responses.
- A deleted document is never returned, including before garbage collection.
writedoes not implyread.
License
Apache 2.0. Multi-tenancy, SSO/SCIM, EMA, and audit ship as separate commercial modules — see nacre.work/enterprise.
The Nacre name and mark are trademarks; see TRADEMARK.md.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.