rfcxml-mcp

Servidor MCP para comprensión estructural de documentos RFC.

Documentación

Servidor MCP RFCXML

npm version Docs CI License: MIT Node.js Claude Code

README en japonés · Documentación

Un servidor de Protocolo de Contexto de Modelo (MCP) para la comprensión estructurada de documentos RFC.

Propósito

A diferencia de los servidores MCP de RFC existentes basados en texto, este servidor aprovecha la estructura semántica de RFCXML para permitir:

  • Extracción de requisitos normativos (DEBE/DEBERÍA/PUEDE) con salida estructurada
  • Construcción de grafo de dependencias de RFC
  • Gestión del alcance de definiciones
  • Generación de listas de verificación de implementación

Arquitectura

┌─────────────────────────┐
│  Markdown / PDF         │  Display & Sharing
├─────────────────────────┤
│  Translation            │  Explanation & Verification
├─────────────────────────┤
│  RFCXML MCP             │  Common Understanding for AI & Humans
├─────────────────────────┤
│  RFCXML                 │  Single Source of Truth
└─────────────────────────┘

Comparación con MCP existentes

Característicamcp-rfc existenteRFCXML MCP
Recuperación de texto RFC✅✅
Extracción de secciones✅ (basado en texto)✅ (basado en estructura)
Extracción DEBE/DEBERÍA/PUEDE❌✅
Estructuración de condiciones/excepciones❌✅
Grafo de dependencias de RFC❌✅
Gestión del alcance de definiciones❌✅
Lista de verificación de implementación❌✅

Inicio rápido

Uso con Claude Desktop / Claude Code

Añade lo siguiente a tu archivo de configuración de MCP:

{
  "mcpServers": {
    "rfcxml": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/rfcxml-mcp"]
    }
  }
}

Para fijar una versión (0.6.x publica parches con frecuencia), escribe la versión en la especificación del paquete:

{
  "mcpServers": {
    "rfcxml": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/rfcxml-mcp@0.6.53"]
    }
  }
}

Para mantener los RFC obtenidos en disco entre reinicios, pasa RFCXML_CACHE_DIR (consulta Caché de disco y rfcxml-prefetch):

{
  "mcpServers": {
    "rfcxml": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/rfcxml-mcp@0.6.53"],
      "env": { "RFCXML_CACHE_DIR": "/home/you/.cache/rfcxml-mcp" }
    }
  }
}

Ubicaciones de los archivos de configuración:

  • Claude Desktop (macOS): ~/Library/Application Support/Claude/claude_desktop_config.json
  • Claude Desktop (Windows): %APPDATA%\Claude\claude_desktop_config.json
  • Claude Code (ámbito de proyecto): .mcp.json en la raíz del proyecto
  • Claude Code (ámbito de usuario): ~/.claude.json
  • Claude Code (CLI): claude mcp add rfcxml -- npx -y @shuji-bonji/rfcxml-mcp

Instalación (opcional)

Para instalación global:

npm install -g @shuji-bonji/rfcxml-mcp

Luego configura MCP:

{
  "mcpServers": {
    "rfcxml": {
      "command": "rfcxml-mcp"
    }
  }
}

Herramientas disponibles

Fase 1: Estructura básica

  • get_rfc_structure - Obtener jerarquía de secciones y metadatos
  • get_requirements - Extraer requisitos normativos (DEBE/DEBERÍA/PUEDE) con estructura
  • get_definitions - Obtener definiciones de términos y su alcance

Fase 2: Relaciones

  • get_rfc_dependencies - Obtener RFC referenciados (normativos/informativos)
  • get_related_sections - Obtener secciones relacionadas dentro del mismo RFC

Fase 3: Soporte de verificación

  • validate_statement - Encontrar los requisitos de RFC que afectan a una declaración e informar de contradicciones detectadas. Esto no es un juicio de conformidad: isValid tiene tres valores (null = nada coincidió lo suficientemente fuerte como para juzgar, false = se detectó una contradicción, true = no se detectó contradicción entre las coincidencias). El veredicto es tuyo.
  • generate_checklist - Generar lista de verificación de implementación

Soporte de RFC heredados

Los RFC publicados después del RFC 8650 (diciembre de 2019) están disponibles en formato oficial RFCXML v3. Los RFC anteriores pueden no tener XML disponible.

