Skip to main content
Glama

KAUT — 信任之下的知识实现

test release license node platforms runtime deps OKF

让遗留代码库具备 AI 原生能力。 KAUT 是为你的项目提供的自我维护、AI 优先的文档——一个知识层,让无文档、弱上下文的代码对 AI 代理变得可读。它不是对话的记忆,而是关于系统本身的知识库:它做什么、如何构建、以及为什么。它将代理在工作中学到的东西转化为活文档——因此没有会话从零开始。

零依赖 Node.js(≥ 20,在 24 上开发),Apache-2.0。在 macOS 和 Linux 上开发和测试(CI 运行 Linux,Node 20 和 24);不支持 Windows。

一个完整、独立的产品。 一次 git clone 就是全部安装;将你的工具指向捆绑的 MCP 服务器(或从任何技能/提示调用 CLI)即可工作——无需编排器、框架、服务、账户,无需部署其他任何东西。它与兄弟 TAUT 编排框架组合(TAUT 驱动代理,KAUT 是它们所知道的内容)——但该集成是可选的,不是依赖。

状态:v0.8.1 — 完整循环已上线。 读取:lookup(一次调用即可获得现成答案),带有新鲜度判定(基于 merge-base,不确定时绝不声称“新鲜”)、信任层级和 altitude 覆盖范围;篡改遏制会扣留任何在管道之外编辑的内容。多仓库:工作区注册表、每个成员存储、一个锚定到启动器仓库的系统存储。写入:分层写入门(代理层更新直接落地;所有者门控层和新文档排队为草稿以供异步审查)。维护:refresh(重新推导增量包)、touched(变更点传感器)、digest/note(使用和结果遥测)。互操作:存储满足 OKF v0.2 一致性标准,kaut okf export 生成惯用的 OKF 包。任何支持 MCP 的工具都可以通过捆绑的 MCP 服务器接入。详细内容见:docs/HANDBOOK.md §16


它解决的问题

每个新的 AI 会话都从失忆开始:代理重新探索你的项目,再次问同样的问题,而且——最糟糕的是——不断犯下最昂贵的错误:代码能编译并通过测试,却悄悄破坏了它无法知道的业务规则。

项目的“为什么”通常无处可写。KAUT 给了它一个生存之地——并让它保持活力。

这在遗留代码上伤害最大:多年未记录的决策,没有原始作者在场,业务规则仅作为副作用可见。这正是当今 AI 编码工具表现不佳的地方——也正是 KAUT 为之构建的代码库。KAUT 是更大目标的第一步:让遗留代码库具备 AI 原生能力——结构化,使代理能够安全且廉价地处理它们。

Related MCP server: 50 First Tapes MCP Server

KAUT 是什么——以及不是什么

它存储什么

它如何保持真实

当代码变化时会发生什么

代理记忆

对话、偏好

它不保持——情景回忆无法验证

什么也不做;昨天的回忆原样提供

RAG / 嵌入

任何现有文本的块

它不保持——检索没有新鲜度或来源契约

过时的块继续排名靠前,以完全自信提供

维基 / 自动生成的文档

某人曾经写过的散文(或 LLM 曾经猜过的)

手动勤奋

它默默腐烂;没有警告读者

KAUT

提炼、精选的事实,每个都绑定到其来源并锚定到提交

新鲜度在每次读取时从 git 计算;门控写入路径让人类负责判断层知识

判定自动翻转为 stale,答案说“重新检查这个”而不是假装

不是另一个记忆系统。 记忆回答*“我们谈了什么,这个用户偏好什么?”——个人的、情景的、无法验证的。KAUT 回答“这个项目如何工作,为什么?”*——文档:按领域组织、绑定来源、检查新鲜度、标记信任,并且任何代理和人类都可读。个人笔记永远不会进入 KAUT;项目知识永远不会被困在单个代理的记忆中。这个边界内置于写入路径中。

不是 RAG。 检索增强生成索引任何恰好存在的文本,并提供最佳匹配的块——不知道它们是否仍然真实。KAUT 存储相反的选择:只有难以重新推导且不易在代码中可见的知识(存储试金石),提炼成模型整体阅读的短文档——没有嵌入、没有排名、没有块汤。而且每个文档都带有机器检查的新鲜度判定:锚定到其推导出的提交,每次读取时与跟踪的主分支进行差异比较,当 git 无法证明其他情况时倾向于陈旧。如果你愿意,可以在代码上运行 RAG——KAUT 用于代码没有说的内容:为什么、横切不变量、部落知识。

