ServiceNow MCP Server
El servidor MCP de ServiceNow más completo: 17 herramientas para CRUD completo, recorrido de grafos de CMDB, scripts en segundo plano y pruebas ATF. Funciona con Claude, Cursor y cualquier cliente MCP.
Documentación
@onlyflows/servicenow-mcp
El servidor MCP de ServiceNow más completo. 19 herramientas para CRUD completo, diarios de incidentes de solo anexar, recorrido de grafos CMDB, pruebas ATF, perfiles multi-instancia y más.
Construido por OnlyFlows · Publicado por @onlyflowstech
Instalación
npm install -g @onlyflows/servicenow-mcp
servicenow-mcp-setup
Ejecútalo directamente en una terminal; servicenow-mcp-setup te guía por todo el
proceso en un solo comando: genera el material de autenticación local, solicita tu
instancia y credencial, verifica esa credencial contra la instancia,
pregunta qué tablas conceder, escribe el perfil y registra cualquier cliente
compatible cuyo CLI esté instalado. La credencial se ingresa en un prompt oculto:
nunca como argumento, nunca en el historial del shell, y no se escribe nada en el perfil
hasta que la instancia la haya aceptado, por lo que un error tipográfico o una contraseña
incorrecta no deja rastro.
ServiceNow MCP setup
This walks through one ServiceNow connection end to end. Nothing is
written to the profile until your credential is verified against the
instance. Press Ctrl+C at any point to stop; nothing will be saved.
Profile name [dev]: dev
ServiceNow instance (for example dev12345.service-now.com): dev12345.service-now.com
Authentication:
1) basic (default)
2) oauth
3) apikey
Choice [1]: 1
How should the credential be stored?:
1) encrypted (default)
2) reference
Choice [1]: 1
ServiceNow username: integration.user
Enter each secret now. Input is hidden — nothing you type from here
is displayed.
credential:
Verifying against the instance...
ok https://dev12345.service-now.com accepted the credential.
Table access is deny-by-default: a profile with no rules denies every
tool call. Grant the narrowest set that does the job; you can add more
later with servicenow-mcp-setup grant.
Tables to allow for READS:
1) Just incident (default)
2) Common ITSM set (incident,change_request,problem,task,sys_user)
3) All tables (*)
4) Enter a custom list
5) None
Choice [1]: 1
Tables to allow for WRITES:
1) Just incident
2) Common ITSM set (incident,change_request,problem,task,sys_user)
3) All tables (*)
4) Enter a custom list
5) None (default)
Choice [5]: 1
Wrote profile dev.
Register this server with codex and claude-code? [Y/n]: y
ServiceNow MCP doctor
ok node: v22.11.0
ok server command: servicenow-mcp resolves on PATH; clients spawn it over stdio
ok config directory: ~/.servicenow-mcp (0700)
ok profile dev: instance: https://dev12345.service-now.com
ok profile dev: credential: basic credential resolves from its encrypted source
ok profile dev: table access: 1 read, 1 write, 1 target(s)
All checks passed.
Setup complete.
Profile dev
Reads incident
Writes incident
Transport stdio (each client spawns its own servicenow-mcp)
Clients codex, claude-code
Start codex or claude-code and it will launch the server itself.
There is nothing to keep running between sessions.
No hay nada que iniciar. El servidor habla stdio: cada cliente registrado
genera su propia copia de servicenow-mcp bajo demanda y se comunica con él a través
de la entrada y salida estándar de ese proceso. La configuración finaliza ejecutando
las mismas verificaciones que ejecuta doctor, para que puedas
volver a ejecutarlas en cualquier momento:
servicenow-mcp-setup doctor --profile dev
npx @onlyflows/servicenow-mcp@latest setup ejecuta el mismo asistente sin una
instalación global, y servicenow-mcp setup es un alias de
servicenow-mcp-setup.
Configuración mediante scripts
Pasa cualquier indicador, o ejecuta sin una terminal, y el asistente se aparta para
dar paso al comportamiento no interactivo original, de modo que los scripts de CI y
aprovisionamiento no se ven afectados. --non-interactive lo fuerza explícitamente:
servicenow-mcp-setup --non-interactive --clients none --json
servicenow-mcp-profile create --name dev --instance https://yourinstance.service-now.com \
--auth-type oauth --client-id <client-id> --source reference --provider env
servicenow-mcp-setup grant --profile dev --read incident,problem --write incident
Los comandos servicenow-mcp-setup
| Comando | Propósito |
|---|---|
servicenow-mcp-setup | Generar material de autenticación local y registrar clientes compatibles |
servicenow-mcp-setup client --client <name> | Imprimir configuración copiable para un cliente |
servicenow-mcp-setup grant --profile <name> --read <tables> | Agregar reglas de acceso a tablas a un perfil |
servicenow-mcp-setup doctor | Diagnosticar la instalación e imprimir soluciones |
--force regenera los identificadores de propietario/cliente pero conserva
deliberadamente SN_PROFILE_ENCRYPTION_KEY, que descifra cada sobre de credenciales en
config.json. Agrega --help a cualquier comando para ver sus
opciones completas.
El servidor se ejecuta como tú, y la lista de clientes es el límite. Nada escucha en un puerto, por lo que nada fuera de esta máquina puede alcanzarlo y ninguna página web puede controlarlo. Lo que queda es el registro: cada cliente MCP registrado aquí puede generar el servidor y usar cualquier acceso a ServiceNow que tus perfiles concedan, como tu cuenta de integración. Mantén las concesiones limitadas y elimina un cliente que ya no uses con
claude mcp remove servicenow-mcpocodex mcp remove servicenow-mcp. Ninguna credencial de ServiceNow se copia en el archivo de configuración de un cliente: el servidor generado lee el perfil y su clave de cifrado del directorio~/.servicenow-mcpexclusivo del propietario.
Conexión de un cliente
servicenow-mcp-setup registra Codex y Claude Code automáticamente cuando su
CLI está en PATH. Para todo lo demás:
servicenow-mcp-setup client --client claude-desktop
servicenow-mcp-setup client --client all
Cada cliente compatible habla stdio de forma nativa, por lo que cada uno se configura de la misma manera: un comando para generar.
claude mcp add servicenow-mcp -- servicenow-mcp
codex mcp add servicenow-mcp -- servicenow-mcp
stdio es el transporte predeterminado para ambos CLI, por lo que no hay indicador de transporte que pasar. Para clientes configurados por archivo:
{
"mcpServers": {
"servicenow-mcp": { "command": "servicenow-mcp", "args": [] }
}
}
| Cliente | Configurado por | Ubicación de configuración |
|---|---|---|
| Claude Code | claude mcp add o .mcp.json | proyecto o --scope user |
| Codex | codex mcp add o config.toml | ~/.codex/config.toml |
| Cursor | archivo | ~/.cursor/mcp.json o .cursor/mcp.json |
| VS Code | archivo ("type": "stdio") | .vscode/mcp.json o usuario mcp.json |
| Claude Desktop | archivo | claude_desktop_config.json |
| Windsurf | archivo | ~/.codeium/windsurf/mcp_config.json |
Ningún cliente posee una credencial de ServiceNow. El servidor generado resuelve la
suya propia desde ~/.servicenow-mcp, que es exclusiva del propietario.
Los bloques completos por cliente están en Configuración de servicio y cliente V2.
servicenow-mcpdebe estar en elPATHdel cliente que genera. Una instalación global de npm lo coloca allí. Si no es así (una instalación local del proyecto o un cliente GUI con unPATHdiferente), registra el punto de entrada absoluto en su lugar;servicenow-mcp-setup doctorverifica esto e imprime el comando exacto.
Creación guiada de perfiles desde tu cliente
Después del arranque, un cliente MCP conectado puede guiarte en la creación de perfiles:
Add a ServiceNow MCP profile for https://yourinstance.service-now.com
El prompt de MCP es servicenow-mcp.add-profile. Guía el nombre del perfil, el modo de
autenticación y el acceso de denegación predeterminada con privilegios mínimos, y
deliberadamente no te pide que pegues contraseñas, claves API, tokens de portador,
secretos de cliente OAuth o claves de cifrado en el chat.
Qué se instala
servicenow-mcp— el propio servidor MCP, generado por un cliente a través de stdioservicenow-mcp-profile— gestiona las credenciales del perfil fuera de bandaservicenow-mcp-setup— arranque, configuración del cliente, concesiones y diagnóstico
Configuración manual sin el arranque
El servidor mantiene la configuración explícita. Una ejecución manual necesita:
- identidad de auditoría:
MCP_OWNER_IDyMCP_CLIENT_ID(opcional; etiquetan los registros de auditoría y tienen como valor predeterminadolocal-owner/local-client) - un perfil de ServiceNow con nombre, ya sea en
~/.servicenow-mcp/config.jsono medianteSN_PROFILE_NAME+SN_INSTANCE+ variablesSN_*específicas de autenticación - reglas de acceso a tablas por perfil; el acceso no configurado deniega todo
La ruta de entorno SN_* construye un perfil solo cuando
~/.servicenow-mcp/config.json no existe. Una vez que creas un archivo de perfil,
SN_ALLOWED_READ_TABLES, SN_ALLOWED_WRITE_TABLES y
SN_TABLE_ACCESS_TARGETS dejan de aplicarse y las reglas deben vivir en el perfil
(servicenow-mcp-setup grant). Esta es la causa más común de un servidor que
deniega cada llamada; servicenow-mcp-setup doctor lo detecta.
El servidor lee ~/.servicenow-mcp/server.env por sí mismo al inicio, porque el
cliente que lo genera proporciona su propio entorno y no habrá obtenido
nada. Un valor ya presente en el entorno siempre gana sobre ese
archivo, por lo que la configuración de contenedores y CI no se ve afectada.
Para una ejecución rápida solo con entorno y sin archivo de perfil (manejar el servidor manualmente a través de una tubería, o desde un cliente que pase variables de entorno), inyecta valores protegidos desde tu llavero o gestor de secretos y pasa solo valores no secretos en la línea de comandos:
MCP_OWNER_ID=local-owner \
MCP_CLIENT_ID=local-client \
SN_PROFILE_NAME=dev \
SN_INSTANCE=https://yourinstance.service-now.com \
SN_USER=your_user \
SN_ALLOWED_READ_TABLES=incident,problem,change_request \
SN_ALLOWED_WRITE_TABLES=incident,change_request \
SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]' \
servicenow-mcp
No pongas SN_PASSWORD, secretos de cliente OAuth o claves API en el historial
de comandos. Inyéctalos en el entorno del servidor desde tu mecanismo de secretos
aprobado, o déjalos en el archivo de perfil exclusivo del propietario donde el servidor
pueda resolverlos sin que ningún cliente los vea.
Instalación desde el código fuente para desarrollo
Usa la instalación desde el código fuente solo para desarrollo o cambios no publicados:
git clone https://github.com/onlyflowstech/servicenow-mcp.git
cd servicenow-mcp
npm install
npm run build
npm start
Para desarrollo local con recompilación y mapas de origen:
npm run dev
La implementación en contenedores se aplica al transporte HTTP inactivo en lugar de una instalación stdio 2.0; consulta Implementación de contenedor de producción y el límite empresarial.
Perfiles Multi-Instancia
Gestiona múltiples instancias de ServiceNow (dev, test, prod, PDI) con perfiles con nombre. Cada llamada de herramienta debe seleccionar un perfil configurado explícitamente; V2 no tiene perfil activo ni respaldo de perfil predeterminado.
Configuración
Crea perfiles con el CLI en lugar de hacerlo manualmente: captura las credenciales sin ponerlas en argv y escribe el archivo con la propiedad y el modo correctos:
servicenow-mcp-profile create --name dev --instance https://mydev.service-now.com --auth-type basic --username admin --source reference --provider env
servicenow-mcp-profile create --name prod --instance https://myprod.service-now.com --auth-type basic --username api.user --source reference --provider env
servicenow-mcp-setup grant --profile dev --read incident,problem --write incident
servicenow-mcp-setup grant --profile prod --read incident
El ~/.servicenow-mcp/config.json resultante se ve así. Ten en cuenta
tableAccess: un perfil sin él deniega cada llamada de herramienta.
{
"version": 2,
"profiles": {
"dev": {
"instance": "https://mydev.service-now.com",
"username": "admin",
"credential": { "type": "secret_ref", "provider": "env", "reference": "SN_PASSWORD_DEV" },
"description": "Development instance",
"tableAccess": {
"readTables": ["incident", "problem"],
"writeTables": ["incident"],
"targets": [
{
"table": "incident",
"kind": "canonical",
"tools": ["sn_query", "sn_get", "sn_aggregate", "sn_schema", "sn_create", "sn_update"],
"closureComplete": true,
"relatedTables": ["incident"]
},
{
"table": "problem",
"kind": "canonical",
"tools": ["sn_query", "sn_get", "sn_aggregate", "sn_schema"],
"closureComplete": true,
"relatedTables": ["problem"]
}
]
}
}
}
}
Haz que el supervisor, orquestador, llavero o gestor de secretos aprobado proporcione
los valores referenciados por SN_PASSWORD_DEV y SN_PASSWORD_PROD en el
entorno con el que se genera el servidor, o en ~/.servicenow-mcp/server.env,
al que el servidor recurre. No escribas ninguno de los dos valores en un comando de
shell, argumento de comando, archivo dotenv o historial de comandos.
Cada entrada targets afirma closureComplete: true, lo que significa que
relatedTables enumera cada tabla base, ancestro y descendiente que la operación
puede alcanzar. Cuando una tabla extiende otra, declárala:
servicenow-mcp-setup grant --profile dev --read change_request --related change_request=task.
Las tablas relacionadas se unen a la lista de permitidos pero no obtienen un destino
propio, por lo que un llamador no puede dirigirse a ellas directamente.
Opciones de Credenciales
| Formato | Ejemplo | Descripción |
|---|---|---|
| Referencia de entorno heredada | "env:SN_PASSWORD_DEV" | Forma V1 compatible con lectura; migrada a una referencia estructurada en la siguiente escritura |
| Referencia de secreto | {"type":"secret_ref","provider":"env","reference":"SN_PASSWORD_DEV"} | Referencia neutral al proveedor resuelta solo para la solicitud seleccionada |
| Sobre cifrado | {"type":"encrypted","version":1,...} | Valor AES-256-GCM creado por el CLI de administración protegido |
Los secretos de perfil en texto plano se rechazan. Usa el comando de operador
servicenow-mcp-profile instalado para crear, inspeccionar, rotar o eliminar perfiles;
lee los secretos mediante un prompt protegido o entrada estándar limitada y rechaza
argumentos de línea de comandos que contengan credenciales. Las fuentes cifradas
requieren exactamente 32 bytes aleatorios codificados como base64 o base64url en
SN_PROFILE_ENCRYPTION_KEY, proporcionados por separado mediante el mecanismo de secretos de
implementación y nunca almacenados en el archivo de perfil. Consulta la
guía de credenciales de perfil y administración.
La indirección heredada env:VAR_NAME sigue siendo legible para cada campo de
secreto: credential, clientSecret y apiKey.
Uso de Perfiles
Pasa el parámetro profile en cada llamada de herramienta:
- "consultar incidentes en prod" — llama a
sn_queryconprofile: "prod" - "obtener incidente INC0010001 en dev" — llama a
sn_getconprofile: "dev" - "muéstrame el endpoint del perfil dev" — llama al diagnóstico de solo lectura
sn_profileconprofile: "dev"
Los perfiles se crean y cambian fuera de banda por el operador del servicio. Los
metadatos heredados default_profile se ignoran y no se persisten en la siguiente
escritura administrativa; el límite de MCP nunca los consulta.
Compatibilidad de configuración SN_*
Si no existe un archivo de configuración, los valores de conexión canónicos
SN_* se exponen solo mediante un mapeo explícito
SN_PROFILE_NAME. Por ejemplo, establece
SN_PROFILE_NAME=dev con SN_INSTANCE, SN_USER y SN_PASSWORD, luego
llama a las herramientas con profile: "dev". Sin SN_PROFILE_NAME, las
variables de conexión simples no crean un perfil y no pueden enrutar una solicitud.
Los valores secretos siguen siendo referencias de entorno solo en tiempo de ejecución
y nunca se persisten como texto plano.
Autenticación
Hay tres tipos de autenticación de ServiceNow disponibles por perfil, seleccionados
con authType (predeterminado: basic). La configuración del
perfil se gestiona fuera de banda por el operador del servicio. Esta es la única
autenticación involucrada: el transporte es stdio, por lo que no hay endpoint frente
al servidor que proteger.
Aviso: el programa de restricción de autenticación básica entrante de ServiceNow está eliminando gradualmente la autenticación básica para solicitudes de API: las instancias pueden comenzar a rechazarla en cualquier momento (exenciones: cuentas de solo acceso web o el rol
snc_basic_auth_api_access). OAuth es el tipo de autenticación recomendado. El servidor imprime una advertencia de inicio para perfiles de autenticación básica.
OAuth 2.0 (recomendado)
Concesión client_credentials (predeterminada): crea un cliente de endpoint de API OAuth
en ServiceNow (System OAuth → Application Registry) y referencia el secreto mediante
indirección env::
{
"version": 2,
"profiles": {
"dev": {
"instance": "https://mydev.service-now.com",
"authType": "oauth",
"clientId": "your-oauth-client-id",
"clientSecret": "env:SN_CLIENT_SECRET",
"description": "OAuth client_credentials"
}
}
}
Concesión password: establece grantType y proporciona también
las credenciales del usuario:
{
"instance": "https://mydev.service-now.com",
"authType": "oauth",
"grantType": "password",
"clientId": "your-oauth-client-id",
"clientSecret": "env:SN_CLIENT_SECRET",
"username": "integration.user",
"credential": "env:SN_PASSWORD_DEV"
}
Los tokens se almacenan en caché hasta poco antes de su expiración expires_in
y se actualizan automáticamente (incluida una sola actualización + reintento en 401).
Las respuestas de tokens nunca se registran.
Clave API
Para instancias que usan Perfiles de Autenticación Entrante con claves API. El nombre
del encabezado es configurable (predeterminado x-sn-apikey):
{
"instance": "https://mydev.service-now.com",
"authType": "apikey",
"apiKey": "env:SN_API_KEY",
"apiKeyHeader": "x-sn-apikey"
}
Básica (predeterminada, obsoleta por ServiceNow)
{
"instance": "https://mydev.service-now.com",
"username": "admin",
"credential": "env:SN_PASSWORD_DEV"
}
En un 401, el error explica el programa de restricción de autenticación básica (KB3096078) y cómo migrar a OAuth.
Tiempos de espera y reintentos
Cada solicitud está limitada por un tiempo de espera (predeterminado 30s; por perfil timeoutMs o env SN_TIMEOUT_MS) y se reintenta hasta dos veces con retroceso exponencial en 429/502/503/504, respetando Retry-After. Las solicitudes POST solo se reintentan en 429, nunca después de un 5xx que pueda haber ejecutado efectos secundarios.
ServiceNow upstream puede devolver HTTP 429 con un cuerpo vacío, mientras que los rechazos por límite de tasa HTTP de este servidor devuelven un cuerpo JSON corto más Retry-After. Trate el estado y el encabezado Retry-After como autoritativos; no mida ni valide el éxito de las herramientas basándose únicamente en la latencia de respuesta o la forma del cuerpo. En instancias normales de ServiceNow, planifique en torno al valor predeterminado de limitación de Background de aproximadamente 120 solicitudes por 60 segundos por identidad, a menos que el límite de la instancia se eleve explícitamente.
¿Por qué este servidor MCP?
La mayoría de las integraciones MCP de ServiceNow son de solo lectura y admiten un puñado de tablas. Este servicio ofrece un catálogo de herramientas más amplio detrás de una política de tablas y herramientas explícita, denegada por defecto:
| Característica | Otros | @onlyflows/servicenow-mcp |
|---|---|---|
| Consultar registros | ✅ | ✅ |
| Crear registros | ❌ | ✅ |
| Actualizar registros | ❌ | ✅ |
| Eliminar registros | ❌ | ✅ (con confirmación de seguridad) |
| Operaciones masivas | ❌ | ✅ (simulación por defecto) |
| Agregaciones (COUNT/AVG/MIN/MAX/SUM) | ❌ | ✅ |
| Introspección de esquema de tablas | ❌ | ✅ |
| Recorrido de relaciones CMDB | ❌ | ✅ (recursivo, profundidad configurable) |
| Monitoreo de salud de la instancia | ❌ | ✅ (versión, nodos, trabajos, estadísticas) |
| Gestión de adjuntos | ❌ | ✅ (listar, subir, descargar; base64 en línea, sin sistema de archivos del host) |
| Consultas de registros del sistema | ❌ | ✅ |
| Búsqueda de código entre artefactos | ❌ | ✅ |
| Descubrimiento de tablas/aplicaciones/plugins | ❌ | ✅ |
| Ejecución de pruebas ATF | ❌ | 🚧 listado/resultados disponibles; ejecución actualmente denegada por política |
| Interfaz de lenguaje natural | ❌ | 🚧 actualmente denegada por política pendiente de un plan de acceso tipado |
| Scripts en segundo plano | ❌ | 🚧 en la hoja de ruta (SNS-39) |
| Perfiles multi-instancia | ❌ | ✅ (perfiles nombrados, anulación por llamada) |
| Total de herramientas | 1–3 | 19 |
Inicio rápido
El servidor habla stdio y requiere Node.js 20 o superior. El camino más corto es el bootstrap descrito en Instalación:
servicenow-mcp-setup
Eso registra sus clientes; cada uno inicia el servidor cuando lo necesita.
El resto de esta sección es la ruta de entorno manual, para una implementación que inyecta todo desde un supervisor o gestor de secretos, o para manejar el servidor manualmente a través de una tubería.
Use .env.example solo como un inventario de configuración no secreto. Sus asignaciones de valores protegidos están intencionalmente vacías; inyecte los secretos de ServiceNow a través de un supervisor, orquestador, llavero o gestor de secretos en lugar de completar un archivo dotenv del repositorio.
Las variables
SN_ALLOWED_*ySN_PROFILE_NAMEa continuación construyen un perfil solo cuando~/.servicenow-mcp/config.jsonno existe. Con un archivo de perfil presente, coloque las reglas en el perfil conservicenow-mcp-setup grant.
export MCP_OWNER_ID="your-owner-id"
export MCP_CLIENT_ID="your-client-id"
export SN_ALLOWED_READ_TABLES="incident,problem,change_request"
export SN_ALLOWED_WRITE_TABLES="incident,change_request"
export SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]'
export SN_PROFILE_NAME="dev"
export SN_INSTANCE="https://yourinstance.service-now.com"
export SN_USER="your_username"
npm run build
npm start
Antes de ejecutar esos comandos no secretos, el mecanismo de secretos de runtime aprobado ya debe haber inyectado el secreto específico de autenticación de ServiceNow en el proceso. No lo ingrese en este bloque de shell.
Un cliente se conecta iniciando el comando; no hay URL ni encabezado:
{
"mcpServers": {
"servicenow-mcp": { "command": "servicenow-mcp", "args": [] }
}
}
Los mensajes JSON-RPC viajan en el stdin y stdout del hijo, un mensaje delimitado por nueva línea por marco. Todo lo demás que el servidor informa (advertencias de inicio y un evento JSON-line estructurado por llamada de herramienta completada) va a stderr, que su cliente captura como su registro del servidor. No hay límite de tamaño por mensaje impuesto por el transporte.
Para ejemplos completos del SDK oficial y de clientes independientes, configuración segura de dos perfiles y verificaciones cruzadas de perfil/resultado/auditoría, consulte Configuración del servicio y cliente V2.
Cambios importantes en 2.0
Cada llamada de herramienta debe nombrar un profile, y el acceso a tablas está denegado por defecto. Esos dos requieren acción en cada instalación. El transporte es stdio, como lo era en 1.0.0, por lo que un cliente configurado con una entrada command sigue funcionando.
Los cambios importantes desde 1.0.0, cada uno con un ejemplo antes/después, están en Migración a 2.0.
Guías de implementación para el transporte HTTP inactivo
2.0 incluye solo stdio. La imagen de contenedor, el contrato de salud y apagado, el runbook de operaciones y el adaptador Secure MCP Tunnel describen el transporte HTTP inactivo, al que ninguna ruta CLI llega. Se mantienen porque ese transporte es una forma de implementación empresarial planificada, no porque se apliquen a una instalación 2.0: nada en esta sección es necesario para usar este servidor.
- Implementación de contenedor de producción — artefacto OCI, runtime no root, procedencia y escaneo
- Runbook de operaciones remotas — interpretación de salud, telemetría, alertas, rotación, respuesta a incidentes
- Conectividad privada de ChatGPT — adaptador Secure MCP Tunnel solo de salida
Referencia de herramientas
CRUD principal
| Herramienta | Descripción |
|---|---|
sn_query | Consultar una tabla aprobada con filtros estructurados, selección de campos, paginación y ordenamiento; las lecturas sin procesar acotadas requieren una regla de política explícita |
sn_get | Obtener un solo registro por sys_id de una tabla aprobada |
sn_create | Crear un registro en cualquier tabla con permiso de escritura, usando solo campos de escritura aprobados por la política de campos; incident además requiere un short_description acotado |
sn_update | Actualizar un registro seleccionado por sys_id exacto en cualquier tabla con permiso de escritura, usando solo campos de escritura aprobados por la política de campos; rechaza comments y work_notes con guía de migración de herramientas dedicadas |
sn_incident_add_comment | Agregar un comentario visible para el cliente acotado a un incidente; las llamadas repetidas agregan de nuevo |
sn_incident_add_work_note | Agregar una nota de trabajo interna acotada a un incidente; las llamadas repetidas agregan de nuevo |
sn_delete | Eliminar un registro en una tabla de escritura aprobada (requiere confirm: true) |
sn_batch | Actualización/eliminación masiva usando un filtro estructurado requerido y seguridad de simulación (los selectores codificados sin procesar están prohibidos; requiere confirm: true para ejecutar) |
Analítica y esquema
| Herramienta | Descripción |
|---|---|
sn_aggregate | COUNT, AVG, MIN, MAX, SUM con agrupación |
sn_schema | Definiciones de campos de tabla, tipos, referencias |
sn_health | Versión de la instancia, nodos del clúster, trabajos atascados, estadísticas clave |
CMDB y operaciones
| Herramienta | Descripción |
|---|---|
sn_relationships | Recorrido del grafo CI de CMDB — ascendente/descendente/ambos, profundidad configurable |
sn_attach | Listar adjuntos, devolver descargas como base64 en línea y subir contenido base64 en línea; nunca toca una ruta del sistema de archivos del host |
sn_syslog | Consultar registros del sistema con filtros de severidad/origen/tiempo |
sn_codesearch | Buscar reglas de negocio, includes de script, scripts de cliente, etc. |
sn_discover | Descubrir tablas, aplicaciones con ámbito, aplicaciones de la tienda, plugins |
Pruebas y automatización
| Herramienta | Descripción |
|---|---|
sn_atf | Listar pruebas/suites ATF y obtener resultados; run/run-suite actualmente fallan de forma cerrada |
sn_nl | Actualmente falla de forma cerrada hasta que la composición en lenguaje natural emita un plan de acceso tipado completo |
sn_script (ejecución de scripts en segundo plano) se envió en 1.0.0 como un stub no implementado y no se publica en 2.0 — no aparece en tools/list. Use sn_query y sn_batch en su lugar. Consulte Hoja de ruta.
Gestión de perfiles
| Herramienta | Descripción |
|---|---|
sn_profile | Inspeccionar metadatos no secretos para un perfil nombrado explícitamente; la configuración del perfil es gestionada por el operador fuera de banda |
Variables de entorno
Runtime MCP
| Variable | Requerida | Predeterminado | Descripción |
|---|---|---|---|
MCP_OWNER_ID | ❌ | local-owner | Identificador de propietario estable no secreto registrado en el contexto de solicitud/herramienta y en cada registro de auditoría. Una etiqueta, no una credencial; nunca se verifica. |
MCP_CLIENT_ID | ❌ | local-client | Identificador de cliente estable no secreto registrado en el contexto de solicitud/herramienta y en cada registro de auditoría. Una etiqueta, no una credencial; nunca se verifica. |
Esa es la lista completa. No hay dirección de enlace, puerto, lista blanca Host/Origin, límite de concurrencia, límite de conexiones, período de gracia de apagado, token portador o límite de tasa, porque no hay listener: un cliente inicia el servidor y es dueño de su ciclo de vida.
El servidor lee estos desde su entorno y recurre a ~/.servicenow-mcp/server.env para cualquiera que no encuentre allí. Ese archivo es solo del propietario (modo 0600) y es donde servicenow-mcp-setup escribe los identificadores generados y SN_PROFILE_ENCRYPTION_KEY. Existe porque el cliente que inicia el servidor suministra su propio entorno y no habrá obtenido nada. Un valor ya presente en el entorno siempre gana, por lo que un contenedor o runner de CI que pase configuración directamente no se ve afectado. servicenow-mcp-setup doctor informa el modo y el contenido de ese archivo.
Observabilidad
Cada llamada de herramienta completada emite un evento JSON-line a stderr, que el cliente que inicia captura como su registro del servidor:
{"schemaVersion":1,"type":"mcp_tool","observedAtMs":1737000000000,"latencyMs":42,
"correlationId":"stdio-<session>-<invocation>","ownerIdHash":"sha256:...",
"clientIdHash":"sha256:...","tool":"sn_query","profile":"dev",
"instance":"https://dev00001.service-now.com","outcome":"success","reason":null,
"errorCategory":null,"retry":null,"retryAfterSeconds":null}
Las auditorías de herramientas clasifican la cancelación de solicitudes y la expiración del plazo de solicitud por separado de los fallos del handler. Los identificadores de propietario/cliente configurados se representan solo mediante seudónimos SHA-256; los encabezados, URLs/cadenas de consulta, cuerpos, credenciales, tokens, objetos de configuración y texto de excepciones no son campos de eventos. La telemetría nunca bloquea un resultado de herramienta: la contrapresión de stderr retiene como máximo 256 líneas pendientes, descarta eventos excesivos y emite un resumen {"type":"telemetry_dropped","count":N} después de que el flujo se drene.
Un ID de correlación es stdio-<session>-<invocation>. La mitad de sesión es fija durante la vida de un servidor iniciado, por lo que todos los registros de una sesión de cliente se agrupan; la mitad de invocación es nueva por llamada. Ninguna mitad se deriva de nada que el llamador haya enviado.
stdout lleva el protocolo y nada más. Cada diagnóstico va a stderr. Un byte extraviado en stdout desincronizaría el parser JSON-RPC del cliente y terminaría la sesión, por lo que no existe tal cosa como un console.log inofensivo en la ruta de inicio o solicitud; test/stdio-entrypoint.test.ts inicia un servidor real y lo verifica.
Los argumentos que fallan el esquema de una herramienta son rechazados por el SDK MCP antes de que se ejecute cualquier handler, por lo que devuelven un error al llamador pero no producen evento de auditoría — el contexto de ejecución que emitiría uno nunca se abre. Cada llamada que llega a una herramienta es auditada.
Tamaño del cuerpo y concurrencia (solo runtime HTTP inactivo)
Nada de esto se aplica al servidor enviado. Describe el runtime HTTP inactivo, al que ninguna ruta CLI llega — consulte el límite de lanzamiento empresarial — y solo afecta a alguien que incruste este paquete y llame a createHttpRuntime directamente. Sobre stdio no hay límite de cuerpo de solicitud ni techo de admisión.
El tamaño del cuerpo de solicitud y la concurrencia se intercambian directamente entre sí bajo el techo de admisión de 512 MiB:
maxBodyBytes | Mayor concurrencia que inicia | Efecto |
|---|---|---|
| 1 MiB (predeterminado enviado) | 2 | 416 MiB presupuestados; la configuración prevista |
| 1.75 MiB | 2 | 512 MiB — exactamente en el techo |
| 2 MiB | 1 | Single-flight: cada llamada de herramienta se serializa |
| 5.75 MiB | 1 | el último valor que inicia en absoluto |
| por encima de 5.75 MiB | ninguno | el inicio falla en cualquier concurrencia |
Dos modos de fallo vale la pena conocer:
- A partir de 2 MiB, el servidor opera en modo de un solo vuelo. La concurrencia 2 ya no es viable, por lo que el runtime solo puede iniciar en 1 y cada llamada de herramienta se pone en cola detrás de las demás. No hay advertencia ni línea de registro: se presenta como "el servidor se volvió lento", y una carga grande bloquea todas las demás herramientas durante su duración. Nada conecta la causa con el efecto.
- Por encima de 5.75 MiB, el servidor se niega a iniciar. Un constructor
throw, no un límite. El mensaje mencionamaxConcurrentRequestsymaxBodyBytes, pero no indica ni el techo, ni la aritmética, ni un valor funcional; la tabla anterior es el camino a seguir.
maxBodyBytes no es configurable por el operador. src/http-entrypoint.ts
construye la política de solicitudes solo con allowedHosts y allowedOrigins, por lo que el
límite siempre es 1 MiB y ninguna variable de entorno lo cambia.
Caché de metadatos
Las lecturas estables de metadatos de ServiceNow se almacenan en caché por instancia e identidad de credenciales durante 24 horas de forma predeterminada. Los patrones de tabla en caché predeterminados son
sys_glide_object, sys_dictionary, sys_db_object, sys_app, sys_plugins,
sys_metadata* y sys_flow*. Establezca metadataCache.ttlMs y
metadataCache.tables en un perfil respaldado por archivo, o SN_METADATA_CACHE_TTL_MS
/ SN_METADATA_CACHE_TABLES para el perfil de entorno explícito. sn_query,
sn_get y sn_schema aceptan force_recache: true para actualizar los metadatos. Una
acierto de caché realiza una sonda ligera de sys_updated_on y se usa solo cuando no
hay filas de metadatos coincidentes que hayan cambiado desde la sincronización anterior.
Requisito previo: una zona horaria de sesión resoluble. La sonda de frescura compara
sys_updated_on, que ServiceNow evalúa en la zona horaria del usuario de la sesión,
no en UTC. Resolver esa zona requiere que el user_name de la cuenta autenticada
busque sys_user.time_zone, recurriendo a la propiedad glide.sys.default.tz.
Cuando no se puede resolver, la caché se desactiva para esa
identidad en lugar de asumir UTC: una suposición incorrecta serviría silenciosamente
metadatos obsoletos durante la duración del desfase. El servidor registra una advertencia que
nombra las lecturas que necesita.
Esto tiene una consecuencia que vale la pena conocer antes de configurarlo:
| Autenticación de perfil | Caché de metadatos |
|---|---|
| Básica | funciona: el perfil lleva un nombre de usuario |
| Concesión de contraseña OAuth | funciona: el perfil lleva un nombre de usuario |
| client_credentials OAuth | deshabilitada: no hay nombre de usuario para resolver una zona horaria |
| Clave API | deshabilitada: no hay nombre de usuario para resolver una zona horaria |
El perfil también necesita acceso de lectura a sys_user (para time_zone) y
sys_properties (para glide.sys.default.tz) para que la búsqueda tenga éxito.
La compensación honesta: la caché solo ahorró bytes de carga útil, nunca
viajes de ida y vuelta: un acierto de caché aún cuesta una sonda de frescura. Entonces, en un perfil de client-credentials
o de clave API, la pérdida práctica es ancho de banda en lecturas de sys_dictionary,
no latencia. Si está eligiendo un modo de autenticación, este no debería ser el factor
decisivo.
Las eliminaciones se vuelven visibles dentro de un TTL. La sonda de frescura detecta
actualizaciones, no eliminaciones, por lo que una fila eliminada en el origen se sigue sirviendo hasta que su entrada
expira y se vuelve a buscar, hasta 24 horas con el TTL predeterminado. Este es un comportamiento
aceptado, no un defecto; reduzca SN_METADATA_CACHE_TTL_MS o pase
force_recache: true si necesita que una eliminación se refleje antes.
Selección de campos sin restricciones (fields=all, response_format=detailed)
Ambos se resuelven a una selección de comodín. Anteriormente omitían sysparm_fields
por completo, por lo que ServiceNow devolvía cada columna y una tabla amplia podría superar el
límite acumulativo de 1 MiB aguas arriba y fallar la llamada por completo. Ahora están
limitados a un máximo de 100 columnas.
El límite acota la solicitud aguas arriba, no la respuesta: truncar después de
la recepción no ayudaría, porque los bytes ya han cruzado el cable y ya
superaron el límite. Las columnas se resuelven desde sys_dictionary, recorriendo
super_class para que una tabla extendida contribuya con sus campos heredados. El orden es
determinista: la proyección predeterminada curada de la tabla primero en su orden
declarado, luego cada columna restante alfabéticamente. Los valores predeterminados lideran para que un
resultado limitado siga siendo útil; alfabéticamente después porque el orden de filas del diccionario no es
estable entre instancias. Cada ruta de fallo recurre a la proyección predeterminada limitada de la tabla,
nunca a eliminar sysparm_fields.
sn_query informa el truncamiento a través de su campo hint. sn_get llevará el
mismo aviso en breve.
Dos cambios de comportamiento que vale la pena declarar claramente, porque cambian lo que un llamante recibe:
- Los campos de diario ahora se devuelven.
commentsywork_notesse incluyen en el conjunto resuelto parafields=allydetailed. Consulte Contenido del diario y selección de campos. - Los nombres de campos de apariencia sensible se excluyen por completo del conjunto resuelto.
Un nombre que coincida con el patrón de campo sensible nunca se solicita, en lugar de
solicitarse y depurarse al llegar. Bajo el comportamiento de comodín anterior, el
valor cruzaba el cable y luego se eliminaba; nombrarlo en
sysparm_fieldslo habría traído deliberadamente, lo cual es peor.
Contenido del diario y selección de campos
El contenido del diario en incident — comments (visible para el cliente) y work_notes
(interno) — es legible a través de fields=all, response_format: "detailed", un
fields=comments explícito y sn_schema. La proyección predeterminada aún
lo excluye, por lo que un sn_query o sn_get ordinario no lo devuelve.
Declarado como un hecho más que como una advertencia: el contenido del diario en instancias
reales contiene rutinariamente PII del cliente, por lo que pedir todos los campos en incident devuelve
comentarios visibles para el cliente junto con todo lo demás. Los operadores que otorgan
lecturas de incident a un agente deben saberlo. Si eso no es deseado, otorgue una
lectura más restringida a través de la política de campos en lugar de confiar en la proyección
predeterminada, ya que el llamante elige fields.
Cargas útiles de archivos adjuntos
sn_attach nunca lee ni escribe en rutas del sistema de archivos del host. Las cargas usan un
file_name de hoja seguro más content_base64; las descargas devuelven
content_base64, file_name, content_type y size_bytes. La descarga también
requiere el table propietario y el registro sys_id, que están autorizados por política
y verificados contra los metadatos del archivo adjunto antes de que se devuelvan bytes.
Límite de tamaño: 10 MiB decodificados, y ese es el único. El transporte stdio
enmarca mensajes por nueva línea sin límite de tamaño, por lo que los propios límites de la herramienta son
los que se aplican: 10 MiB de bytes decodificados para una carga y un presupuesto bruto separado de 10 MiB
para una descarga. La descripción del esquema content_base64 de la herramienta lleva
la cifra autoritativa.
El techo práctico de ~760 KiB documentado antes de 2.1 provenía del límite del cuerpo HTTP, que ya no se aplica: el cliente y el servidor comparten una tubería, no un sobre. Base64 aún infla un archivo en aproximadamente un tercio en el mensaje mismo, por lo que un archivo adjunto de 10 MiB es aproximadamente un marco JSON de 13.3 MiB: grande, pero el transporte lo llevará.
Trate sn_attach como adecuado para registros, configuraciones, capturas de pantalla y documentos
en lugar de transferencia masiva; un marco muy grande aún cuesta memoria tanto en el
cliente como en el servidor, y la propia interfaz de ServiceNow o una integración dedicada es un
mejor camino para el movimiento masivo de archivos.
Política de acceso a tablas
2.0 deniega todas las tablas de ServiceNow de forma predeterminada. El acceso a tablas se selecciona por
perfil, no a partir de un valor predeterminado implícito de todo el proceso. Los perfiles respaldados por archivo definen
tableAccess en ~/.servicenow-mcp/config.json; el perfil de entorno explícito SN_PROFILE_NAME
mapea las variables SN_ALLOWED_* a ese único perfil solo
cuando no existe un archivo de perfil. Si un perfil no tiene reglas de tabla, lo deniega todo.
Escriba las reglas con la CLI en lugar de a mano: valida el resultado con el mismo cargador que el servidor usa en el momento de la solicitud:
servicenow-mcp-setup grant --profile dev --read incident,problem --write incident
servicenow-mcp-setup grant --profile dev --read cmdb_ci --tools sn_query,sn_relationships
servicenow-mcp-setup grant --profile dev --read change_request --related change_request=task
Las entradas de la lista de permitidos pueden ser nombres de tabla exactos o el literal * para permitir cada
tabla para esa operación. Los nombres de tabla se recortan, se convierten a minúsculas, se deduplican
y deben ser identificadores válidos de ServiceNow.
tableAccesses la única autoridad a nivel de tabla. Ya no hay una lista integrada de tablas que el servidor rechace incondicionalmente. Un perfil que otorga una tabla la obtiene, sujeto solo a las ACL por usuario de ServiceNow — por lo que una concesión desys_script,sys_user_roleo una tabla de credenciales se honra. Escribirsys_scriptes ejecución de script del lado del servidor bajo la cuenta de integración. El privilegio mínimo ahora vive completamente en la concesión y en los roles que le dé a esa cuenta; otorgue el conjunto más restringido que haga el trabajo y prefiera una cuenta cuyos roles de ServiceNow no puedan alcanzar lo que la concesión no necesita.
| Variable | Requerida | Predeterminado | Descripción |
|---|---|---|---|
SN_ALLOWED_READ_TABLES | ❌ | denegar todo | Tablas permitidas para operaciones de lectura solo en el perfil de entorno explícito SN_PROFILE_NAME. Use * para permitir cada tabla legible. |
SN_ALLOWED_WRITE_TABLES | ❌ | denegar todo | Tablas permitidas para crear, actualizar, agregar al diario de incidentes, eliminar, cargar y operaciones por lotes confirmadas solo en el perfil de entorno explícito SN_PROFILE_NAME. Use * para permitir cada tabla escribible. El permiso de escritura nunca implica permiso de lectura. |
SN_TABLE_ACCESS_TARGETS | Requerida para tablas direccionables por llamante exactas en la lista de permitidos; opcional con * | [] | Clasificación JSON confiable con table, tools exactos permitidos, kind (canonical, alias, view o extension), literal closureComplete: true y el cierre completo de relatedTables de respaldo/ancestro/descendiente. Con *, las entradas de destino omitidas usan la concesión de operación comodín; las entradas de destino explícitas aún pueden restringir herramientas y validar el cierre de tablas relacionadas. |
SN_FIELD_POLICY_DEFINITIONS | Requerida para campos de tablas personalizadas/genéricas | política finita integrada | Objeto JSON confiable claveado por nombre de tabla o *. Cada entrada puede definir defaults, readable y writable; readable/writable aceptan matrices de campos exactos o "*". Los nombres de campos sensibles aún se deniegan. Use {"*":{"defaults":["sys_id"],"readable":"*","writable":[]}} para exploración de tablas personalizadas de solo lectura amplia. Use writable:"*" solo para acceso de mutación amplia intencional. |
SN_ENCODED_QUERY_READ_POLICY | ❌ | denegar todo | Objeto JSON confiable que contiene rules limitados para un par sn_query/tabla exacto. Cada regla requiere maxLength, maxTerms, fields legibles, operators compatibles, maxLimit, maxOffset y maxResponseBytes. Ninguna regla puede autorizar una escritura u otra herramienta. |
La configuración de política inválida falla el inicio. Una herramienta compuesta se admite solo cuando su plan completo de tablas de respaldo está permitido antes del primer acceso al cliente de ServiceNow. Cada destino relacionado debe tener el mismo permiso de lectura o escritura, por lo que una tabla base, un alias, una vista o una extensión no pueden eludir una tabla de respaldo o descendiente no listada. El permiso relacionado no hace que una dependencia sea directamente direccionable por el llamante sin su propia entrada de destino. La política de campos restringe lo que expone una tabla otorgada; no deniega una tabla que el operador otorgó. Los nombres de campos de apariencia sensible permanecen excluidos independientemente. Construya el catálogo de destinos completo a partir de metadatos de ServiceNow aprobados y trátelo como configuración de inicio confiable; omita un destino cuando no se pueda probar que la alcanzabilidad esté completa. Ejemplo de perfil respaldado por archivo:
{
"version": 2,
"profiles": {
"dev": {
"instance": "https://dev.service-now.com",
"username": "integration.user",
"credential": "env:SN_PASSWORD",
"tableAccess": {
"readTables": ["incident", "sys_dictionary"],
"writeTables": ["incident"],
"targets": [
{
"table": "incident",
"kind": "canonical",
"tools": ["sn_query", "sn_get", "sn_create", "sn_update"],
"closureComplete": true,
"relatedTables": ["incident"]
}
]
}
}
}
}
sn_nl y ATF run/run-suite actualmente fallan de forma cerrada porque no emiten
un plan completo de efectos secundarios tipado; usa la herramienta tipada correspondiente en su lugar.
Los campos de diario de incidentes son de solo añadidura: el sn_update genérico rechaza comments
y work_notes antes de las credenciales o la creación del cliente. Usa
sn_incident_add_comment o sn_incident_add_work_note con exactamente
profile, incidente sys_id y content acotado; otorga la herramienta seleccionada
explícitamente en el objetivo incident además del acceso de escritura a esa tabla.
Perfiles de ServiceNow
Nota: Un archivo de perfil es autoritativo cuando está presente. Sin uno,
SN_PROFILE_NAMEdebe mapear explícitamente las variables de conexión canónicas a un perfil nombrado; no existe un perfil sintético ni predeterminado.
| Variable | Requerida | Predeterminado | Descripción |
|---|---|---|---|
SN_PROFILE_NAME | ✅* | — | Nombre explícito para el perfil de entorno local del proceso; requerida antes de que las variables de conexión simples definan cualquier perfil. |
SN_INSTANCE | ✅* | — | URL de la instancia (p. ej., https://yourinstance.service-now.com) |
SN_USER | ✅* | — | Nombre de usuario de ServiceNow (autenticación básica / concesión de contraseña OAuth) |
SN_PASSWORD | ✅* | — | Contraseña de ServiceNow (autenticación básica / concesión de contraseña OAuth) |
SN_AUTH_TYPE | ❌ | basic | Esquema de autenticación: basic, oauth o apikey |
SN_CLIENT_ID | ❌ | — | ID de cliente OAuth (SN_AUTH_TYPE=oauth) |
SN_CLIENT_SECRET | ❌ | — | Secreto de cliente OAuth (SN_AUTH_TYPE=oauth) |
SN_GRANT_TYPE | ❌ | client_credentials | Concesión OAuth: client_credentials o password |
SN_API_KEY | ❌ | — | Clave de API (SN_AUTH_TYPE=apikey) |
SN_API_KEY_HEADER | ❌ | x-sn-apikey | Encabezado en el que se envía la clave de API |
SN_TIMEOUT_MS | ❌ | 30000 | Tiempo de espera por solicitud en milisegundos |
SN_DISPLAY_VALUE | ❌ | true | Modo de valor de visualización predeterminado (true, false, all) |
SN_REL_DEPTH | ❌ | 3 | Profundidad de recorrido de relaciones CMDB predeterminada |
*SN_PROFILE_NAME y SN_INSTANCE no son requeridas cuando se usa
~/.servicenow-mcp/config.json. Las variables específicas de autenticación dependen de
el tipo de autenticación seleccionado.
Ejemplos de uso
Una vez conectado, tu asistente de IA puede:
Consultar incidentes:
"En dev, muéstrame todos los incidentes P1 asignados al equipo de Red" (
profile: "dev")
Crear un registro:
"En staging, crea un incidente para la prueba de VPN aprobada" (
profile: "staging")
Agregar datos:
"En prod, ¿cuántos incidentes están agrupados por prioridad?" (
profile: "prod")
Verificar estado:
"Ejecuta la verificación de estado de la instancia dev" (
profile: "dev")
Recorrido CMDB:
"En prod, muestra las dependencias ascendentes de email-server-01" (
profile: "prod")
Introspección de esquema:
"En dev, ¿qué campos hay en change_request?" (
profile: "dev")
Búsqueda de código:
"En dev, encuentra reglas de negocio que referencien GlideRecord('incident')" (
profile: "dev")
Pruebas ATF:
"En staging, lista la suite ATF aprobada" (
profile: "staging")
Selección explícita de perfil:
"Consulta incidentes en dev" (el cliente envía
profile: "dev"en esa llamada)
El cliente debe traducir cada ejemplo en una invocación de herramienta que contenga ese
profile exacto; ninguna llamada previa crea un estado predeterminado, activo o de cambio de perfil.
Funciones de seguridad
Este servidor está diseñado para uso en producción con múltiples capas de seguridad:
- Las operaciones de eliminación requieren
confirm: trueexplícito - Las operaciones por lotes se ejecutan en modo de prueba en seco de forma predeterminada: muestran el recuento de coincidencias sin realizar cambios
- Las operaciones masivas requieren
confirm: truepara salir del modo de prueba en seco - La composición no clasificada se deniega —
sn_nly la ejecución de ATF no se ejecutan hasta que puedan emitir planes de acceso tipados completos - El acceso a tablas se deniega de forma predeterminada con listas de permitidos de lectura/escritura exactas independientes y denegaciones de tablas sensibles no configurables
- La entrada del usuario se neutraliza antes de la interpolación en consultas codificadas (
^se elimina de los valores de filtro: la sintaxis de consulta de ServiceNow no tiene secuencia de escape)
Desarrollo
Haz que el supervisor local aprobado o el llavero inyecten el secreto de autenticación de ServiceNow seleccionado antes de iniciar el proceso. Los comandos a continuación contienen solo configuración no secreta; nunca antepongas ni agregues valores protegidos en la línea de comandos.
# Clone
git clone https://github.com/onlyflowstech/servicenow-mcp.git
cd servicenow-mcp
# Install & build
npm install
npm run build
# Run the server directly, speaking stdio on this terminal's pipes
MCP_OWNER_ID=local-owner \
MCP_CLIENT_ID=local-client \
SN_ALLOWED_READ_TABLES=incident,problem,change_request \
SN_ALLOWED_WRITE_TABLES=incident,change_request \
SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]' \
SN_PROFILE_NAME=dev \
SN_INSTANCE=https://yourinstance.service-now.com \
SN_USER=your_user \
npm start
# Build and run with source maps for local development
MCP_OWNER_ID=local-owner \
MCP_CLIENT_ID=local-client \
SN_ALLOWED_READ_TABLES=incident,problem,change_request \
SN_ALLOWED_WRITE_TABLES=incident,change_request \
SN_TABLE_ACCESS_TARGETS='[{"table":"incident","kind":"canonical","tools":["sn_query","sn_get","sn_create","sn_update","sn_incident_add_comment","sn_incident_add_work_note","sn_delete","sn_batch"],"closureComplete":true,"relatedTables":["incident"]},{"table":"problem","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["problem"]},{"table":"change_request","kind":"canonical","tools":["sn_query","sn_get"],"closureComplete":true,"relatedTables":["change_request"]}]' \
SN_PROFILE_NAME=dev \
SN_INSTANCE=https://yourinstance.service-now.com \
SN_USER=your_user \
npm run dev
Pruebas con MCP Inspector
Usa la cadena de herramientas Inspector aislada y con bloqueo exacto en Node.js 22.19 o más reciente;
el servidor en sí sigue siendo compatible con Node.js 20. Configura el
MCP_PROFILE no secreto, instala desde tools/inspector/package-lock.json y ejecuta el
lanzador solo local:
MCP_PROFILE=dev npm run inspector
(Ejecuta npm ci --prefix tools/inspector --engine-strict --ignore-scripts primero).
El lanzador imprime el comando y los argumentos exactos de STDIO para ingresar en la
interfaz de Inspector. No hay endpoint ni token que escribir. Incluye el perfil
explícito en cada llamada. Inspector inicia el servidor por sí mismo y hereda un
entorno depurado con cada valor de MCP_* y SN_* eliminado; el servidor
aún resuelve su credencial, porque lee el
~/.servicenow-mcp/server.env de solo propietario al inicio en lugar de depender de lo que se le
entregó. El lanzador no expone Inspector más allá del loopback ni crea un
túnel.
npm run smoke es el segundo cliente. Inicia dist/index.js de la misma manera y
solo necesita MCP_PROFILE:
MCP_PROFILE=dev npm run smoke
Consulta docs/RELEASE-VALIDATION.md para las puertas de
lanzamiento, confirmación de escritura, evidencia y procedimiento de reversión.
Hoja de ruta
- Transporte stdio — el cliente inicia el servidor; existe un runtime HTTP Streamable pero está inactivo
- Soporte de autenticación OAuth 2.0 (concesiones client_credentials + password, claves de API)
- Ejecución de script en segundo plano sn_script (SNS-39) — estado futuro, deliberadamente no incluido en 2.0; requiere automatizar el endpoint de interfaz
sys.scripts.docon autenticación de sesión - Transmisión para conjuntos de resultados grandes
- Caché para búsquedas de esquema y relaciones
Licencia
MIT © OnlyFlows
Construido con ❤️ por OnlyFlows · @onlyflowstech