Ciltress/sap-abap-mcp

SAP ABAP MCP - ADT y JSON RPC

Documentación

Estado: experimental. Úsese con precaución en sistemas productivos.

Servidor MCP ABAP ADT

Un servidor MCP que da a un agente de IA acceso completo de lectura/escritura a un sistema SAP ABAP a través de ADT (ABAP Development Tools), autenticado con inicio de sesión único SPNEGO/Kerberos, un certificado de cliente X.509 o un token portador OAuth 2.0 — sin contraseña en ningún lugar de la configuración. Usuario y contraseña siguen disponibles como respaldo, ¡pero no se recomienda!

Envuelve abap-adt-api y añade una cosa que ADT por sí mismo no puede hacer: llamar módulos de función habilitados para RFC, a través del servicio JSON-RPC 2.0 de SAP Gateway.

128 herramientas — CRUD de objetos, edición de código fuente, bloqueos, transportes, activación, comprobaciones de sintaxis, autocompletado de código, ABAP Unit, ATC, DDIC, abapGit, refactorización, trazas, el depurador y llamadas RFC.

Cuántas ve realmente un cliente es menor, por partida doble. Los perfiles (ABAP_MCP_PROFILE) intercambian superficie por contexto: core lista 9 herramientas mientras que all lista 129, lo que supone ~2.700 tokens frente a ~17.800 en cada turno para un cliente que no puede obtener esquemas de herramientas bajo demanda. Y el servidor pregunta al sistema qué soporta antes de listar nada, de modo que una versión sin el plugin de abapGit nunca recibe las 10 herramientas que responderían 400. En DEV eso deja 116.

Este es el fork SSO de mcp-abap-abap-adt-api de mario-andreschak. Las principales diferencias: SSO Kerberos en lugar de Basic Auth, las herramientas JSON-RPC/RFC, un router derivado de las definiciones de herramientas y una referencia de herramientas documentada.


Documentación

DocumentoQué cubre
AGENTS.mdTrabajar en este repositorio: estructura, convenciones, cómo probar. Léelo antes de cambiar código.
docs/Tool-Router.mdLo que quieres hacer → la herramienta que lo hace. Escrito a mano, con las palabras que usa la gente. Empieza aquí si conoces la tarea pero no la herramienta.
docs/Tool-Reference.mdLas 128 herramientas con sus argumentos, agrupadas por familia. Generado a partir de las definiciones de herramientas, por lo que no puede desviarse del código.
docs/MCP-Tools.mdCómo se comporta el servidor. Los perfiles, flujos de trabajo de ruta dorada, semántica de URI y bloqueos de ADT, el modelo de respuesta/error y una matriz de resolución de problemas. Escrito para humanos y para agentes que manejan el servidor.
docs/ABAP-Skills.mdLas 20 habilidades SAP/ABAP y cómo se asignan a estas herramientas.
docs/Development-Skills.mdLas 35 habilidades generales de ingeniería incluidas.
docs/JSON-RPC.mdNotas de diseño y protocolo para las herramientas JSON-RPC / RFC, leídas del código fuente ABAP de /IWBEP/CL_JSRPC_*: el protocolo de red, la garantía LUW detrás de los lotes y las trampas.
docs/Authentication.mdLos dos modos de inicio de sesión sin contraseña: SSO Kerberos y certificados X.509 para usuarios de servicio y técnicos. Qué necesita SAP configurado y por qué esto es TLS mutuo en lugar de SNC.