不是 LLM 维基。 自动生成的文档是看似合理的文本,出生时未经验证,在第一次提交时就被抛弃。KAUT 文档如果没有类型化源绑定和锚定提交就无法存在——并且不能保持错误而不被发现,因为源在每次读取时都会被差异比较。写入路径是另一半:机械层自动重新生成,代理可以落地他们在会话中验证的操作事实,但判断层知识(决策、领域语义、契约)只能通过人类批准的网关进入——更新排队为草稿,你批量审查。维基默认腐烂;KAUT 的默认是坦白。

而且它不是专有的孤岛。 KAUT 是供应商中立的 Open Knowledge Format (OKF) v0.2 的实现——存储是类型化 Markdown 概念文档,就地满足 OKF 的一致性标准,kaut okf export 将任何存储投影为完全惯用的 OKF v0.2 包(包括来源、信任和生命周期系列),任何 OKF 消费者都可读。KAUT 的新鲜度/信任机制作为 OKF 保护的扩展键叠加在其上:格式记录知识——引擎是保持其真实的东西。规范性映射位于 SCHEMA.md

原则

  1. 源绑定、提交锚定。 每个事实都指明其来源文件和推导时的提交。没有来源就没有文档——契约在门口验证。

  2. 倾向于陈旧。 新鲜度是纯粹的 git 计算(与跟踪的主分支进行 merge-base)。当 git 无法证明文档是最新的时,判定会说明。KAUT 在不确定时绝不声称“新鲜”——错误的“陈旧”代价是重新检查;错误的“新鲜”会发布一个 bug。

  3. 知识提供信息;它从不授权。 健康的判定是跳过重新推导的许可,而不是行动的许可。判定路由信任:健康 + 精确 = 可直接使用;陈旧 / 损坏 / 粗粒度 = 先在代码中确认。

  4. 不提供你无法担保的内容。 存储由 AI 代理读取,因此管道外的编辑是注入通道,而不是便利。任何与上次管道提交不完全相同的字节都会被完全扣留(tampered),直到恢复或合法落地。

  5. 人类拥有判断;代理拥有机制。 分层写入门:映射自由重新生成,经过验证的操作事实在代理层落地,决策/领域/契约知识在草稿队列中等待所有者一键审查。

  6. 在最便宜的地方修复。 新鲜度衰减是结构性对抗,而不是英雄式对抗:变更点(touched 命名代码变更所欠的文档)、读取点(陈旧判定附带 refresh 增量包——确切改变了什么,针对什么重新推导),以及诚实的遥测(digest)以查看维护是否跟上。

  7. 本地优先、零依赖、不触碰仓库。 一次克隆,无需安装步骤,无守护进程,无云;知识存储位于你的仓库之外,新鲜度检查成本是 git 比较——而不是模型调用。

KAUT 做什么

  • 一个已知的查看位置。 代理在重新探索你的代码之前检查 KAUT。要么答案就在那里,要么 KAUT 记录差距以便稍后填补。

  • 知识自我收集。 任务完成后,代理刚刚学到的有用内容被浓缩到基础中——这是已支付工作的副产品,而不是单独的文档项目。

  • 它从不自信地撒谎。 每个存储的事实都保持与其来源代码的关联。当该代码变化时,该事实自动标记为可能过时。有疑问时,KAUT 说“重新检查这个”而不是假装一切都是新鲜的。

  • 它拒绝提供无法担保的内容。 知识库由 AI 代理读取,因此在 KAUT 背后(在其自己的版本控制之外)编辑的文件是潜在的注入通道。此类内容被完全扣留,直到恢复或正确重新提交——代理看到的每个答案都来自来源跟踪的提交。

  • 你仍然是法官。 所有者门控层和新文档未经你的批准永远不会落地:更新排队为草稿kaut draft),你一次坐下即可落地或丢弃整个批次(kaut review)。代理完成时你不必在场。

  • 你的仓库永远不会被触碰。 所有知识都存在于项目外的单独文件夹中。你的 git 历史、分支和队友永远不会看到它。

  • 任何代理都可以接入。 除了 CLI,KAUT 还附带一个 MCP 服务器(node <engine>/mcp.mjs,零依赖)——相同的查找、新鲜度判定和门控写入作为 MCP 工具,适用于任何支持 MCP 的工具或编排器。一个服务器处理整个多仓库工作区(每次调用都指定其仓库)。

