doc-platform
@ingadhoc/docs-platform
Adhoc 文档平台:一个搜索引擎,一个 MCP 核心,一个访问网关和一个泄露守卫,由内容仓库(oba-docs、odumbo-docs、adhoc-docs)固定引用。
在此之前,这四个部分分别 fork 在三个仓库中:同一个文件有三种方言,每个修复都手动传播——或者根本没有传播。度量在 docs/unificacion/ 中:lib/mcp/indice.mjs 在三个副本之间有 41 处差异,其中 17 处是一个仓库有而另外两个没有的修复。最昂贵的案例:泄露守卫在两个仓库中字节相同,而在第三个仓库中不存在。
knowledge-management的 ADR 0006 —— 每个内容体一个仓库,平台作为独立包:内容和引擎有不同的生命周期和不同的所有者。knowledge-management的 ADR 0007 —— 网关和泄露守卫属于平台,而不是每个站点:每个仓库重新实现一次的保护,就是某个仓库没有的保护。arquitectura-plataforma-docs规范的 A 阶段:这个包,带有两个版本化契约和使 pin 滞后可见的 drift-check。
如何消费
npm i --ignore-scripts github:ingadhoc/doc-platform#v0.1.0精确 pin,始终通过 tag。 不要 ^,不要 main,不要分支:pin 是防止平台修复同时破坏三个站点的手段,也是允许一行回滚的手段。范围会使 docs-drift-check 故意失败——不固定的 pin 不是 pin。
推荐 --ignore-scripts。 这个包没有任何 install 脚本,也不会有;该标志适用于整个依赖树,因为它在公共站点的 buildCommand 中运行。同样的原因,这个包只有一个依赖(minisearch,搜索引擎需要它)和零 devDependencies:构建中的最小表面。
消费者已经拥有而此包未声明的: mcp-handler 和 zod,由 lib/mcp/mcp-handler.mjs 导入。它们是有意作为仓库的依赖:仓库决定使用哪个版本的 MCP 框架进行部署,包不强制其版本。三个仓库今天都有它们。
在 npm i 之后,消费仓库会得到三行胶水代码:
// api/mcp.mjs
import { crearMcp } from '@ingadhoc/docs-platform/mcp-handler';
import { crearFeedback } from '@ingadhoc/docs-platform/feedback';
import * as indice from '@ingadhoc/docs-platform/indice';
import { config } from '../docs.mcp.config.mjs';
const { handler } = crearMcp({
config,
indice,
crearIssue: crearFeedback(config.feedback),
});
export default handler; // sin default export Vercel no encuentra el handler// middleware.js — en la RAÍZ del repo (Vercel lo exige ahí)
import { next } from '@vercel/functions';
// Por RUTA RELATIVA, no por especificador de paquete: el bundler del edge
// rechaza `@ingadhoc/docs-platform/gate` cuando el repo consumidor no es
// `"type": "module"` (Docusaurus lo impide) — "unsupported modules".
// Y ojo con renombrar a middleware.mjs: el deploy queda VERDE y SIN
// middleware (la ausencia silenciosa del gate). Hallazgo del piloto
// odumbo-docs, deployment 3mXWLwPHPgcwasEji49pGEg7Lyuv.
import { decidir } from './node_modules/@ingadhoc/docs-platform/lib/mcp/gate.mjs';
const AUDIENCIAS = ['publico', 'interno']; // adhoc-docs: ['interno']
export default function middleware(request) {
return decidir(request, process.env, { audiencias: AUDIENCIAS }) ?? next();
}// package.json del consumidor — el guard, dentro del buildCommand
"build:publico": "node tools/build.mjs --audience=publico && npm --prefix site run build && npx docs-guard-fuga --salida=dist/publico"&& 不是装饰性的:它是当守卫以 1 退出时中止部署的东西。不要把它改成 ;。
Related MCP server: docrag
它导出什么
导入 | 它是什么 |
| 搜索引擎: |
|
|
|
|
| 恒定时间令牌比较(使用 |
|
|
|
|
|
|
|
|
| 参考 |
bin | 泄露守卫,用于 |
bin | drift-check,用于消费者的 CI |
两个契约
两者都带有 schemaVersion,并且两个读取器在声明方声明了比它们能读取的更新版本——或者根本没有声明时——会抛出。绝不静默降级:一个错误响应的索引比一个不响应的索引更糟糕。
config ↔ 平台:
docs.config.json,schema 发布在schema/docs.config.schema.json,验证器在lib/config.mjs(自有的,无依赖:ajv不会进入公共站点的构建)。每个字段的设计,带有测量的证据,在docs/unificacion/diseno-eje.md中;三个当前 config 的翻译在mapeo-configs.md中。索引 ↔ 引擎:由每个仓库的
tools/build.mjs生成,由lib/mcp/indice.mjs读取。它在docs/unificacion/contrato-indice.md中规定。
轴,用表格表示
语料库声明一个轴作为对象:{ tipo, default?, valores[] }。
| corpus | tools 中的参数 | 没有值时的 | 通配符(轴外的文章) |
| oba-docs |
| 选择 | 是( |
| adhoc-docs |
| 结构化歧义(不声明 | 否 |
| odumbo-docs | (不暴露) | — | — |
leer() 的规则是一个,没有按轴类型的 if:它只在 config 声明了选择谁时才选择。改变行为的是 eje.default 的存在,而不是类型——并且有一个测试通过给 project 轴的语料库添加 default 来证明这一点。
运行测试
npm install && npm test # 227 casosbloques 需要一个内容仓库(它真实地运行其 tools/build.mjs 在事件 fixtures 上),如果没有则有理由地跳过:
DOCS_REPO=~/repositorios/oba-docs node --test tests/bloques.test.mjsmcp.test.mjs 的 HTTP 处理程序部分(16 个案例)如果 checkout 没有 mcp-handler/zod(它们是消费者的依赖,不是此包的依赖),也会被有理由地跳过。两个都安装后,mcp 给出 57。没有 capability 的案例被显式跳过;不会降级运行。
给 jjs —— 未决决策
这个组装不能单独解决的事情。前三个来自 diseno-eje.md §7 并涉及契约;其余来自四个分析,在统一后仍然存在。
1. 每个语料库一个轴:接受上限吗?
schemaVersion: 1 每个 config 允许一个轴,今天对三个仓库来说足够了。如果某天一个语料库需要 project × version 同时存在,schema 无法表达,输出将是带有 ejes: [...](复数)的 schemaVersion: 2。设计建议: 明确接受上限,让真实需求用证据重新打开它(与 B 阶段 bump 警报相同的标准)。这是你的决定,因为它涉及 major 版本。
2. metadata.types:每个语料库的词汇表还是 Adhoc 统一的?
今天只有 adhoc-docs 有 types,其 6 个值看起来非常像 knowledge-management 的标准(concepto、referencia、procedimiento、troubleshooting、guia、indice)。如果词汇表是 Adhoc 的,它不应该放在每个仓库的 config 中:它应该放在包中,config 只说明是否要求它。这是一个内容治理决策,不是 schema 决策;在裁决之前,schema 将其保留为每个语料库的列表(与两种输出兼容)。
3. adhoc-docs 中泄露守卫的退出选项:你签字吗?
schema 强制声明 deploy.guardDeFuga,所以静默省略不再可能。剩下两个选项,都站得住脚:{"activo": false, "motivo": "…"}(该仓库没有公共构建:其网关是无条件的,守卫保护的是公共构建的泄露),或者守卫照常进入,作为安全带。今天在 mapeo-configs.md 中的 motivo 字面写着 "PENDIENTE DE FIRMA (jjs)"。
还有一个技术部分不能通过复制文件来解决(analisis-04-seguridad.md 中的 DUDA 1):adhoc-docs 没有 :::interno 块,不生成带有受众的 site/generated.json,也没有 deploy.proyectos 映射。如果守卫按原样激活,其构建会因“不存在 site/generated.json”而立即失败。严格的做法是让它生成这两样东西。
4. 受众列表仍然重复,drift-check 还没有比较它
docs.config.json → audiences 和 middleware.js → AUDIENCIAS 必须匹配,并且无法避免重复:边缘不读取文件系统。这正是 fork 开始的那种静默漂移。缺少一个 CI 案例来比较它们(今天的 docs-drift-check 测量 pin,而不是这种一致性)。
5. 在 tag 之前需要在仓库中查看的三件事
每个 Vercel 项目的三个环境中的
DOCS_AUDIENCE(Production、Preview 和 Development)在采用该包的合并之前。使用 fail-closed,没有该变量的项目返回 503。这是安全的方向,但不是免费的。当前
buildCommand中的--esperada:现在守卫在 Vercel 上运行时会拒绝它。如果某个 buildCommand 今天传递了它,该部署将开始失败。无法从快照中验证。MCP 的 GET 返回 503,如果部署没有声明可服务的受众。这是对消费者的可观察变化:当部署配置错误时,Claude Code 的预检会收到 503 而不是提示。
6. 此包无法关闭的已测量债务
预处理器的 fail-closed 会先输出然后失败。 对于拼写错误的指令(
::: interno),build.mjs会将内部行写入site/docs/**,然后以退出码 1 结束。目前没有泄漏是因为buildCommand用&&串联:保护在于操作符,而非程序本身。这在tests/bloques.test.mjs中声明为todo,而build.mjs的统一化可以修复它——但该统一化没有进入本阶段。tests/bloques.test.mjs会写入<repo>/site/,因为在 oba 和 odumbo 中,构建输出是硬编码的。运行测试套件后,需要用npm run gen重新生成。guard 的词法方法的局限:少于 5 个字符的数字和字符串永远不会被探测(如键
4821、缩写),图像不会被扫描,applyBlocks内部的泄漏不会生成探测。这写在 guard 的头部;我在这里重复是因为这部分容易与覆盖率混淆。serverInfo.version在 handler 中仍硬编码为'1.0.0'。它应该来自所固定包的package.json,这样 MCP 客户端就能报告它对话的是哪个平台版本。没有更改:那将是凭空捏造行为。通配符是轴
tipo的属性,而不是语料库的属性。 具有project轴的语料库不能有横向文档(eje: null对任何过滤器都不可见)。如果将来需要,严格的输出是索引契约在通配符关闭时禁止它,以便矛盾在构建时失败,而不是在运行时失败。规范说“vitest” 作为阶段 A 的测试约定,而三个仓库都没有使用 vitest:实际约定——以及本包的约定——是原生的
node:test。在有人为了遵守而安装 vitest 之前,值得修正这一行。
This server cannot be deployed
Maintenance
Related MCP Connectors
Team docs served to AI agents over MCP - search, Markdown reads, version pinning, read audit.
Read-only MCP server for the OrchestKit docs: full-text search + Markdown fetch. No auth.
Political Comms documentation MCP server: search docs, query the docs filesystem. No auth.
Public read-only MCP for products, frameworks, guides, methodology, and blog metadata.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to access and read mdbook documentation, including structure, content, and search.12 npm3MIT
- AlicenseNot gradedqualityDmaintenanceProvides RAG (Retrieval Augmented Generation) access to technical documentation through MCP, enabling LLMs to search and retrieve relevant documentation on-demand.4MIT
- AlicenseNot gradedqualityAmaintenanceEnables searching, reading, and navigating MkDocs documentation sites through MCP tools for keyword, semantic, or hybrid search, document browsing, and project metadata.1BSD 2-Clause "Simplified"
- FlicenseAqualityCmaintenanceEnables MCP clients to retrieve authoritative AI Square documentation, API references, SDK examples, guides, and troubleshooting information through citation-safe hybrid search and static resources.11-