Este servidor incluye funcionalidad de respaldo automático: cuando el XML no está disponible, analiza el formato de texto en su lugar.

Información de fuente

Todas las respuestas incluyen información de fuente:

{
  "rfc": 6455,
  "sections": [...],
  "_source": "text",
  "_sourceNote": "Warning: Parsed from text format. Accuracy may be limited."
}
_sourceDescripción
xmlAnalizado desde RFCXML (alta precisión)
textAnalizado desde texto (precisión media)

Compatibilidad

RFCFormatoNotas
RFC 8650+XMLSoporte oficial RFCXML v3
Antes de RFC 8650TextoRespaldo automático

Ejemplos de salida

Cada ejemplo a continuación está recortado de la salida real de la compilación actual (npm run build, luego la llamada a la herramienta listada a través de un cliente MCP). Los nombres de campos y valores son textuales; los arreglos largos se cortan con ....

get_rfc_structure - Obtener estructura de RFC

get_rfc_structure { "rfc": 9293 }

{
  "metadata": {
    "title": "Transmission Control Protocol (TCP)",
    "docName": "draft-ietf-tcpm-rfc793bis-28",
    "number": 9293,
    "date": "2022-08",
    "category": "std",
    "stream": "IETF",
    "abstract": "This document specifies the Transmission Control Protocol (TCP). ..."
  },
  "sections": [
    { "number": "1", "title": "Purpose and Scope" },
    { "number": "2", "title": "Introduction" },
    {
      "number": "3",
      "title": "Functional Specification",
      "subsections": [
        { "number": "3.1", "title": "Header Format" },
        {
          "number": "3.5",
          "title": "Establishing a Connection",
          "subsections": [
            { "number": "3.5.1", "title": "Half-Open Connections and Other Anomalies" },
            { "number": "3.5.2", "title": "Reset Generation" },
            { "number": "3.5.3", "title": "Reset Processing" }
          ]
        }
      ]
    }
  ],
  "referenceCount": { "normative": 15, "informative": 85 },
  "_source": "xml"
}

number es el número de sección tal como se imprime en el RFC (3.5, A.2), no el pn de RFCXML (section-3.5). category / stream / abstract provienen de la API de IETF Datatracker y se omiten cuando la API no está disponible o informa un valor fuera del mapeo (por ejemplo, RFC 1 es unkn / legacy); en ese caso _sourceNote lo indica.

get_requirements - Extraer requisitos normativos

get_requirements { "rfc": 9293, "level": "MUST" }

{
  "rfc": 9293,
  "filter": { "section": "all", "level": "MUST" },
  "stats": { "total": 55, "byLevel": { "MUST": 55 } },
  "requirements": [
    {
      "id": "R-3.5-1",
      "level": "MUST",
      "text": "A TCP implementation MUST support simultaneous open attempts (MUST-10).",
      "section": "3.5",
      "sectionTitle": "Establishing a Connection",
      "fullContext": "A TCP implementation MUST support simultaneous open attempts (MUST-10).",
      "subject": "tcp implementation",
      "action": "support simultaneous open attempts (MUST-10)"
    },
    {
      "id": "R-3.7.1-1",
      "level": "MUST",
      "text": "TCP endpoints MUST implement both sending and receiving the MSS Option (MUST-14).",
      "section": "3.7.1",
      "sectionTitle": "Maximum Segment Size Option",
      "fullContext": "TCP endpoints MUST implement both sending and receiving the MSS Option (MUST-14).",
      "subject": "tcp endpoints",
      "action": "implement both sending and receiving the MSS Option (MUST-14)"
    }
  ],
  "_source": "xml"
}

id es R-<section>-<n> con n numerados por sección, por lo que el identificador permanece estable cuando se añaden requisitos en otras partes del documento.

get_rfc_dependencies - Obtener dependencias de RFC

get_rfc_dependencies { "rfc": 9293 }

{
  "rfc": 9293,
  "normative": [
    { "rfcNumber": 791, "title": "Internet Protocol", "anchor": "RFC0791" },
    { "rfcNumber": 1191, "title": "Path MTU discovery", "anchor": "RFC1191" },
    {
      "rfcNumber": 2119,
      "title": "Key words for use in RFCs to Indicate Requirement Levels",
      "anchor": "RFC2119"
    }
  ],
  "informative": [
    { "rfcNumber": 793, "title": "Transmission Control Protocol", "anchor": "RFC0793" },
    { "rfcNumber": 896, "title": "Congestion Control in IP/TCP Internetworks", "anchor": "RFC0896" }
  ],
  "_source": "xml",
  "_referencesSource": "xml"
}