架构

flowchart LR
    subgraph clients["Clients"]
        direction TB
        HARNESS["AI agents\nany MCP-capable harness"]
        HUMAN["Humans and CI\nshell, scripts"]
        ORCH["Orchestrator, e.g. TAUT\n(optional)"]
    end

    subgraph engine["KAUT engine - stateless, zero-dep Node, no daemon"]
        direction TB
        SURF["Two surfaces\nmcp.mjs - 7 MCP tools\nkaut.mjs - CLI"]
        READP["READ path (lock-free)\nlookup / stale / digest\nfreshness verdict = pure git computation\n+ trust tier + altitude on every answer"]
        WRITEP["WRITE path (one chokepoint)\nlayered write gate + draft queue\nagent tier lands, judgment tier\nwaits for owner review"]
        MAINTP["Maintenance loop\nrefresh / touched / note\nmap collectors (stack adapters)"]
    end

    subgraph home["Knowledge data home - set once with kaut home"]
        direction TB
        STORES["One store per repo\ntyped markdown + frontmatter\nown private git = audit + rollback\njournal telemetry"]
        REG["workspaces registry\nmember stores + one system store"]
        BACK["backups/\nkaut backup / restore"]
    end

    REPOS["Your repositories\nREAD-ONLY sources\n(at most one git-ignored pointer file)"]
    OKFB["OKF v0.2 bundle\nkaut okf export"]

    HARNESS --> SURF
    HUMAN --> SURF
    ORCH --> SURF
    SURF --> READP
    SURF --> WRITEP
    SURF --> MAINTP
    READP -- "diff sources against\nthe anchor commit" --> REPOS
    MAINTP -- "derive maps from code" --> REPOS
    READP <--> STORES
    WRITEP --> STORES
    STORES --> OKFB

用四句话概括其形态。引擎是无状态的——每条命令(CLI 或 MCP 工具)都根据两条 git 历史计算出答案后即退出;没有任何常驻进程需要运行、同步或可能损坏。知识存放在你的仓库之外,每个仓库在数据主目录中对应一个存储,每个存储本身就是一个独立的私有 git 仓库——这正是写入门禁、防篡改、审计和回滚得以实现的基础。读取路径从不阻塞、从不猜测:判定结果是在你提问的那一刻,将文档的类型化来源与其锚定提交进行 diff 得出的。写入路径只有一个咽喉点,因此策略(代理层级 vs 所有者审核)无法通过选择不同命令来绕过。

快速开始

1. 将引擎克隆到它将要服务的仓库旁边(一个同级文件夹——安装脚本会扫描其邻居;无需 npm install,引擎零依赖):

cd ~/projects && git clone https://github.com/yurgeno/kaut.git

2. 运行安装脚本——三个问题,每个答案都有对应的标志位用于脚本化安装:

node kaut/kaut.mjs setup
  • 知识数据文件夹——存储所在位置(默认:<siblings>/kaut-data)。 持久化一次(kaut home 重定向):之后每条命令和 MCP 服务器都会自行解析它——无需导出,无需传递。此文件夹是实时数据:引擎只会向其中添加内容;不会清除或重写任何已有内容。

  • 哪些仓库——安装脚本会列出每个同级 git 仓库;回答 all、编号或名称。

  • 立即引导?——选择是会在现场为每个选中的仓库创建/更新存储(幂等:已有存储会被更新,绝不会重新播种);选择否则只记录配置并打印供稍后使用的逐仓库命令。

非交互式:node kaut/kaut.mjs setup --data <dir> --repos all --bootstrap --yes--no-bootstrap--scan <dir> 用于扫描其他位置)。

