[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80747":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":41,"readmeContent":42,"aiSummary":43,"trendingCount":16,"starSnapshotCount":16,"syncStatus":44,"lastSyncTime":45,"discoverSource":46},80747,"akb","dnotitia\u002Fakb","dnotitia","AKB — Agent Knowledgebase. Organizational memory for AI agents: vault-scoped docs \u002F tables \u002F files unified by URI graph, served over MCP.","",null,"Python",52,3,1,5,0,7,9,11,21,1.81,"Other",false,"main",true,[27,28,29,30,31,32,33,34,35,36,37,38,39,40],"agent","claude","claude-code","fastapi","knowledge-base","knowledge-graph","mcp","model-context-protocol","multi-tenant","pgvector","postgres","rag","react","vector-search","2026-06-12 02:04:06","\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fakb-hero.png\" alt=\"AKB — agents reading and writing into a permissioned knowledge vault of docs, tables, and files, linked by a URI graph\" width=\"100%\">\n\u003C\u002Fp>\n\n# AKB — Agent Knowledge Base\n\n> **Organizational memory for AI agents.** Git-backed knowledge base served\n> over the **Model Context Protocol (MCP)** — agents read and write directly\n> with hybrid semantic + keyword search, structured tables, files, and a URI\n> graph. Drop-in alternative to Confluence \u002F Notion for Claude Code, Cursor,\n> Windsurf, and any MCP-aware agent.\n\n[![License: PolyForm NC](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-PolyForm%20NC%201.0-blue.svg)](.\u002FLICENSE)\n[![npm: akb-mcp](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Fakb-mcp.svg?label=npm%3A%20akb-mcp)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fakb-mcp)\n[![MCP](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMCP-Streamable%20HTTP-orange.svg)](https:\u002F\u002Fmodelcontextprotocol.io)\n\n## Works with\n\nAny agent client that speaks **MCP (Streamable HTTP or stdio)**:\n\n- **Claude Code** — CLI \u002F VS Code \u002F JetBrains\n- **Claude Desktop** — macOS \u002F Windows\n- **Cursor**, **Windsurf**, **Cline**, **Continue** — via the\n  [`akb-mcp`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fakb-mcp) stdio proxy\n- Custom agents — direct HTTP `POST \u002Fmcp\u002F` with a Bearer token\n\n## Why AKB\n\nMost knowledge tools are built for humans clicking through a UI. Agents need a\ndifferent shape: structured documents, semantic + keyword search in one call,\nexplicit relations, and full version history. AKB gives agents a single set of\ntools (`akb_put`, `akb_search`, `akb_browse`, `akb_relations`, …) over a\nbacking store of Git bare repos and a PostgreSQL hybrid index.\n\n## Retrieval quality\n\nMemory is only useful if the right note comes back. AKB's hybrid retrieval\n(dense + BM25, source-level dedup) was benchmarked on\n[LongMemEval](https:\u002F\u002Fgithub.com\u002Fxiaowu0162\u002FLongMemEval)-S — 500 long-context\nquestions, ~50 chat sessions per question. **Recall@5 = 98.4%**, with no\nreranker in the loop.\n\n| System | R@5 | n | Reranker | Source |\n|---|---:|:---:|:---:|---|\n| **AKB hybrid** | **98.4%** | 500 | no | this repo |\n| MemPalace hybrid + rerank | 98.4% | 450 | yes | [MemPalace](https:\u002F\u002Fgithub.com\u002Fmempalace\u002Fmempalace) |\n| gbrain hybrid | 97.6% | 500 | no | [gbrain-evals](https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain-evals) |\n| gbrain vector | 97.4% | 500 | no | gbrain-evals |\n\nMethodology, per-category breakdown, and a one-command reproducible harness\nlive in [`eval\u002Flongmemeval\u002F`](eval\u002Flongmemeval\u002F). The embedding model differs\nacross systems (AKB: `bge-m3@1024`), so read this as a stack-level comparison.\n\n## Design philosophy\n\n**Core stays small; flexibility comes from extension, not built-in\nautomation.** AKB does not ship its own consolidator, summariser, or\n\"knowledge gardener\" — instead every write emits a structured event to a\nRedis Stream (`akb:events`). Operators wire any external consumer\n(periodic synthesis bot, doc-rot reaper, weekly-digest agent, audit\ntrail, …) on top, with no patches to the core. The base contract is a\nread\u002Fwrite store; opinions about *what to do with* the knowledge live\noutside.\n\n## Architecture\n\n```\n┌──────────────────────────────────────────────────────────┐\n│                  Access Layer                            │\n│   MCP Server  │  REST API  │  Web UI                     │\n├──────────────────────────────────────────────────────────┤\n│                  Core Services                           │\n│   Document (Put\u002FGet)  │  Search (Hybrid: dense+BM25)     │\n│   Relations (graph)   │  Session  │  Publications        │\n├──────────────────────────────────────────────────────────┤\n│                  Storage Layer                           │\n│   Git bare repos       │  PostgreSQL 16 (text + meta SoT)│\n│                        │  Vector store (driver):         │\n│                        │    pgvector  (default, same PG) │\n│                        │    qdrant    (optional)         │\n│                        │    seahorse  (managed, optional)│\n└──────────────────────────────────────────────────────────┘\n```\n\nPostgreSQL is the source of truth — chunk text + metadata + BM25 vocab.\nThe vector store is a driver-pluggable derived index holding dense\nembeddings and corpus-side sparse vectors. Full vector-store loss is\nrecoverable from PG by setting `chunks.vector_indexed_at = NULL` and\nletting the indexing worker re-populate.\n\n## Key Concepts\n\n- **Vault** — A Git bare repo. The unit of access control and physical isolation.\n- **Collection** — A directory inside a vault. Topical grouping of documents.\n- **Document** — Markdown + YAML frontmatter, optimised for agent read\u002Fwrite.\n- **Hybrid Search** — Dense (semantic) + BM25 (lexical) fused via RRF in one call.\n- **Relations** — `depends_on`, `related_to`, `implements` in frontmatter form an explicit knowledge graph.\n- **Vault isolation in `akb_sql`** — Enforced by PostgreSQL ACL. Each\n  AKB user has a corresponding PG role (`akb_user_\u003Cuid>`) and each\n  vault has three group roles (`akb_vault_\u003Cvid>_{reader,writer,admin}`).\n  `akb_sql` runs the user's SQL inside a transaction with\n  `SET LOCAL ROLE`; cross-vault references return PG `42501`\n  directly. No application-side regex inspects user SQL for forbidden\n  identifiers. See `docs\u002Fdesigns\u002Fpg-native-rbac\u002F`.\n\n## MCP Tools (selection)\n\n| Tool | Description |\n|------|-------------|\n| `akb_list_vaults` \u002F `akb_create_vault` | Vault management |\n| `akb_put` \u002F `akb_get` \u002F `akb_update` \u002F `akb_delete` | Document CRUD (Git commit + indexing) |\n| `akb_put_file` \u002F `akb_get_file` \u002F `akb_delete_file` | File attachments — proxy-side (requires local filesystem) |\n| `akb_create_table` \u002F `akb_alter_table` \u002F `akb_drop_table` \u002F `akb_sql` | Tabular content — per-doc tables + SQL |\n| `akb_browse` | Tree traversal (collection → docs) |\n| `akb_search` \u002F `akb_grep` | Hybrid search (dense + BM25) \u002F literal grep |\n| `akb_drill_down` | Section-level retrieval |\n| `akb_relations` \u002F `akb_link` \u002F `akb_unlink` \u002F `akb_graph` | Knowledge graph |\n| `akb_edit` \u002F `akb_diff` \u002F `akb_history` | In-place edit, diff, Git history |\n| `akb_grant` \u002F `akb_revoke` \u002F `akb_set_public` | Permission boundaries — per-user, per-org, public |\n| `akb_remember` \u002F `akb_recall` \u002F `akb_forget` | Agent memory |\n| `akb_session_start` \u002F `akb_session_end` | Session lifecycle |\n| `akb_publish` \u002F `akb_unpublish` | Public publication |\n\nThe full tool catalogue is exposed via `akb_help()` from any MCP client.\n\n## Document Format\n\nEvery vault resource has a location-aware AKB URI — the canonical handle\nused by every tool and stored in relations. As of 0.3.0:\n\n```\nakb:\u002F\u002F{vault}                                          vault root (browse target)\nakb:\u002F\u002F{vault}\u002Fcoll\u002F{coll_path}                         collection (browse target)\nakb:\u002F\u002F{vault}[\u002Fcoll\u002F{coll_path}]\u002Fdoc\u002F{filename}        document\nakb:\u002F\u002F{vault}[\u002Fcoll\u002F{coll_path}]\u002Ftable\u002F{name}          table\nakb:\u002F\u002F{vault}[\u002Fcoll\u002F{coll_path}]\u002Ffile\u002F{uuid}           file\n```\n\nThe `\u002Fcoll\u002F{coll_path}` segment is omitted for resources at the vault\nroot. Walking up a URI to its parent collection is a pure string\noperation — paste the parent into `akb_browse(uri=...)` to list\nsiblings without an extra lookup.\n\n```yaml\n---\ntitle: \"Payment API v2 migration plan\"\ntype: plan              # note | report | decision | spec | plan | session | task | reference\nstatus: active          # draft | active | archived | superseded\ntags: [payments, api]\ndomain: engineering\nsummary: \"REST → gRPC transition plan.\"\ndepends_on: [\"akb:\u002F\u002Feng\u002Fcoll\u002Fspecs\u002Fdoc\u002Fpayment-api-v2.md\"]\nrelated_to: [\"akb:\u002F\u002Feng\u002Fcoll\u002Fmeetings\u002Fdoc\u002F2026-05-01-payments.md\"]\n---\n\n# Payment API v2 migration plan\n...\n```\n\n## Quick Start\n\nAKB ships as a **3-container stack** (PostgreSQL with pgvector + backend +\nfrontend). You bring an OpenAI-compatible embedding endpoint (OpenAI,\nOpenRouter, self-hosted vLLM\u002FTEI, etc.) — that's the only required external\ndependency for core CRUD and search. Prefer running a separate Qdrant\ncluster, or pointing at a managed Seahorse Cloud table? See *Vector store*\nbelow.\n\n```bash\n# 1. Configure\ncp config\u002Fapp.yaml.example   config\u002Fapp.yaml\ncp config\u002Fsecret.yaml.example config\u002Fsecret.yaml\n$EDITOR config\u002Fsecret.yaml   # set embed_api_key (and jwt_secret for any non-local deploy)\n\n# 2. Run\ndocker compose up -d\n\n# 3. Open\nopen http:\u002F\u002Flocalhost:3000\n```\n\n`config\u002Fapp.yaml` and `config\u002Fsecret.yaml` are the **single source of runtime\nconfiguration** — no environment variables are read by the backend. Mount the\n`config\u002F` directory at `\u002Fetc\u002Fakb\u002F` in any deployment.\n\n### Vector store (driver-pluggable)\n\nHybrid search (dense + BM25 sparse, RRF-fused) runs through a driver\ninterface. Three drivers ship; pick at config time:\n\n- **`pgvector`** (default) — uses the same Postgres container that holds\n  application data. The pgvector\u002Fpgvector image pre-installs the\n  extension; the driver creates a separate `vector_index` schema, so the\n  main `chunks` table stays plain PostgreSQL. RRF fusion runs\n  application-side. No external service to operate.\n- **`qdrant`** — runs a separate Qdrant container; native RRF via the\n  Query API. Useful when you already operate Qdrant or want to scale\n  the vector store independently of Postgres.\n- **`seahorse`** — points at a managed [Seahorse Cloud][shc] table over\n  its TABLE_V2 + BFF API (Bearer auth, per-table host). No\n  infrastructure to run on your side; you provision a table in the\n  Seahorse console (or let the driver auto-create one) and AKB stores\n  its chunks there. Native RRF, server-side BM25. See\n  [`docs\u002Fvector-store-seahorse.md`](.\u002Fdocs\u002Fvector-store-seahorse.md)\n  for the end-to-end setup walkthrough (sign-up → token → schema →\n  config).\n\n[shc]: https:\u002F\u002Fconsole.seahorse.dnotitia.ai\n\nSwitching drivers is a config edit (no schema migration on the main DB):\n\n```bash\n# Default flow targets pgvector.\ndocker compose up\n\n# Qdrant:\ndocker compose -f docker-compose.yaml -f docker-compose.qdrant.yaml up\n$EDITOR config\u002Fapp.yaml     # vector_store_driver: qdrant\n                            # vector_url: http:\u002F\u002Fqdrant:6333\n\n# Seahorse Cloud (managed; full guide in docs\u002Fvector-store-seahorse.md):\ndocker compose up           # no extra container needed\n$EDITOR config\u002Fapp.yaml     # vector_store_driver: seahorse\n                            # seahorse_tenant_uuid: \u003Cyour tenant>\n                            # seahorse_table_name: \u003Cyour table>\n$EDITOR config\u002Fsecret.yaml  # seahorse_token: shsk_\u003C...>\n```\n\nEmbedding model + dimensions are also fully pluggable via\n`embed_base_url` \u002F `embed_model` \u002F `embed_dimensions` — the codebase has\nno hard-coded model. For pgvector with HNSW, keep `embed_dimensions ≤ 2000`\n(or 4000 with `halfvec`); larger models fall back to exact scan.\nQdrant\u002FSeahorse have no such limit (Qdrant up to 65536, Seahorse up to\nits table-defined dim).\n\n### LLM features (optional)\n\nLLM is only used by the `metadata_worker` to auto-tag documents imported via\nexternal git mirroring. Core CRUD\u002Fsearch works without it. To enable, set\n`llm_base_url` \u002F `llm_model` in `app.yaml` and `llm_api_key` in `secret.yaml`.\n\n### Event fanout (optional)\n\nThe PG `events` outbox is always written. Set `redis_url` in `app.yaml` to\nhave the `events_publisher` worker drain the outbox to a Redis Stream\n(`akb:events`) so external services can subscribe via `XREAD` \u002F consumer\ngroups. Leave blank to disable; events still accumulate in PG and you can\nbuild an SSE endpoint on top of the LISTEN\u002FNOTIFY trigger without Redis.\n\n### Production deployment\n\nFor Kubernetes, see [`deploy\u002Fk8s\u002FREADME.md`](.\u002Fdeploy\u002Fk8s\u002FREADME.md). The\n`deploy\u002Fk8s\u002F` directory contains a generic kustomize base; provide your\nown registry, hostname, and TLS issuer via the documented env vars or an\noperator-private overlay under `deploy\u002Fk8s\u002Finternal\u002F`.\n\n## Project Structure\n\n```\nakb\u002F\n├── backend\u002F                  # Python 3.11 \u002F FastAPI \u002F asyncpg \u002F GitPython\n│   ├── app\u002F\n│   │   ├── api\u002Froutes\u002F       # REST endpoints\n│   │   ├── services\u002F         # Business logic + workers\n│   │   └── db\u002F               # PostgreSQL schema + migrations\n│   ├── mcp_server\u002F           # Streamable HTTP MCP server\n│   └── tests\u002F                # E2E shell tests\n├── frontend\u002F                 # React 19 + TypeScript + Vite + Tailwind\n├── packages\u002F\n│   └── akb-mcp-client\u002F       # stdio ↔ HTTP MCP proxy (npm: akb-mcp)\n├── agents\u002F                   # Reference Python agent runtime (think\u002Fact loop over MCP)\n├── templates\u002F                # Doc templates (ADR, PRD, runbook, …) and vault profiles\n├── design-system\u002F            # Frontend design system docs\n├── config\u002F\n│   ├── app.yaml.example      # Non-secret runtime settings\n│   └── secret.yaml.example   # API keys, passwords (gitignored when not .example)\n├── deploy\u002F\n│   └── k8s\u002F                  # Generic kustomize base for Kubernetes\n└── docker-compose.yaml       # 3-container local stack (postgres + backend + frontend)\n```\n\n## Tech Stack\n\n- **Backend**: Python 3.11, FastAPI, Uvicorn, asyncpg, GitPython, MCP SDK\n- **Database**: PostgreSQL 16 (main DB needs no extension; the same\n  pgvector\u002Fpgvector image hosts the optional vector_index schema)\n- **Vector store**: driver-pluggable (pgvector default; Qdrant or\n  Seahorse Cloud optional — hybrid dense + BM25 sparse, RRF fusion)\n- **Event stream** (optional): PG `events` outbox + Redis Streams fanout\n- **Frontend**: React 19, TypeScript, Vite, Tailwind CSS v4, Radix UI\n- **Auth**: JWT + Personal Access Tokens (PATs)\n- **MCP**: Streamable HTTP (backend) + stdio proxy (`akb-mcp` on npm)\n\n## Versioning\n\nAKB follows [SemVer](https:\u002F\u002Fsemver.org\u002F). The product version lives in\n`backend\u002Fpyproject.toml` (`[project].version`) and is mirrored to\n`frontend\u002Fpackage.json` via `scripts\u002Fbump-version.sh \u003Cx.y.z>`. Each\n`deploy\u002Fk8s\u002Fdeploy.sh` run tags the Docker images with both the explicit\nversion (`:${VERSION}`) and `:latest`, so historical builds remain\npullable for rollback.\n\n`packages\u002Fakb-mcp-client` (the `akb-mcp` npm proxy) follows its own npm\nsemver lifecycle and is **not** tied to the product version.\n\n## License\n\n[PolyForm Noncommercial 1.0](.\u002FLICENSE) — free for noncommercial use,\nmodification, and distribution within the license's noncommercial scope.\nAttribution required.\n\n**Trademarks** — \"AKB\", \"Dnotitia\", and \"Seahorse\" are trademarks of\nDnotitia, Inc. The software license does not grant trademark rights.\nForks and derivative works must be distributed under a different name.\nSee [TRADEMARKS.md](.\u002FTRADEMARKS.md).\n\n**Commercial use** — a commercial license is required to:\n\n- Deploy AKB in any for-profit company's internal or production systems.\n- Offer AKB (modified or not) as a hosted service, on-premises product,\n  embedded component, or rebranded distribution to third parties.\n- Bundle AKB into a commercial product or service.\n\nFor commercial licensing or trademark permission requests, contact\n**opensource@dnotitia.com**.\n\n## Security\n\nFound a vulnerability? See [SECURITY.md](.\u002FSECURITY.md) — please report\nprivately, not via public issues.\n\n## Contributing\n\nSee [CONTRIBUTING.md](.\u002FCONTRIBUTING.md).\n","AKB是一个面向AI代理的知识库系统，旨在为组织提供记忆存储。它通过Model Context Protocol (MCP)协议，支持文档、表格和文件的统一管理和访问，并且这些资源通过URI图进行链接。项目采用Python开发，核心功能包括基于混合语义与关键词搜索、结构化数据表、文件管理和版本控制。特别地，AKB利用PostgreSQL结合向量搜索技术实现了高效的数据检索。此工具适用于需要为AI助手或自动化流程提供知识支持的场景，如企业内部的知识管理、代码辅助开发等环境。相比传统的知识管理工具，AKB更加注重于满足机器读写的需求，而非仅限于人类用户的界面操作体验。",2,"2026-06-11 04:01:53","CREATED_QUERY"]