Características

  • Dos modos de inicio de sesión sin contraseña — SPNEGO/Kerberos con el ticket del usuario de Windows con sesión iniciada, o un certificado de cliente X.509 para un usuario de servicio o técnico que no tiene identidad Kerberos. No se almacena ni envía ninguna contraseña SAP en ninguno de los dos casos, y ambos se auto-reparan cuando la sesión expira.
  • Leer cualquier objeto por nombrereadAbapObject resuelve un nombre a su código fuente en una sola llamada; sin URL ADT que descubrir o construir a mano.
  • Describir una tabladescribeAbapTable devuelve campos, tipos DDIC, indicadores de clave y tablas de verificación.
  • Gestión de objetos — buscar, leer, crear, modificar, eliminar y activar objetos ABAP.
  • Examinar una convención de nombressearchPackages encuentra paquetes por patrón (["ZPP_*","Z_PP*"]) y expande cada uno en sus objetos agrupados por tipo, en una sola llamada.
  • Flujo de trabajo de código fuente — bloquear → editar → comprobar sintaxis → activar → desbloquear, con gestión de transportes.
  • Inteligencia de código — autocompletado, definiciones, referencias de uso, ABAP Doc, pretty printer, ATC, ABAP Unit, refactorización (renombrar, extraer método).
  • Llamar módulos de función RFCcallFunctionViaJsonRpc ejecuta un módulo de función habilitado para RFC y valida la solicitud contra su firma real, leída del sistema.
  • Llamadas RFC por lotes en una sola LUWcallFunctionsViaJsonRpc envía varios módulos de función en una sola solicitud, que es lo que permite que un BAPI de actualización y su BAPI_TRANSACTION_COMMIT compartan una LUW.
  • Acceso a datostableContents y SELECTs runQuery ad-hoc.
  • Ver el sistema en ejecuciónlistLoggedOnUsers responde "quién está conectado" desde TH_USER_LIST, los datos detrás de SM04; readProfileParameters lee valores RZ11 en un solo viaje de ida y vuelta; y checkLogonConfiguration indica qué autenticación acepta realmente el sistema.
  • Habilidades de agente incluidas — 54 habilidades en skills/, para ABAP (Clean ABAP, RAP, CDS, ATC, abapGit…) e ingeniería general (TDD, revisión de código, diagnóstico de errores), servidas como recursos y a través de readSkill.
  • Autodocumentado — las guías siguientes las sirve el propio servidor, como recursos MCP (abap-adt://guides/…) y a través de la herramienta readServerGuide, de modo que un agente puede consultar un flujo de trabajo o un argumento a mitad de tarea sin salir de la sesión.

Requisitos previos

  • Un sistema SAP ABAP accesible a través de ADT. /sap/bc/adt debe estar activo en SICF. Para las herramientas RFC, /sap/gw/jsonrpc también debe estar activo (SAP_GWFND), y tu usuario necesita S_RFC para los grupos de funciones que llames.
  • Una forma de iniciar sesión sin contraseña, una de:
    • Un inicio de sesión Kerberos funcional — el sistema SAP debe aceptar SPNEGO y debes tener un ticket válido (klist). Este es el predeterminado y necesita Windows tal como se distribuye: el bootstrap invoca a C:\Windows\System32\curl.exe --negotiate, que necesita el backend Schannel/SSPI de curl. En otras plataformas apunta SSO_CURL_PATH a un curl compilado con soporte GSS-API.
      • Un certificado de cliente X.509 — para un usuario de servicio o técnico que no tiene identidad Kerberos. No necesita ni curl ni Windows. SAP debe estar configurado para ello: el puerto ICM debe solicitar un certificado (VCLIENT en icm/server_port_<n>, que anula icm/HTTPS/verify_client), la CA emisora debe ser de confianza en STRUST, y un mapeo CERTRULE al usuario. Configuración completa — incluido cómo comprobar todo eso desde este servidor — en docs/Authentication.md.
      • Un cliente OAuth 2.0 — para un entorno ABAP de SAP BTP, donde no hay dominio Kerberos ni ICM que configurar, o para un sistema on-premise que publica ADT a través de SOAUTH2. Una clave de servicio BTP ya es una de estas. Ver §11.
  • Node.js (LTS) y npm — verifica con node -v y npm -v.

Instalación

git clone --recurse-submodules https://github.com/Ciltress/sap-abap-mcp.git
cd sap-abap-mcp
npm install
npm run build

--recurse-submodules importa: las habilidades generales de ingeniería viven en un submódulo, y sin él ese directorio está vacío y el servidor ofrece 35 habilidades menos. ¿Ya clonado? Ejecuta git submodule update --init --recursive.

El paquete npx mcp-abap-abap-adt-api en npm es el servidor upstream y no incluye el bootstrap SSO ni las herramientas RFC. Compila este repositorio desde el código fuente en su lugar.

Configurar

Copia .env.example a .env y completa tu sistema:

SAP_URL=https://your-sap-server.example.com:44301
SAP_USER=YOUR_SAP_USER
SAP_CLIENT=100
SAP_LANGUAGE=EN

SAP_URL y SAP_USER son obligatorios; SAP_CLIENT y SAP_LANGUAGE son opcionales pero recomendados. Tres de los cuatro modos de inicio de sesión no necesitan ningún SAP_PASSWORD en absoluto.

Nunca hagas commit de .env; ya está en .gitignore.

Variable opcionalEfecto
SAP_SYSTEM_IDEl id del sistema, como en sy-sysid (p. ej. DEV). Se anuncia en el momento de la conexión para que un cliente pueda elegir entre varios servidores por nombre. Ver Más de un sistema.
NODE_TLS_REJECT_UNAUTHORIZED=0Aceptar un certificado de una CA interna/desconocida. Solo desarrollo.
SSO_CURL_PATHRuta a un binario de curl con soporte SPNEGO, si no es el del sistema Windows.
SAP_JSONRPC_PATHAnular la ruta ICF JSON-RPC cuando el nodo se publica bajo un alias.
ABAP_MCP_PROFILEQué herramientas lista este servidor — y por tanto cuáles responderá. Ver más abajo.
ABAP_MCP_MAX_RESPONSE_BYTESTope para una sola respuesta, en bytes. 0 lo elimina.
ABAP_MCP_GATEoff omite la comprobación de capacidades al inicio que retiene herramientas que esta versión no puede servir.
ABAP_MCP_RFC_FALLBACKIniciar incluso cuando SAP deniega a este usuario el nodo ADT, conservando las herramientas RFC. Ver docs/Authentication.md.
SAP_FALLBACK_BOOTSTRAP_PATHA qué nodo ICF inicia sesión ese respaldo. Solo necesita emitir una cookie de sesión y un token CSRF.

Dimensionar el servidor para su cliente

Las tres variables ABAP_MCP_* existen por una razón: un cliente que no puede obtener esquemas de herramientas bajo demanda paga por la lista completa de herramientas en cada turno. Claude Code difiere los esquemas y debería quedarse en el valor predeterminado; un modelo 8B con una ventana de 128k gasta una sexta parte de su contexto antes de que empiece la conversación, y de ahí viene "el mismo prompt funciona la mitad de las veces".

ABAP_MCP_PROFILE — sin definir significa all, de modo que una configuración existente no cambia.

perfiltools/listcoste por turnopara
core9~2.737 tokensleer un sistema y completar una edición
analyst18~3.982 tokenssolo lectura: diccionario, datos de tabla, llamadas RFC
rfc10~2.900 tokensun usuario con derechos RFC pero sin S_DEVELOP, donde las herramientas ADT no pueden funcionar
dev49~8.034 tokensel ciclo de edición más pruebas, ATC, transportes, refactorización
all129~17.759 tokensel predeterminado; adecuado para clientes que obtienen esquemas bajo demanda

Los recuentos incluyen healthcheck, que está fuera de todos los perfiles porque es la herramienta que responde "¿qué perfil estoy ejecutando?".

Un perfil no es un filtro de conveniencia. Una herramienta fuera del perfil activo no se lista ni se enruta, por lo que no se puede llamar — que es lo que convierte a analyst en una garantía de que nada edita código fuente en lugar de un menú más pequeño. Las llamadas fuera de perfil reciben un error que lo dice, en lugar de "herramienta desconocida", así que no tiene sentido reintentar. Un nombre de perfil no reconocido detiene el servidor al inicio en lugar de recurrir a all — servir silenciosamente 129 herramientas a algo que pidió 9 es exactamente el fallo que los perfiles existen para prevenir.

core es pequeño porque una herramienta, editAbapSource, es el ciclo de escritura: bloquear, escribir, activar, desbloquear, liberando el bloqueo incluso cuando un paso falla. Los cuatro pasos separados permanecen en dev y all.

ABAP_MCP_MAX_RESPONSE_BYTES — la lista de herramientas es un coste fijo que un perfil puede reducir; una respuesta no tiene límite. En core toda la lista de herramientas es ~11KB mientras que un adtDiscovery es ~42KB. Sin definir sigue el perfil (core 24.000 bytes, analyst 32.000, dev 48.000, all sin tope); 0 lo elimina.

Una respuesta que supera el presupuesto se retiene y se sustituye por JSON válidostatus:"truncated", el bytes original, el budget, un preview de 2.000 bytes y un nextStep — nunca por un fragmento cortado, que no se analizaría y solo invitaría al reintento idéntico.

ABAP_MCP_GATE — antes de listar nada, el servidor pregunta al sistema qué soporta y retiene las herramientas cuyas colecciones ADT están ausentes. En DEV son las 10 herramientas de abapGit y las 3 herramientas de enlace de servicios, que de otro modo responderían HTTP 400. Cuesta un viaje de ida y vuelta de descubrimiento por proceso, solo puede acortar la lista, y cualquier fallo deja todas las herramientas listadas. ABAP_MCP_GATE=off lo omite.

healthcheck informa de los tres: el perfil activo, responseBudgetBytes y cualquier cosa retenida.

Un certificado en lugar de Kerberos

Para un usuario de servicio o técnico, añade un certificado — eso solo cambia el modo:

SAP_USER=CLAUDEAGENT                                 # the user CERTRULE maps the certificate to
SAP_CERT_FILE=C:\Users\svc_agent\SNC\sec\claudeagent.p12
SAP_CERT_PASSPHRASE=<PKCS#12 password / PSE PIN>
Variable opcionalEfecto
SAP_AUTH_MODEkerberos, certificate, oauth o password. Solo se necesita para forzar un modo mientras otro está configurado.
SAP_CERT_KEY_FILELa clave privada, cuando no está en SAP_CERT_FILE.
SAP_CA_FILEPaquete de CA para verificar el certificado propio de SAP, en lugar de deshabilitar la verificación TLS.

Esto es TLS mutuo, no SNC — ADT es HTTPS. Un certificado que ya funciona para RFC/SNC se puede reutilizar y su mapeo CERTRULE se transfiere, pero la ACL SNC0 no juega ningún papel y el ICM necesita icm/HTTPS/verify_client. docs/Authentication.md cubre las diferencias, la trampa de sapgenpse export_p12 / OpenSSL 3, y cómo leer un certificado rechazado.

Un cliente OAuth 2.0, para BTP y para SOAUTH2

Para un entorno ABAP de SAP BTP, o un sistema local que publica ADT detrás de un servidor de autorización. Configurar el id de cliente cambia el modo:

SAP_OAUTH_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token
SAP_OAUTH_CLIENT_ID=sb-abap-agent!t1234              # 'clientid' in a BTP service key
SAP_OAUTH_CLIENT_SECRET=<'clientsecret'>

En local, el endpoint está en el propio host de SAP — https://<host>:<port>/sap/bc/sec/oauth2/token — y el cliente es el registrado en SOAUTH2.

Variable opcionalEfecto
SAP_OAUTH_GRANTclient_credentials (predeterminado), refresh_token, password o static.
SAP_OAUTH_SCOPEÁmbitos a solicitar. Sin configurar, pide los valores predeterminados del cliente, lo que suele ser correcto.
SAP_OAUTH_REFRESH_TOKENPara la concesión refresh_token; la selecciona por sí mismo.
SAP_OAUTH_TOKENUn token emitido en otro lugar, usado tal cual. Nada puede renovarlo.
SAP_OAUTH_CLIENT_AUTHbasic (predeterminado) o post, cuando un servidor rechaza un secreto que es correcto.

El token inicia sesión una vez. Después, la cookie de sesión de SAP lleva cada solicitud, como en los otros modos — así que un token que expira en cinco minutos no es un problema. Ten en cuenta que un cliente OAuth 2.0 en AS ABAP es un usuario en SU01: un SAP_OAUTH_CLIENT_SECRET incorrecto cuenta contra login/fails_to_user_lock como una contraseña, por lo que una solicitud de token rechazada nunca se reintenta. El flujo de código de autorización no está implementado — necesita un navegador, que un servidor iniciado sobre stdio no tiene forma de abrir; complétalo una vez a mano y pasa el token de actualización. docs/Authentication.md §11 tiene el detalle, incluyendo qué fallos se bloquean y por qué.

Una contraseña, cuando no hay nada más

Para un sistema sin Kerberos ni certificados — un sandbox, una prueba, cualquier cosa fuera del dominio:

SAP_USER=CLAUDEAGENT
SAP_PASSWORD=<the password>

El último recurso, y no intercambiable con los otros dos. Un ticket faltante o un certificado no mapeado simplemente se rechaza; una contraseña incorrecta cuenta contra login/fails_to_user_lock y bloquea a ese usuario para todos los consumidores, no solo para este servidor. La implementación se niega a reintentar una contraseña rechazada por esa razón — un inicio de sesión fallido, bloqueado, sin importar cuántas herramientas se llamen. Prefiere un certificado para cualquier cosa desatendida. docs/Authentication.md §10 tiene el detalle.

Apunta el cliente al punto de entrada compilado con rutas absolutas:

{
  "mcpServers": {
    "sap-abap-dev-100": {
      "command": "node",
      "args": ["C:/path/to/sap-abap-mcp/dist/index.js"],
      "env": {
        "SAP_URL": "https://your-sap-server.example.com:44301",
        "SAP_USER": "YOUR_SAP_USER",
        "SAP_SYSTEM_ID": "DEV",
        "SAP_CLIENT": "100",
        "SAP_LANGUAGE": "EN"
      }
    }
  }
}

El bloque env del cliente gana sobre .env. Ejecuta npm run start para lanzar el servidor manualmente, o npm run dev para manejarlo a través del MCP Inspector.

Para un cliente que lleva el esquema de cada herramienta en cada turno, añade un perfil a ese mismo bloque:

"env": { "…": "…", "ABAP_MCP_PROFILE": "core" }

En Docker

El servidor habla MCP sobre stdio, así que no hay puerto que publicar — el cliente inicia el contenedor y se comunica con él a través de stdin/stdout.

docker build -t abap-adt-mcp .
{
  "mcpServers": {
    "sap-abap-dev-100": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "--env-file", "C:/path/to/.env", "abap-adt-mcp"]
    }
  }
}