3. 按照打印的后续步骤操作——安装脚本结束时恰好有两步:将 MCP 服务器连接到你的工具框架,并将知识契约粘贴到你的代理指令中(两者均在下方)。可选:为每个仓库生成机械映射:

node kaut/kaut.mjs map

(引导已检测到你的技术栈并播种了正确的收集器——参见下方支持的技术栈;输入缺失的收集器会附带说明自行跳过,而 map.collectors: [] 意味着映射层直接保持为空)。

支持的技术栈

引导、知识循环、新鲜度判定、写入门禁——所有这些都与技术栈无关:任何 git 仓库都可以。只有机械化的 map/ 层与技术栈相关,而引导会自动检测技术栈并相应地播种 map.collectors(已有配置绝不会被改动;每个旋钮都可覆盖):

技术栈

检测依据

映射输出

Vue(含 monorepo)

vue 依赖 / src/router/routes.ts

路由表 + 包导入图

Java / Kotlin + Spring

Gradle/Maven 构建根(顶层或嵌套一层)+ 控制器注解

@RequestMapping 系列路由表 + 模块图

Next.js

next 依赖 / app·pages 目录树

基于文件的路由表(App + Pages 路由器)

Express / Nest / FastAPI / Flask

package.json / requirements / pyproject 中的依赖

词法 METHOD-path 路由表

PHP(Laravel / Symfony)

composer.json

Route::… / #[Route] 路由表

SQL 迁移(Flyway 风格)

V*__*.sql 文件

迁移清单(数量、版本)

docker-compose 全景

docker-compose.yml

服务映射

没有可识别技术栈的仓库会获得空的映射层,其他一切照常工作。词法收集器是诚实的尽力而为扫描,并在生成的文档中如此标注。更多技术栈的适配器刻意设计为小型模块——如果你的技术栈缺失,请参阅 CONTRIBUTING.md

连接你的代理——让一切真正生效的步骤

仅有存储本身不会改变任何东西:你的代理必须知道它的存在以及何时查阅它。 两步操作(完整指南含可直接粘贴的代码块和一个实战会话:docs/AGENT-INTEGRATION.md):

  1. 将 MCP 服务器连接到你的工具框架(Claude Code 用 .mcp.json,Codex 用 config.toml——指南中有代码片段)。七个 kaut_* 工具会出现在每个会话中,它们的描述已经教会模型这套纪律:在重新探索之前先查证,根据判定结果路由信任,通过门禁写回。

  2. 将知识契约粘贴到你的代理每次会话都会加载的内容中(CLAUDE.md / AGENTS.md / 系统提示)——指南中约 15 行的代码块,使行为可靠而非偶发:先读再重新推导;健康 + 精确 = 直接使用,过期/粗略 = 在代码中确认;用 kaut_note 标记结果;编辑文件后运行 kaut_touched 并修复或排队处理变更所欠下的内容。

可选:将契约封装为工具框架技能(指南中有模板),或让编排框架为你编译接线——TAUT 只需一个安装答案即可完成。然后:照常工作。 如果你想自己浏览,node <engine>/kaut.mjs lookup 会打印主题目录。

日常使用——没有

KAUT 被设计为不可见的。你只会在三个时刻注意到它:

  • 在你下令时——告诉代理保存它刚学到的东西("persist this to KAUT"):它会用试金石测试过滤会话中的发现,以正确的来源绑定写入它们,并提交到存储的 git 中。所有者门控的知识仍会停在草稿队列中等待你的审核。

  • 当草稿堆积时——kaut review 列出等待你处理的内容;一次性批准或拒绝整批(doctor 在队列待处理时也会发出警告)。

  • 偶尔代理会问一个只有人类才能回答的问题("这条规则是有意为之,还是意外?")。你的回答会成为知识库中最有价值的一类知识。

其他一切——查证、检查新鲜度、重建映射——都会自动且静默地发生。

命令

在项目 git 仓库内的任何位置运行:

