doc-platform
@ingadhoc/docs-platform
Платформа документации Adhoc: один поисковый движок, одно ядро MCP, один шлюз доступа и один защитный механизм от утечек, которые потребляются пинами из репозиториев контента (oba-docs, odumbo-docs, adhoc-docs).
До этого четыре части жили в форках в трёх репозиториях: один и тот же файл с тремя диалектами, и каждый фикс распространялся вручную — или не распространялся. Измерение находится в docs/unificacion/: lib/mcp/indice.mjs имел 41 различие между тремя копиями, и 17 из них были фиксами, которые были в одном репозитории, а в двух других — нет. Самый дорогой случай: защитный механизм от утечек был байт-идентичным в двух репозиториях и отсутствовал в третьем.
ADR 0006 из
knowledge-management— один репозиторий на корпус контента, а платформа как отдельный пакет: контент и движок имеют разные жизненные циклы и разных владельцев.ADR 0007 из
knowledge-management— шлюз и защитный механизм от утечек принадлежат платформе, а не каждому сайту: защита, которую каждый репозиторий реализует заново, — это защита, которой у какого-то репозитория нет.Этап A спецификации
arquitectura-plataforma-docs: этот пакет с двумя версионированными контрактами и drift-check, который делает видимым отставание пина.
Как потребляется
npm i --ignore-scripts github:ingadhoc/doc-platform#v0.1.0Точный пин, всегда по тегу. Никаких ^, никаких main, никаких веток: пин — это то, что предотвращает поломку трёх сайтов одновременно из-за фикса платформы, и это то, что позволяет откат одной строкой. Диапазон намеренно вызывает сбой docs-drift-check — пин, который не пинует, не является пином.
--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: Markdown RAG MCP
Что экспортирует
Импорт | Что это |
| поисковый движок: |
|
|
|
|
| сравнение токенов за постоянное время (использует |
| грамматика |
|
|
|
|
|
|
| эталонный |
bin | защитный механизм от утечек, для |
bin | drift-check, для CI потребителя |
Два контракта
Оба несут schemaVersion, и оба читателя выбрасывают ошибку, если эмитент объявляет более новую версию, чем они умеют читать — или если не объявляет её вообще. Никакой тихой деградации: неправильно отвечающий индекс хуже, чем тот, который не отвечает.
config ↔ платформа:
docs.config.json, со схемой, опубликованной вschema/docs.config.schema.json, и валидатором вlib/config.mjs(собственный, без зависимостей:ajvне попадает в сборку публичного сайта). Дизайн каждого поля с измеренными доказательствами находится вdocs/unificacion/diseno-eje.md; три текущих конфига в переводе — вmapeo-configs.md.индекс ↔ движок: его выдаёт
tools/build.mjsкаждого репозитория, а читаетlib/mcp/indice.mjs. Он описан вdocs/unificacion/contrato-indice.md.
Ось в таблице
Корпус объявляет одну ось как объект: { tipo, default?, valores[] }.
| корпус | параметр в tools |
| подстановочный знак (статьи вне оси) |
| oba-docs |
| выбирает | да ( |
| adhoc-docs |
| структурная неоднозначность (не объявляет | нет |
| odumbo-docs | (не раскрывается) | — | — |
Правило leer() одно и не содержит if по типу оси: оно выбирает только тогда, когда конфиг объявил, кого выбирать. Поведение меняет наличие eje.default, а не тип — и есть тест, который это проверяет, добавляя default корпусу с осью project.
Запуск тестов
npm install && npm test # 227 casosbloques требует репозиторий контента (он по-настоящему запускает его tools/build.mjs на фикстурах инцидентов) и пропускается с причиной, если его нет:
DOCS_REPO=~/repositorios/oba-docs node --test tests/bloques.test.mjsПолоса HTTP-обработчика из mcp.test.mjs (16 случаев) также пропускается с причиной, если в checkout нет mcp-handler/zod, которые являются зависимостями потребителя, а не этого пакета. С обеими установленными mcp даёт 57. Случай без своей capability пропускается явно; он не выполняется в деградированном режиме.
Для jjs — открытые решения
Что этот ансамбль не решает сам. Первые три — из diseno-eje.md §7 и затрагивают контракт; остальные вышли из четырёх анализов и остаются живыми после унификации.
1. Одна ось на корпус: принимается ли потолок?
schemaVersion: 1 допускает одну ось на конфиг, и сегодня этого достаточно для трёх репозиториев. В день, когда корпусу понадобится project × version одновременно, схема этого не выражает, и выход — schemaVersion: 2 с ejes: [...] (множественное число). Рекомендация дизайна: явно принять потолок и позволить реальной потребности переоткрыть его с доказательствами (тот же критерий, что и сигнализация о бампах на Этапе B). Это твоё решение, потому что оно затрагивает major.
2. metadata.types: словарь по корпусу или единый для Adhoc?
Сегодня только у adhoc-docs есть types, и его 6 значений очень похожи на стандарт из knowledge-management (concepto, referencia, procedimiento, troubleshooting, guia, indice). Если словарь принадлежит Adhoc, он не идёт в конфиг каждого репозитория: он идёт в пакет, а конфиг только говорит, требует ли он его. Это решение по управлению контентом, а не по схеме; пока оно не принято, схема оставляет его как список по корпусу (совместимо с обоими выходами).
3. Отказ от защитного механизма от утечек в adhoc-docs: подписываешь?
Схема обязывает объявлять deploy.guardDeFuga, так что тихое опущение больше невозможно. Остаются два выхода, оба защитимы: {"activo": false, "motivo": "…"} (у этого репозитория нет публичной сборки: его шлюз безусловный, а защитный механизм защищает от утечки в публичную сборку), или защитный механизм входит всё равно, как ремень. motivo, который сегодня находится в mapeo-configs.md, буквально гласит "PENDIENTE DE FIRMA (jjs)".
И есть техническая часть, которая не исправляется копированием файла (ВОПРОС 1 из analisis-04-seguridad.md): у adhoc-docs нет блоков :::interno, он не выдаёт site/generated.json с аудиторией и у него нет карты deploy.proyectos. С активным защитным механизмом как есть его сборка падает с самого начала из-за "no existe site/generated.json". Строгий вариант — чтобы он выдавал эти две вещи.
4. Список аудиторий остаётся дублированным, и drift-check пока его не сравнивает
docs.config.json → audiences и middleware.js → AUDIENCIAS должны совпадать, и нет способа избежать дублирования: edge не читает из файловой системы. Это ровно тот тип тихого дрейфа, с которого начался форк. Не хватает случая в CI, который бы их сравнивал (сегодняшний docs-drift-check измеряет пин, а не эту согласованность).
5. Три вещи, которые нужно проверить в репозиториях перед тегированием
DOCS_AUDIENCEво всех трёх окружениях каждого проекта Vercel (Production, Preview и Development) до merge, который принимает пакет. При fail-closed проект без переменной возвращает 503. Это безопасное направление, но не бесплатное.--esperadaв текущихbuildCommand: теперь защитный механизм отклоняет его при работе в Vercel. Если какой-то buildCommand передаёт его сегодня, этот деплой начнёт падать. Не удалось проверить по снимкам.GET MCP возвращает 503, если деплой не объявляет обслуживаемую аудиторию. Это наблюдаемое изменение для потребителя: предварительная проверка Claude Code получает 503 вместо плаката, когда деплой неправильно сконфигурирован.
6. Измеренный долг, который этот пакет не может закрыть
Fail-closed препроцессора выводит и затем завершается с ошибкой. С неправильно написанной директивой (
::: interno),build.mjsзаписываетsite/docs/**с внутренней строкой внутри и затем завершается с кодом 1. Сегодня утечки нет, потому чтоbuildCommandобъединяется через&&: защита находится в операторе, а не в программе. Оно объявлено какtodoвtests/bloques.test.mjs, и это исправляет унификацияbuild.mjs— которая не вошла в этот этап.tests/bloques.test.mjsзаписывает в<repo>/site/потому что в oba и odumbo выходные данные сборки захардкожены. После запуска набора тестов нужно перегенерировать с помощьюnpm run gen.Ограничения лексического подхода guard: числа и строки короче 5 символов никогда не имеют зонда (ключ
4821, аббревиатура), изображения не сканируются, и утечка внутриapplyBlocksне генерирует зонд. Это указано в заголовке guard; я повторяю это здесь, потому что эту часть можно спутать с покрытием.serverInfo.versionпо-прежнему захардкожена как'1.0.0'в обработчике. Она должна браться изpackage.jsonзакреплённого пакета, чтобы клиент MCP мог сообщить, с какой версией платформы он взаимодействовал. Это не изменено: это было бы выдумыванием поведения.Подстановочный знак является свойством
tipoоси, а не корпуса. Корпус с осьюprojectне может иметь поперечный документ (eje: nullостаётся невидимым для любого фильтра). Если когда-нибудь это понадобится, строгий выход — чтобы контракт индекса запрещал это, пока подстановочный знак выключен, чтобы противоречие возникало на этапе сборки, а не в рантайме.В спецификации сказано "vitest" как соглашение о тестах Этапа A, и ни один из трёх репозиториев не использует vitest: реальное соглашение — и соглашение этого пакета — это нативный
node:test. Стоит исправить эту строку, прежде чем кто-то установит vitest, чтобы ей соответствовать.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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.203MIT
- AlicenseNot gradedqualityDmaintenanceProvides semantic search over markdown documentation using RAG, allowing natural language queries and integration with MCP clients.1MIT
- 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"
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ingadhoc/doc-platform'
If you have feedback or need assistance with the MCP directory API, please join our Discord server