Skip to main content
Glama

@ingadhoc/docs-platform

Adhoc 문서 플랫폼: 하나의 검색 엔진, 하나의 MCP 코어, 하나의 액세스 게이트, 하나의 유출 가드. 콘텐츠 저장소(oba-docs, odumbo-docs, adhoc-docs)가 핀으로 고정하여 사용합니다.

이전에는 네 개의 조각이 세 저장소에 포크되어 있었습니다. 같은 파일이 세 가지 방언으로 존재했고, 각 수정 사항은 수동으로 전파되거나 전파되지 않았습니다. 측정은 docs/unificacion/에 있습니다: lib/mcp/indice.mjs는 세 복사본 간에 41개의 차이가 있었고, 17개는 한 저장소에는 있지만 다른 두 저장소에는 없는 수정 사항이었습니다. 가장 비용이 큰 사례: 유출 가드는 두 저장소에서 바이트 단위로 동일했지만 세 번째 저장소에는 존재하지 않았습니다.

  • knowledge-management의 ADR 0006 — 콘텐츠 본문당 하나의 저장소, 플랫폼은 별도 패키지: 콘텐츠와 엔진은 수명 주기와 소유자가 다릅니다.

  • knowledge-management의 ADR 0007 — 게이트와 유출 가드는 각 사이트가 아닌 플랫폼에 속합니다: 각 저장소가 다시 구현하는 보호는 어떤 저장소에는 없는 보호입니다.

  • arquitectura-plataforma-docs 스펙의 A 단계: 이 패키지, 두 개의 버전이 있는 계약, 그리고 핀의 지연을 보이게 만드는 드리프트 검사.

사용 방법

npm i --ignore-scripts github:ingadhoc/doc-platform#v0.1.0

정확한 핀, 항상 태그로. ^도, main도, 브랜치도 없음: 핀은 플랫폼의 수정 사항이 동시에 세 사이트를 깨뜨리는 것을 막고, 한 줄로 롤백을 가능하게 합니다. 범위는 의도적으로 docs-drift-check를 실패하게 만듭니다 — 핀하지 않는 핀은 핀이 아닙니다.

--ignore-scripts 권장. 이 패키지에는 install 스크립트가 없으며 앞으로도 없을 것입니다. 이 플래그는 전체 트리에 적용됩니다. 공개 사이트의 buildCommand에서 실행되기 때문입니다. 같은 이유로 패키지에는 단 하나의 의존성(minisearch, 검색 엔진이 필요로 함)과 devDependencies가 0개입니다: 빌드에서 최소 표면.

소비자가 이미 가지고 있고 이 패키지가 선언하지 않는 것: mcp-handler와 zod는 lib/mcp/mcp-handler.mjs에서 import합니다. 이들은 의도적으로 저장소의 의존성입니다: 저장소가 어떤 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

내보내는 것

Import

설명

@ingadhoc/docs-platform/indice

검색 엔진: 빌드가 생성하는 인덱스에 대한 buscar(), leer(), mapa(). minisearch를 사용하는 유일한 모듈

@ingadhoc/docs-platform/mcp-handler

crearMcp({config, indice, crearIssue}): 도구, 축별 스키마, Bearer 및 전송

@ingadhoc/docs-platform/gate

decidir(request, env, {audiencias}) / crearGate(config): 엣지 미들웨어의 결정

@ingadhoc/docs-platform/auth

상수 시간 토큰 비교 (node:crypto 사용: 함수 쪽에서만)

@ingadhoc/docs-platform/tokens

DOCS_MCP_TOKENS 문법, 한 번만, 엣지와 함수 간 공유

@ingadhoc/docs-platform/feedback

crearFeedback(config): docs-feedback 이슈를 여는 도구

@ingadhoc/docs-platform/config

cargarConfig() / validarConfig(): docs.config.json 검증기

@ingadhoc/docs-platform/guard-fuga

correrGuard(), 빌드에서 바이너리 대신 직접 호출하려는 경우

@ingadhoc/docs-platform/middleware

참조 middleware.js (소비자 루트에 위치)

bin docs-guard-fuga

유출 가드, buildCommand용

bin docs-drift-check

드리프트 검사, 소비자 CI용

두 계약

둘 다 schemaVersion을 가지며, 두 리더 모두 발신자가 자신이 읽을 수 있는 버전보다 더 새로운 버전을 선언하거나 선언하지 않으면 던집니다. 조용히 저하시키지 않습니다: 잘못 응답하는 잘못된 인덱스는 응답하지 않는 것보다 나쁩니다.

  1. config ↔ 플랫폼: docs.config.json, 스키마는 schema/docs.config.schema.json에 게시되고 검증기는 lib/config.mjs에 있습니다 (자체 구현, 의존성 없음: ajv는 공개 사이트 빌드에 들어가지 않음). 각 필드의 설계와 측정된 증거는 docs/unificacion/diseno-eje.md에 있습니다; 현재 세 config의 번역은 mapeo-configs.md에 있습니다.

  2. 인덱스 ↔ 엔진: 각 저장소의 tools/build.mjs가 생성하고 lib/mcp/indice.mjs가 읽습니다. docs/unificacion/contrato-indice.md에 명시되어 있습니다.

축, 표로

코퍼스는 하나의 축을 객체로 선언합니다: { tipo, default?, valores[] }.

eje.tipo

corpus

tools의 param

leer() 값 없음

와일드카드 (축 외부 문서)

version

oba-docs

version

default를 선택 하고 말함 (elegidoPor)

예 (relacion/ 모든 것에 적용)

project

adhoc-docs

project

구조적 모호성 (default 선언 안 함)

아니요

none

odumbo-docs