Los cuatro modos de inicio de sesión funcionan aquí, pero una credencial es algo que el contenedor debe recibir, y --env-file no es dotenv — Docker no elimina comillas, no lee export, y no elimina # comment finales, así que un valor que dotenv habría limpiado llega tal cual. Las rutas de Windows en .env deben reemplazarse por las montadas. Kerberos es el modo que más necesita del contenedor y OAuth el que menos: un token se obtiene a través de la red, así que no hay que montar nada.

Modo certificado — monta el material de clave de solo lectura, y la CA que firma el certificado de SAP con él:

docker run -i --rm --env-file .env \
  -v /host/certs:/certs:ro \
  -e SAP_CERT_FILE=/certs/agent.p12 \
  -e SAP_CA_FILE=/certs/corporate-root.pem \
  abap-adt-mcp

Modo Kerberos — la imagen incluye un curl compilado contra GSS-API y kinit, así que lo que queda es un dominio y una credencial:

docker run -i --rm --env-file .env \
  -v /etc/krb5.conf:/etc/krb5.conf:ro \
  -v /host/agent.keytab:/krb5/agent.keytab:ro \
  -e SAP_KRB_KEYTAB=/krb5/agent.keytab \
  -e SAP_KRB_PRINCIPAL=SVC_AGENT@CORP.EXAMPLE.COM \
  abap-adt-mcp