_referencesSource indica de dónde proviene la lista de referencias: xml (RFCXML <references>), text (la sección de Referencias del texto plano), o api (Datatracker relateddocument, con títulos de marcador de posición).

generate_checklist - Generar lista de verificación de implementación

generate_checklist { "rfc": 9293, "role": "client", "sections": ["3.5", "3.7.1"] } — el campo markdown:

# RFC 9293 Implementation Checklist

**Transmission Control Protocol (TCP)**

Role: client

Generated: 2026-09-04T17:09:37.833Z

## Mandatory Requirements (MUST / REQUIRED / SHALL)

- [ ] **MUST** A TCP implementation MUST support simultaneous open attempts (MUST-10). (§3.5)
- [ ] **MUST** TCP endpoints MUST implement both sending and receiving the MSS Option (MUST-14). (§3.7.1)
- [ ] **MUST** If an MSS Option is not received at connection setup, TCP implementations MUST assume a default send MSS of 536 (576 - 40) for IPv4 or 1220 (1280 - 60) for IPv6 (MUST-15). (§3.7.1)

## Recommended Requirements (SHOULD / RECOMMENDED)

- [ ] **SHOULD** TCP implementations SHOULD allow a received RST segment to include data (SHLD-2). (§3.5.3)

La misma llamada también devuelve "stats": { "must": 6, "should": 2, "may": 1, "total": 9 }.

validate_statement - Encontrar requisitos relevantes

validate_statement { "rfc": 6455, "statement": "The client MUST mask all frames sent to the server." }

{
  "rfc": 6455,
  "statement": "The client MUST mask all frames sent to the server.",
  "analysis": { "detectedLevel": "MUST", "detectedSubject": "client" },
  "isValid": true,
  "matchingRequirements": [
    {
      "id": "R-5.3-2",
      "level": "MUST",
      "text": "When preparing a masked frame, the client MUST pick a fresh masking key from the set of allowed 32-bit values.",
      "section": "5.3",
      "sectionTitle": "Client-to-Server Masking",
      "_matchScore": 17,
      "_matchedKeywords": ["client", "mask", "frames"],
      "_subjectMatch": true,
      "_levelMatch": true
    }
  ],
  "conflicts": [],
  "_source": "text",
  "_sourceNote": "Warning: Parsed from text format. Validation accuracy may be limited."
}

isValid: true significa solo que no se detectó contradicción entre los requisitos coincidentes. Cuando nada coincide lo suficientemente fuerte, isValid es null y _verdictNote explica por qué.

Salida de respaldo de texto (RFC heredados)

get_rfc_structure { "rfc": 6455 } — RFC 6455 es anterior a RFCXML v3, por lo que se analiza el texto plano:

{
  "metadata": {
    "title": "The WebSocket Protocol",
    "number": 6455,
    "date": "2011-12",
    "category": "std",
    "stream": "IETF",
    "abstract": "The WebSocket Protocol enables two-way communication ..."
  },
  "sections": [
    { "number": "1", "title": "Introduction" },
    { "number": "2", "title": "Conformance Requirements" },
    { "number": "5", "title": "Data Framing" }
  ],
  "referenceCount": { "normative": 18, "informative": 9 },
  "_source": "text",
  "_sourceNote": "Warning: Parsed from text format. Accuracy may be limited."
}

Para RFC 8650 y posteriores, se intenta primero el XML. Si cada fuente XML devuelve 404, la llamada falla ("No hay ningún RFC publicado con ese número"). Si la obtención de XML falla por otra razón (5xx, tiempo de espera), se usa el texto y _sourceNote indica que la obtención de XML falló y puede ser temporal.

Caché de disco y rfcxml-prefetch

Por defecto, los RFC obtenidos viven solo en una caché LRU en memoria y se vuelven a obtener después de cada reinicio. Establece RFCXML_CACHE_DIR para mantenerlos en disco:

$RFCXML_CACHE_DIR/
├── xml/rfc9293.xml     # RFCXML (RFC 8650 and later)
└── text/rfc6455.txt    # plain text (older RFCs, or XML fetch failures)