(노출되지 않음)

—

—

leer()의 규칙은 하나이며 축 유형별 if가 없습니다: config가 누구를 선택할지 선언했을 때만 선택합니다. 동작을 바꾸는 것은 eje.default의 존재이며, 유형이 아닙니다 — 그리고 project 축을 가진 코퍼스에 default를 넣어 이를 증명하는 테스트가 있습니다.

테스트 실행

npm install && npm test        # 227 casos

bloques는 콘텐츠 저장소가 필요하며 (인시던트 픽스처에 대해 실제 tools/build.mjs를 실행) 없으면 이유와 함께 건너뜁니다:

DOCS_REPO=~/repositorios/oba-docs node --test tests/bloques.test.mjs

mcp.test.mjs의 HTTP 핸들러 부분 (16개 케이스)도 체크아웃에 mcp-handler/zod가 없으면 이유와 함께 건너뜁니다. 이들은 소비자 의존성이며 이 패키지의 의존성이 아닙니다. 둘 다 설치되면 mcp는 57개입니다. capability가 없는 케이스는 명시적으로 건너뜁니다; 저하된 상태로 실행되지 않습니다.


jjs를 위한 — 열린 결정 사항

이 어셈블리가 단독으로 해결하지 못하는 것. 처음 세 개는 diseno-eje.md §7에서 나온 것이며 계약을 위태롭게 합니다; 나머지는 네 가지 분석에서 나왔고 통합 후에도 여전히 살아 있습니다.

1. 코퍼스당 단일 축: 한계를 수용할까요?

schemaVersion: 1은 config당 하나의 축을 허용하며, 현재 세 저장소에 충분합니다. 코퍼스가 project × version을 동시에 필요로 하는 날, 스키마는 표현하지 못하고 출력은 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는 요구 여부만 말합니다. 콘텐츠 거버넌스 결정이지 스키마 결정이 아닙니다; 결정될 때까지 스키마는 코퍼스별 목록으로 둡니다 (두 출력 모두 호환).

3. adhoc-docs의 유출 가드 옵트아웃: 서명하시겠습니까?

스키마는 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을 audience와 함께 생성하지 않으며, deploy.proyectos 맵이 없습니다. 가드를 그대로 활성화하면 빌드가 "site/generated.json이 없음"으로 시작부터 실패합니다. 엄격한 방법은 이 두 가지를 생성하는 것입니다.

4. audience 목록은 여전히 중복되어 있고, drift-check는 아직 비교하지 않습니다

docs.config.json → audiences와 middleware.js → AUDIENCIAS는 일치해야 하며, 중복을 피할 방법이 없습니다: 엣지는 파일시스템에서 읽지 않습니다. 포크가 시작된 정확히 그런 조용한 드리프트 유형입니다. CI 케이스가 이들을 비교하는 것이 빠져 있습니다 (현재 docs-drift-check는 핀을 측정하지 그 일관성을 측정하지 않습니다).

5. 태그를 붙이기 전에 저장소에서 확인해야 할 세 가지

  • Vercel 프로젝트의 세 환경 (Production, Preview, Development) 모두에 DOCS_AUDIENCE 패키지를 채택하는 merge 전에. fail-closed로 변수가 없는 프로젝트는 503을 반환합니다. 안전한 방향이지만 공짜는 아닙니다.

  • 현재 buildCommand의 --esperada: 이제 가드는 Vercel에서 실행되는 것을 거부합니다. 어떤 buildCommand가 오늘 이 플래그를 전달하면 해당 배포가 실패하기 시작합니다. 스냅샷에서 확인할 수 없었습니다.

  • MCP GET은 503을 반환 배포가 서빙 가능한 audience를 선언하지 않으면. 소비자에게 관찰 가능한 변경입니다: 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으로 재생성해야 한다.

  • 가드의 어휘적 접근 방식의 한계: 5자 미만의 숫자와 문자열에는 프로브가 없다(키 4821, 약어). 이미지는 스캔되지 않으며, applyBlocks 내부의 누출은 프로브를 생성하지 않는다. 이는 가드의 헤더에 있다. 커버리지와 혼동될 수 있는 부분이므로 여기서 반복한다.

  • serverInfo.version은 여전히 핸들러에서 '1.0.0'으로 하드코딩되어 있다. 이는 고정된 패키지의 package.json에서 가져와야 하며, MCP 클라이언트가 플랫폼의 어떤 버전과 통신했는지 보고할 수 있어야 한다. 변경되지 않았다. 동작을 발명하는 것이기 때문이다.

  • 와일드카드는 말뭉치가 아니라 축의 tipo 속성이다. project 축을 가진 말뭉치는 횡단 문서(eje: null은 모든 필터에 보이지 않음)를 가질 수 없다. 언젠가 필요해지면, 엄격한 출력은 와일드카드가 꺼져 있는 동안 인덱스 계약이 이를 금지하여 모순이 런타임이 아니라 빌드에서 실패하도록 하는 것이다.

  • 스펙은 "vitest"를 말한다. Etapa A의 테스트 관례로, 세 저장소 중 어느 것도 vitest를 사용하지 않는다. 실제 관례 —그리고 이 패키지의 관례—는 네이티브 node:test이다. 누군가 이를 충족시키기 위해 vitest를 설치하기 전에 그 줄을 수정하는 것이 좋다.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides RAG (Retrieval Augmented Generation) access to technical documentation through MCP, enabling LLMs to search and retrieve relevant documentation on-demand.
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables searching, reading, and navigating MkDocs documentation sites through MCP tools for keyword, semantic, or hybrid search, document browsing, and project metadata.
    1
    BSD 2-Clause "Simplified"