Modo OAuth 2.0 — nada que montar; la credencial se obtiene:

docker run -i --rm --env-file .env \
  -e SAP_OAUTH_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token \
  -e SAP_OAUTH_CLIENT_ID='sb-abap-agent!t1234' \
  -e SAP_OAUTH_CLIENT_SECRET=<clientsecret> \
  abap-adt-mcp

Modo contraseña — ¡Último recurso!

docker run -i --rm --env-file .env \
  -e SAP_USER=YourUser \
  -e SAP_PASSWORD=YourPassword \ 
  abap-adt-mcp

Tres cosas que saber antes de recurrir a él:

  • Un keytab, no tu propio ticket. Un contenedor no puede tomar prestada la credencial de la sesión como lo hace un inicio de sesión interactivo. En un host Linux puedes montar la caché de tickets que ya tienes (-v /tmp/krb5cc_1000:/krb5/ccache:ro -e KRB5CCNAME=FILE:/krb5/ccache), pero expira con la del host. Desde un host Windows tampoco funciona: el TGT vive en la caché de LSA y no se puede escribir en un archivo — usa el modo certificado, que no necesita nada de esto. El keytab es la única credencial que funciona desatendida, y la única que sobrevive a la vida del ticket.
  • Verifica el certificado de SAP, o sabe que no lo estás haciendo. La imagen confía solo en el paquete de CA público, así que una CA interna que el host confía es desconocida aquí y el handshake falla con UNABLE_TO_GET_ISSUER_CERT_LOCALLY. Monta la CA raíz y apunta SAP_CA_FILE a ella. Llevar un .env de escritorio al por mayor oculta esto en su lugar: NODE_TLS_REJECT_UNAUTHORIZED=0 es un ajuste de desarrollo y no tiene cabida en una imagen desplegada.
  • Compila desde un clon --recurse-submodules. skills/Development es un submódulo; sin él, la imagen incluye 35 habilidades menos.