El paquete también incluye una CLI rfcxml-prefetch que llena el mismo diseño con anticipación, para uso sin conexión o en CI:

# Fetch a range into $RFCXML_CACHE_DIR (or ~/.cache/rfcxml-mcp when unset)
npx -y -p @shuji-bonji/rfcxml-mcp rfcxml-prefetch --range 9110-9114

# Individual RFCs, explicit directory, re-download even if cached
npx -y -p @shuji-bonji/rfcxml-mcp rfcxml-prefetch --rfc 6455 --rfc 9293 --cache-dir ./rfc-cache --force

Opciones: --range A-B, --rfc N (repetible), --cache-dir DIR, --concurrency N (predeterminado 3), --force. Los RFC ya en disco (XML o texto) se omiten a menos que se proporcione --force. Los números de RFC deben ser solo dígitos; --rfc 9110abc sale con código 1.

Ejemplos

Consulta el directorio examples/ para ejemplos completos de listas de verificación:

RFCProtocoloFuente
RFC 6455WebSocketTexto (respaldo)
RFC 9293TCPRFCXML
RFC 7540HTTP/2Texto (respaldo)

Ejemplo de prompt para Claude:

Generate an implementation checklist for RFC 9293 (TCP).

Arquitectura interna

Estructura de módulos

src/
├── index.ts                    # MCP server entry point
├── config.ts                   # Centralized configuration
├── constants.ts                # BCP 14 keyword definitions + RFC number limits
├── services/
│   ├── rfc-fetcher.ts          # RFC fetching (parallel)
│   ├── rfc-service.ts          # RFC parse & cache management
│   ├── rfcxml-parser.ts        # RFCXML parser
│   ├── rfc-text-parser.ts      # Text fallback parser
│   └── checklist-generator.ts  # Checklist generation service
├── tools/
│   ├── definitions.ts          # MCP tool definitions
│   └── handlers.ts             # Tool handlers (toolHandlers map)
├── types/
│   └── index.ts                # Type definitions
└── utils/
    ├── cache.ts                # LRU cache
    ├── fetch.ts                # Parallel fetch utility
    ├── logger.ts               # Logger abstraction
    ├── requirement-extractor.ts # Shared requirement extraction
    ├── section.ts              # Section search utilities
    ├── statement-matcher.ts    # Weighted statement matching
    ├── text.ts                 # Text processing utility
    └── validation.ts           # Input validation

Optimización de obtención de RFC

Envía solicitudes paralelas a las dos fuentes XML (RFC Editor, Datatracker) y usa la primera respuesta exitosa. tools.ietf.org se retiró en 2021 y no se usa. No hay reintentos; la carrera paralela es la única redundancia.

┌─────────────────┐
│  fetchRFCXML()  │
└────────┬────────┘
         │ Parallel requests
    ┌────┴─────────┐
    ▼              ▼
┌────────┐    ┌────────┐
│RFC     │    │Data-   │
│Editor  │    │tracker │
└────┬───┘    └────┬───┘
     │             │
     └──────┬──────┘
            │ Promise.any (first success)
            ▼
    ┌───────────┐
    │ Successful│ → Cancel other requests via AbortController
    │ Response  │
    └───────────┘

Las llamadas concurrentes para el mismo RFC (por ejemplo, get_rfc_structure y get_requirements emitidas en paralelo) comparten una sola obtención en curso y un solo análisis.

Estrategia de caché

Caché LRU (Menos Recientemente Usado) con límites de memoria, más la caché de disco opcional (RFCXML_CACHE_DIR) debajo de las cachés XML / texto:

CachéEntradas máximasContenido
Caché XML20RFCXML sin procesar
Caché de texto20Texto sin procesar
Caché de metadatos100Metadatos de RFC
Caché de análisis50Estructura analizada

Desarrollo

# Install dependencies
npm install

# Development mode
npm run dev

# Build
npm run build

# Unit tests (single run) / watch mode
npm test
npm run test:watch

# E2E test (MCP client integration; fetches a few real RFCs)
npm run test:e2e

# Audit against real RFCs, tool-to-tool crosscheck, output snapshots
# (see tests/audit/README.md; run weekly by .github/workflows/audit.yml)
npm run audit
npm run crosscheck
npm run snapshot

# Lint
npm run lint

# Format
npm run format

Licencia

MIT

Proyectos relacionados