node <engine>/kaut.mjs setup         # guided install: data home, sibling-repo scan, bootstrap (run once, from anywhere)
node <engine>/kaut.mjs bootstrap     # create/repair the project's knowledge store (idempotent)
node <engine>/kaut.mjs index         # regenerate INDEX.md (under lock; auto-commits changes)
node <engine>/kaut.mjs doctor        # integrity checks; exit 0 = healthy
node <engine>/kaut.mjs home [<dir>]  # show or set the knowledge-data home (redirect at ~/.kaut/config.json)
node <engine>/kaut.mjs paths         # print resolved {projectId, root, engine, repo, mainBranch, source}
# reading core:
node <engine>/kaut.mjs lookup [<id>] # one-call ready block; no id = catalog; unknown id = miss (exit 0)
node <engine>/kaut.mjs stale [<id>…] # freshness verdicts for all/selected docs (read-path, no lock)
node <engine>/kaut.mjs map           # regenerate L0 maps per config map.collectors + commit
# maintenance loop:
node <engine>/kaut.mjs refresh [<id>…]        # per-doc re-derivation delta bundles (read-only)
node <engine>/kaut.mjs draft <id>             # queue a finished doc update for async owner review
node <engine>/kaut.mjs review [<id>…]         # owner side: list / diff / --approve / --reject
node <engine>/kaut.mjs touched <file>…        # which docs bind the given changed files
# telemetry:
node <engine>/kaut.mjs note <topic> <result>  # record an in-session outcome (trusted|confirmed|insufficient|stale-misled)
node <engine>/kaut.mjs digest [--since <ISO>] # aggregate journal telemetry across workspace stores
# backup / restore (the whole data home — stores, registry, setup record):
node <engine>/kaut.mjs backup                 # dated, versioned .tar.gz under <data>/backups/
node <engine>/kaut.mjs restore [latest|<file>] [--force]   # no arg = list; never overwrites without --force
# open format (OKF v0.2):
node <engine>/kaut.mjs okf check              # store-as-OKF-bundle conformance report (exit 0 = conformant)
node <engine>/kaut.mjs okf stamp              # backfill `type:` on legacy docs (through the write gate)
node <engine>/kaut.mjs okf export --out <dir> # project committed HEAD into an idiomatic OKF v0.2 bundle
# workspace (multi-repo):
node <engine>/kaut.mjs workspace init --manifest <conductor>/manifest.json
                                     # registry + member stores + ONE system store anchored to the launcher
node <engine>/kaut.mjs workspace list

MCP 服务器:node <engine>/mcp.mjs——一个零依赖的 stdio JSON-RPC 服务器,将会话语义暴露为 MCP 工具(kaut_lookupkaut_notekaut_refreshkaut_touchedkaut_writekaut_draftkaut_status)。每个工具都接受可选的 repo 参数,因此一个服务器即可服务整个多仓库工作区。所有者运行的转义操作(review --approveindex --approve)刻意不通过 MCP 暴露。

标志位:--dry-run(只打印操作而不执行)· --jsonstale|lookup|refresh|review|touched|digest 的机器可读输出)· --quiet · --approve / --reject(所有者运行)· --forcerestore:覆盖已有数据;okf export:写入非空目录)· --out <dir>okf export)· --note <text>notereview --reject)· --manifest <path>workspace init)· --workspace <name>(跨工作区运行 doctor/stale/digest)· --since <ISO-date>digest)· --help/-h(用法说明,退出码 0)。

退出码:0 正常 · 1 验证/doctor 失败 · 2 存储繁忙(锁被持有)· 3 环境缺失(不是 git 仓库 / 存储未引导)。

lookupstale 属于读取路径——它们不获取锁,只向 journal.jsonl 追加一行(使用遥测,未跟踪)。新鲜度判定是数据,而非错误:即使文档已过期,stale 也以 0 退出。判定行最多一条,按优先级 tampered > disputed > broken > stale > branch-advisory;健康文档渲染为干净。

运维深度——磁盘上的存储布局、解析顺序、防篡改和写入门禁的详细说明、卸载、引擎内部机制:docs/OPERATIONS.md

配置

一个文件:存储中的 kaut.config.json(由引导创建,含合理默认值)。大多数人只需接触 map 块(收集器列表和文件位置——参见上方快速开始说明)。引擎实际读取内容的完整参考:docs/HANDBOOK.md §15

它真的有用吗?