La imagen es Debian en lugar de Alpine por una razón: el curl de Alpine está compilado sin GSS-API, y ese curl no falla — simplemente nunca envía un token, y SAP responde el mismo 401 que produce un ticket caducado. Lo que falta se nombra al inicio, en stderr, antes de intentar una sesión. Para preguntar al contenedor con qué credencial terminó, dale un comando en lugar del servidor:

docker run --rm --env-file .env -v /host/agent.keytab:/krb5/agent.keytab:ro \
  -e SAP_KRB_KEYTAB=/krb5/agent.keytab abap-adt-mcp klist

docs/, skills/ y AGENTS.md se copian en la imagen a propósito — el servidor los lee en tiempo de ejecución para servir los recursos readServerGuide, readSkill y abap-adt://. docs/Authentication.md §7 tiene la configuración completa del contenedor, modo por modo.

Más de un sistema

Un servidor está vinculado a un sistema y un cliente durante toda su vida — ninguno se puede cambiar en tiempo de ejecución. Así que registra una entrada por sistema/cliente y dale a cada uno su SAP_SYSTEM_ID:

"sap-abap-dev-100": { "env": { "SAP_SYSTEM_ID": "DEV", "SAP_CLIENT": "100", "…": "…" } },
"sap-abap-dev-200": { "env": { "SAP_SYSTEM_ID": "DEV", "SAP_CLIENT": "200", "…": "…" } },
"sap-abap-q01-100": { "env": { "SAP_SYSTEM_ID": "Q01", "SAP_CLIENT": "100", "…": "…" } }

Cada servidor se anuncia entonces en el instructions de MCP que devuelve al conectarse:

Este servidor está vinculado al sistema SAP DEV, cliente 100 (https://…:44301). No puede cambiar de sistema o cliente en tiempo de ejecución — ambos están fijados por el entorno con el que se inició. Si una solicitud nombra un sistema o cliente diferente, usa el servidor MCP configurado para ese; si no hay ninguno registrado, dilo en lugar de actuar aquí.

Eso es lo que permite a un agente enrutar "por favor revisa esto en DEV cliente 200" al servidor correcto sin llamar a nada. healthcheck reporta la misma identidad para un servidor que necesita ser preguntado directamente.

La declaración se comprueba. SAP nombra el sistema y el cliente en la cookie de sesión que establece al iniciar sesión (SAP_SESSIONID_DEV_100), así que el servidor sabe a qué está realmente conectado. Si eso no coincide con SAP_SYSTEM_ID — una entrada copiada y pegada que apunta al host equivocado, por ejemplo — healthcheck lleva un WARNING y se registra ruidosamente al inicio. Vale la pena vigilarlo, porque cada herramienta sigue funcionando perfectamente; solo que en el sistema equivocado.


Recorrido rápido

Lee cualquier objeto por nombre — no se necesita descubrimiento de URL:

{"tool":"readAbapObject","args":{"objectName":"ZCL_MY_CLASS"}}
{"tool":"describeAbapTable","args":{"tableName":"T000"}}

Examina una convención de nombres completa — los patrones se normalizan por ti, así que zpp_lab se convierte en ZPP_LAB*:

{"tool":"searchPackages","args":{"patterns":["ZPP_*","Z_PP*"]}}
// -> each package with its objects grouped by type, sub-packages, and a \`truncated\` flag

Llama a un módulo de funciones — la firma se lee primero y la solicitud se valida contra ella:

{"tool":"readAbapFunctionModule","args":{"functionModuleName":"STFC_CONNECTION"}}
{"tool":"callFunctionViaJsonRpc","args":{"functionModuleName":"STFC_CONNECTION",
                                         "inputParameters":{"REQUTEXT":"hello"}}}

Un BAPI y su commit deben viajar en un lote, o el commit cae en su propia LUW y los cambios del BAPI se pierden:

{"tool":"callFunctionsViaJsonRpc","args":{"calls":[
  {"functionModuleName":"BAPI_USER_LOCK","inputParameters":{"USERNAME":"DEVUSER"}},
  {"functionModuleName":"BAPI_TRANSACTION_COMMIT","inputParameters":{"WAIT":"X"}}
]}}

El ciclo completo de escritura (bloquear → modificar → comprobar → activar → desbloquear), el depurador, ATC y todos los demás flujos de trabajo están en docs/MCP-Tools.md §4.


Trabajando con objetos ABAP

Tres herramientas cubren la mayor parte de lo que necesitas, y cada una toma un nombre en lugar de una URL de ADT:

QuieresHerramienta
El código fuente de una clase, programa, include, grupo de funciones o móduloreadAbapObject
Cómo se ve una tabla, estructura o vistadescribeAbapTable
Todo lo que hay detrás de una convención de nombressearchPackages
{"tool":"readAbapObject",   "args":{"objectName":"ZCL_MY_CLASS"}}
{"tool":"describeAbapTable","args":{"tableName":"T000"}}
{"tool":"searchPackages",   "args":{"patterns":["ZPP_*","Z_PP*"]}}

readAbapObject devuelve los metadatos y el código fuente en una sola llamada. Cuando un nombre pertenece a varios objetos — ZPP_EXT_LABEL_DATA es tanto un grupo de funciones como un módulo de funciones — elige el más específico y te lo dice, mediante ambiguous:true y alternatives; pasa objectType para forzar la elección. Los objetos sin código fuente vuelven con hasSource:false y un puntero a la herramienta correcta.

describeAbapTable da nombres de campos, tipos DDIC, longitudes, indicadores de clave, elementos de datos, dominios y tablas de verificación — la tabla de verificación es el objetivo de la clave externa, que es la forma más rápida de ver cómo se unen dos tablas. objectStructure no devuelve campos para una tabla, y tableContents devuelve filas en lugar de una definición, así que ninguno responde "¿cómo se ve esta tabla?".

Reglas que vale la pena poner en el prompt del sistema de tu cliente

  • Prefiere las herramientas por nombre. Solo recurre a searchObjectobjectStructuregetObjectSource cuando necesites los resultados intermedios. Nunca construyas manualmente una ruta /sap/bc/adt/....
  • Selecciona eficientemente. Las tablas de SAP son grandes. Siempre restringe los SELECT con una cláusula WHERE, y usa SELECT SINGLE (todos los campos clave conocidos) o UP TO n ROWS en caso contrario.
SELECT vgbel FROM vbrp WHERE vbeln = @lv_vbeln INTO @DATA(lv_vgbel) UP TO 1 ROWS.
  EXIT.
ENDSELECT.

SAP está desacoplado de tu sistema de archivos: leer el código fuente lo devuelve solo como resultado de herramienta, y escribir un archivo local no cambia nada en SAP. Las copias locales son útiles para comparar, nada más.

Los README anteriores listaban GetTable, GetStructure y GetTypeInfo. Esos pertenecen al proyecto separado mcp-abap-adt, no a este servidor.


Desarrollo

npm run build          # tsc -> dist/
npm test               # jest: parser, tool catalogue, JSON-RPC handler (no SAP system needed)
npx tsc --noEmit       # type check only

Las pruebas viven en src/__tests__ y se ejecutan completamente sin conexión — la suite JSON-RPC ejercita el manejador de extremo a extremo contra un nodo falso de SAP Gateway.

Contra un sistema real (necesita un ticket Kerberos), la comprobación de extremo a extremo es:

npm run build
node scripts/live-jsonrpc-check.mjs      # add NODE_TLS_REJECT_UNAUTHORIZED=0 for an internal CA

Conduce el servidor compilado sobre MCP stdio exactamente como lo haría un cliente, y solo llama a módulos de funciones de solo lectura.

Añadir una herramienta es un cambio de un archivo — ver docs/MCP-Tools.md §10.

Solución de problemas

SíntomaCausa / solución
HTTP 401 en cada llamadaModo Kerberos: sin ticket válido, o el sistema no acepta SPNEGO — comprueba klist y tu conexión VPN/dominio. Modo certificado: ver docs/Authentication.md §6.
curl nicht gefundenEl arranque SSO no pudo encontrar curl — establece SSO_CURL_PATH.
SAP rejected the client certificateEl mapeo CERTRULE, icm/HTTPS/verify_client, o la confianza de CA en STRUST. El error nombra el sujeto que se presentó — compáralo con CERTRULE.
unable to get local issuer certificateCA interna. Establece NODE_TLS_REJECT_UNAUTHORIZED=0 (solo desarrollo).
Las herramientas RFC devuelven reachable:falseEjecuta checkJsonRpcEndpoint. Separa un nodo SICF /sap/gw/jsonrpc inactivo de un problema de CSRF o autorización.
-32601 de un módulo de funcionesNo existe, no está habilitado para RFC, o S_RFC deniega su grupo de funciones.
El cliente no muestra herramientasVerifica la ruta absoluta a dist/index.js y que npm run build se haya ejecutado.

Más en docs/MCP-Tools.md §8.

Contribuciones

  1. Haz un fork del repositorio
  2. git checkout -b feature/your-feature-name
  3. Haz tu cambio, mantén npm test y npx tsc --noEmit en verde
  4. git commit -m "Add some feature" y git push origin feature/your-feature-name
  5. Abre un pull request