KAUT 被构建为对自己诚实:

  • 它为每个存储维护一个使用日志journal.jsonl):每次查证及其判定、每次门控写入、每个记录的结果。kaut digest 将其跨工作区聚合为触达 / 自我维护 / 价值信号数字。

  • 会话记录文档实际表现如何(kaut note <topic> trusted|confirmed|insufficient|stale-misled)——这是基于荣誉系统的价值信号,显示知识在哪里节省了工作、在哪里误导了方向。

  • 基准测试在外部进行(在有无 KAUT 的情况下运行相同任务并比较);引擎刻意不附带基准测试框架。

日志是仅追加的未跟踪遥测,会无界增长;手动截断旧行是安全的(它从来不是知识,digest 只是看到更短的历史)。

备份

数据文件夹就是整个数据库——请如此对待它。kaut backup 将整个数据主目录(每个存储及其 git 历史、工作区注册表、安装记录)打包为 <data>/backups/ 下带日期、带版本号的归档——一个普通的 .tar.gz(手工实现的 ustar + node:zlib,零依赖),任何标准 tar 工具也都能读取。kaut restore latest(或文件名)可将其恢复;没有 --force 绝不会覆盖任何已有内容——被拒绝的恢复会列出冲突且不触碰任何东西。

测试

cd <engine> && node --test          # 213 tests, zero deps (node:test)

运行裸的 node --test——不要将测试目录作为参数传入(在 Node ≥ 24 上,该形式无法解析测试套件)。

卸载

删除存储目录(~/.kaut/<project-id>)和指针文件(<repo>/.kaut.json),并从 <repo>/.git/info/exclude 中移除 .kaut.json 行。你的仓库从一开始就没有被修改过——没有其他需要清理的内容。

常见问题

这只是另一种代理记忆系统吗? 不是。代理记忆记住的是对话和偏好;KAUT 是项目的文档——AI 优先、来源绑定、新鲜度检查。写入路径强制执行这一边界:项目知识进入 KAUT,个人偏好进入代理自身的记忆。

这是 RAG 吗? 不是。没有嵌入、没有分块、没有检索排序。KAUT 存储一小批提炼后的文档,代理整体阅读,每篇都带有来源出处和 git 计算的新鲜度判定——并且刻意只存储那些无法从代码中廉价推导出的内容。对代码库的 RAG 和 KAUT 回答的是不同的问题,可以共存。

这是自动生成的 wiki 吗? 不是。没有任何内容以未经验证的生成式散文进入存储:每篇文档必须携带类型化来源绑定和提交锚点,机械层是重新生成的(而非幻觉生成的),判断层知识要经过人工批准的闸门。与 wiki 不同,KAUT 文档不会无声腐烂——其来源在每次读取时都会被 diff。

存储格式是专有的吗? 不是——恰恰相反。KAUT 实现了供应商中立的 开放知识格式(OKF)v0.2:纯类型化 Markdown 概念文档。任何 OKF 消费者都可以读取存储,而 kaut okf export 会生成完全地道的 OKF 包。无锁定:无论哪种方式,你的知识都是 git 仓库中可移植的 Markdown。

它会把任何内容提交到我的仓库吗? 不会。最多一个被忽略的指针文件。知识库位于仓库之外。

我的团队必须采用它吗? 不会。KAUT 是本地优先的:一个开发者安装它即可受益;其他人不会参与或受到影响。

如果存储的事实有误怎么办? 每个事实都带有其来源和信任标签;代理会对低信任度的事实持怀疑态度,并对照代码进行验证。存储保留完整历史,因此可以追踪并回滚错误条目。

运行成本是多少? 首次构建地图是成本较高的部分(几分钟)。日常维护设计为几乎零成本:新鲜度检查是纯 git 比较——不涉及 AI 调用。

了解更多

许可证与引用

Apache-2.0 — 参见 LICENSENOTICE。如果你使用 KAUT 或基于其实现的概念进行构建,请通过 CITATION.cff 引用它。

联系方式:Yuriy Orlov yuriy.orlov@undertrust.dev

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
6Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Give your AI agent a persistent map of your project's structure, dependencies, and bugs.

  • Shared, permission-aware company context for AI agents, with provenance, approvals and audit.

  • Your company's brain for AI agents. Cited, permission-aware knowledge across every system.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yurgeno/kaut'

If you have feedback or need assistance with the MCP directory API, please join our Discord server