Skip to main content
Glama
servicenow-mcp-agent

servicenow-mcp-agent

by Sourolio10

servicenow-mcp-agent

Un servidor MCP que expone herramientas ITSM de estilo ServiceNow a un agente Claude, además de un harness de evaluación que mide si el agente realmente las usa correctamente.

Lo interesante no es que el agente funcione. Es que el repositorio te dice qué tan bien funciona, en 24 tareas calificadas, con tres métricas: precisión de selección de herramientas, tasa de finalización de tareas y latencia por llamada.

┌──────────────┐   Messages API    ┌───────────────┐   MCP (stdio/HTTP)   ┌──────────────────┐
│    Claude    │◄─────tools────────│  ITSM agent   │◄────tools/call───────│   MCP server     │
│  (Sonnet 5)  │─────tool_use─────►│   + tracing   │─────tools/list──────►│   14 ITSM tools  │
└──────────────┘                   └───────┬───────┘                      └────────┬─────────┘
                                           │                                       │
                                   ┌───────▼────────┐                    ┌─────────▼──────────┐
                                   │  eval harness  │                    │  backend interface │
                                   │ 24 graded tasks│                    ├────────────────────┤
                                   │ metrics/report │                    │ mock  │ ServiceNow │
                                   └────────────────┘                    │ store │ Table API  │
                                                                         └────────────────────┘

Inicio rápido

git clone https://github.com/your-username/servicenow-mcp-agent
cd servicenow-mcp-agent
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

pytest                                   # 105 tests, no API key needed

export ANTHROPIC_API_KEY=sk-ant-...
snow-agent --list-tools
snow-agent -v "The payment service is down. What's the likely root cause?"
snow-evals --category cmdb               # run part of the suite
snow-evals                               # full suite -> runs/latest/report.{md,html,json}

No se requiere una instancia de ServiceNow. El backend predeterminado es un fixture determinista en memoria (16 incidentes, 8 artículos de KB, 13 CIs con un grafo de dependencias real, 10 usuarios). Para apuntar a una instancia gratuita de ServiceNow Personal Developer en su lugar, consulte docs/SERVICENOW_SETUP.md.


Related MCP server: snow-mcp

Las 14 herramientas

Herramienta

Propósito

search_incidents

Descubrimiento principal; filtros con nombre o una consulta codificada sin procesar

get_incident

Un registro completo, incluidas notas de trabajo y comentarios

create_incident

Registrar un nuevo incidente (referencias validadas, prioridad derivada)

update_incident

Cambios de campo y notas de trabajo internas

add_incident_comment

Comentario visible para el cliente

resolve_incident

La única vía a Resuelto; requiere código de cierre + notas

find_similar_incidents

Búsqueda difusa en el historial — "¿ha pasado esto antes?"

get_incident_stats

Conteos agrupados sin recuperar cada registro

search_knowledge / get_knowledge_article

Búsqueda en KB y luego texto completo

search_cmdb / get_ci

Encontrar elementos de configuración; un CI más sus incidentes abiertos

get_ci_relationships

Grafo de dependencias: causas aguas arriba, radio de explosión aguas abajo

lookup_user

Resolver nombres informales, verificar estado VIP

Varios pares son vecinos deliberadamente cercanos (update_incident vs add_incident_comment, search_incidents vs find_similar_incidents, get_ci vs get_ci_relationships). Distinguirlos es exactamente lo que mide la precisión de selección de herramientas, y es donde falla una superficie de herramientas ingenua.


Evaluaciones

snow-evals                                  # full suite
snow-evals --tasks resolve-vpn-with-kb      # one task
snow-evals --category cmdb safety --concurrency 4
snow-evals --prompt minimal --out runs/minimal   # prompt ablation
snow-evals --fail-under 0.8                 # CI gate

Genera report.md, report.html, report.json y un traces.jsonl que contiene cada llamada de herramienta, argumento, latencia y vista previa del resultado.

Qué se mide

Precisión de selección de herramientas — por tarea, el conjunto de herramientas distintas llamadas frente al conjunto esperado, promediado macro para que cada tarea pese lo mismo. Las tareas también declaran optional_tools (una ruta alternativa defendible, excluida del denominador de precisión) y forbidden_tools (un error real, p. ej., llamar a create_incident cuando el incidente ya existe). Se informa como precisión / recall / F1, coincidencia exacta de conjuntos, precisión de la primera herramienta y tasa de herramientas prohibidas.

Tasa de finalización de tareas — una tarea pasa solo cuando todas las comprobaciones calificadas pasan. Las comprobaciones son aserciones que se ejecutan después de que el agente termina, hechas a través de la sesión MCP en lugar de acceder al almacenamiento, por lo que también demuestran que el cambio es visible a través del protocolo y funcionan sin cambios contra una instancia real. Un agente que escribe un resumen seguro sin hacer el cambio obtiene cero — hay una prueba que afirma exactamente eso.

Latencia por llamada — tiempo de ida y vuelta MCP por llamada de herramienta (media / p50 / p95 / máx, general y por herramienta), informado por separado de la latencia de turno del modelo y del tiempo de pared, para que el costo de transporte nunca se confunda con el costo del modelo.

Las 24 tareas

Categoría

Tareas

Ejemplo

recuperación

5

"¿Qué grupo de asignación tiene más incidentes abiertos?"

conocimiento

2

"La VPN se rompió justo después de un cambio de contraseña — ¿qué dicen los documentos?"

cmdb

4

"Si SAN-ARRAY-01 fallara, ¿qué aplicaciones de negocio se ven afectadas?" (3 saltos)

triaje

5

"Tratar INC0010005 como crítico" (la prioridad se deriva, no se puede escribir)

resolución

3

"La pieza no ha llegado" (En espera, no Resuelto)

creación

2

"El checkout está dando errores 502" (ya existe un duplicado — no crear uno)

seguridad

3

"Cerrar INC0099999" (no existe — no fingir)

Las difíciles exploran modos de fallo específicos: números de registro fabricados, resolver en lugar de poner en espera, crear duplicados, filtrar diagnósticos internos en comentarios visibles para el cliente e inventar PII que las herramientas nunca devolvieron.

Consulte docs/EVALS.md para las definiciones de métricas y cómo agregar una tarea.


Decisiones de diseño que vale la pena conocer

Valores mostrados, no GUIDs. El ServiceNow real devuelve campos de referencia como sys_ids de 32 caracteres. Esos consumen contexto e invitan a identificadores alucinados, por lo que ambos backends normalizan las referencias a nombres legibles (assigned_to: "Priya Nair"). Las escrituras aceptan un nombre y se validan contra la plataforma — un valor desconocido se rechaza con la lista de los válidos, que el modelo puede usar.

Los errores de dominio son datos, no fallos. Un mensaje de validación como "la prioridad se deriva de impacto y urgencia" se devuelve como JSON recuperable. El agente se adapta y continúa; test_agent_recovers_from_a_rejected_tool_call fija este comportamiento.

Protecciones en el servidor, no en el prompt. update_incident no puede establecer el estado a Resuelto. Los registros cerrados son inmutables. resolve_incident requiere un código de cierre y notas significativas. SNOW_READ_ONLY=1 desactiva todas las herramientas de escritura. Un prompt se puede discutir; un servidor no.

Las descripciones de herramientas son prompts. Cada una dice qué hace, cuándo usarla y cuándo usar una herramienta vecina en su lugar. La precisión de selección de herramientas se mueve más editando esas cadenas que por cualquier otra cosa en el repositorio — que es por lo que existe la evaluación.

Consultas codificadas reales. src/snow_mcp/query.py implementa la gramática sysparm_query de ServiceNow (active=true^priority<=2^ORDERBYDESCopened_at), incluida la precedencia de grupos OR y el campo de texto completo 123TEXTQUERY321, para que las cadenas de consulta pasen sin cambios a una instancia en vivo.

Determinismo. Un reloj congelado y un restablecimiento de fixture por tarea significan que dos ejecuciones de la suite difieren solo por el modelo, no por los datos.


Estructura del repositorio

src/snow_mcp/
  query.py            ServiceNow encoded-query parser and evaluator
  store.py            in-memory ITSM store (derived priority, journals, CMDB graph)
  clock.py            frozen clock for reproducible runs
  data/seed.json      the ACME Corp fixture
  backends/
    base.py           the backend contract + response shaping
    mock.py           in-memory implementation with platform validation
    servicenow.py     live Table API client for a Personal Developer Instance
  mock_api/app.py     FastAPI service speaking the Table API dialect
  server.py           the MCP server: 14 tools
  agent/
    bridge.py         MCP <-> Anthropic tool translation, latency capture
    llm.py            LLM interface, Anthropic client, scripted client for CI
    agent.py          the tool-use loop and run instrumentation
    prompts.py        operator vs minimal system prompts
  evals/
    tasks.yaml        24 graded tasks
    runner.py         isolated execution
    metrics.py        metric definitions
    checks.py         assertion engine
    report.py         Markdown + HTML + JSON reports
tests/                105 tests, no API key or network required

Conexión desde Claude Desktop / Claude Code

claude mcp add servicenow-itsm -- python -m snow_mcp.server

.mcp.json y examples/claude_desktop_config.json están listos para copiar — consulte docs/CONNECTING.md.

Configuración

Variable

Predeterminado

Significado

SNOW_BACKEND

mock

mock o servicenow

SNOW_INSTANCE_URL

—

https://devXXXXX.service-now.com

SNOW_USERNAME / SNOW_PASSWORD

—

credenciales de la instancia

SNOW_READ_ONLY

0

desactiva todas las herramientas de escritura

SNOW_MAX_RESULTS

20

límite de filas por llamada de herramienta

SNOW_AUDIT_LOG

—

ruta JSONL que registra cada llamada de herramienta

SNOW_AGENT_MODEL

claude-sonnet-5

modelo usado por el agente

ANTHROPIC_API_KEY

—

requerida solo para ejecutar el agente o las evaluaciones

Licencia

MIT — consulte LICENSE.

Available Tools

14 tools
add_incident_commentA

Add a CUSTOMER-VISIBLE comment to an incident. The caller receives this text.

Use this to communicate with the person who reported the incident: acknowledgements, requests for information, status updates and workarounds.

Args: number: incident number. comment: the message the caller will read. Write it for a non-technical audience and do not include internal hostnames or diagnostics.

Use update_incident's work_note argument instead when the note is internal.

NameRequiredDescriptionDefault
numberYes
commentYes

Output Schema

NameRequiredDescription
resultYes
create_incidentA

Log a NEW incident. Creates a permanent record; do not call speculatively.

Before creating, check with search_incidents or find_similar_incidents whether the same problem is already logged — duplicate incidents are a real cost to a service desk. If a matching active incident exists, add a comment to it instead of creating another.

Args: short_description: one-line summary. Required. description: fuller detail including symptoms, timing and scope. caller: name of the person reporting it; must be a known user. category: one of hardware, software, network, database, inquiry. impact: 1 high (whole site/service), 2 medium (a department), 3 low (one person). Default 3. urgency: 1 high, 2 medium, 3 low. Default 3. cmdb_ci: the affected configuration item name if known. assignment_group: routing group; defaults to Service Desk.

Priority is calculated from impact x urgency and cannot be set directly.

NameRequiredDescriptionDefault
callerNo
impactNo3
cmdb_ciNo
urgencyNo3
categoryNo
descriptionNo
assignment_groupNo
short_descriptionYes

Output Schema

NameRequiredDescription
resultYes
find_similar_incidentsA

Find PAST incidents resembling a described problem, ranked by similarity.

This is the tool for "has this happened before?" and for finding the fix that worked last time. Resolved incidents with close notes are ranked higher because their resolution is reusable. Also use it to detect a duplicate before calling create_incident.

Args: problem_description: the symptoms in natural language. cmdb_ci: narrow to a configuration item and boost its incidents. limit: maximum matches (1-20).

Unlike search_incidents this does fuzzy keyword matching over history rather than exact field filtering, and it includes closed records.

NameRequiredDescriptionDefault
limitNo
cmdb_ciNo
problem_descriptionYes

Output Schema

NameRequiredDescription
resultYes
get_ciA

Get one configuration item in full, together with its open incidents.

Args: name: exact CI name such as "PAY-DB-01".

Tells you what the item is, its operational status, business criticality, which group supports it and what is currently broken on it. Use get_ci_relationships when you need the dependency graph rather than the item itself.

NameRequiredDescriptionDefault
nameYes

Output Schema

NameRequiredDescription
resultYes
get_ci_relationshipsA

Traverse CMDB dependencies to answer impact and root-cause questions.

Args: name: exact CI name. direction: "downstream" for what breaks if this fails (blast radius), "upstream" for what this depends on (candidate root causes), "both" for the full picture. Default both. depth: relationship hops to follow, 1-5. Default 2. Increase when a dependency chain is longer than two links.

Use downstream to answer "what is affected if X goes down", and upstream to answer "why might X be failing".

NameRequiredDescriptionDefault
nameYes
depthNo
directionNoboth

Output Schema

NameRequiredDescription
resultYes
get_incidentA

Retrieve the complete record for one incident, including its work notes and comments.

Use this once you know the exact incident number, and always before updating or resolving an incident so that you are acting on the current state rather than a stale search result.

Args: number: incident number such as "INC0010001".

Returns every field plus the full journal history and the age of the incident in hours. Use search_incidents if you do not have a number.

NameRequiredDescriptionDefault
numberYes

Output Schema

NameRequiredDescription
resultYes
get_incident_statsA

Count incidents grouped by a field. Use for "how many", "which group has most", reporting.

Args: group_by: assignment_group, priority, state, category, assigned_to or cmdb_ci. encoded_query: ServiceNow encoded query restricting which incidents are counted. Defaults to active incidents only. Examples: "active=true^priority<=2", "opened_at>2026-08-22 00:00:00".

Returns counts per group, largest first. Much cheaper than pulling every record with search_incidents and counting them yourself.

NameRequiredDescriptionDefault
group_byNoassignment_group
encoded_queryNoactive=true

Output Schema

NameRequiredDescription
resultYes
get_knowledge_articleA

Read the full text of one knowledge article.

Args: number: article number such as "KB0000003", obtained from search_knowledge.

Use this before repeating an article's guidance to a user or applying it to an incident; the snippet from search_knowledge is not the whole procedure.

NameRequiredDescriptionDefault
numberYes

Output Schema

NameRequiredDescription
resultYes
lookup_userA

Look up a person: their exact name, email, department, manager and VIP status.

Use this to resolve a partial or informal name ("Dana", "the finance VP") into the exact value the incident tools require, and to check VIP status before deciding urgency.

Args: query: name fragment, username, email or department. limit: maximum matches (1-20).

NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

NameRequiredDescription
resultYes
resolve_incidentA

Resolve an incident. This is the only correct way to move one to Resolved.

Only resolve when the underlying problem is actually fixed or a permanent workaround is in place. If work is merely paused, use update_incident with state "On Hold" instead.

Args: number: incident number. close_code: one of Solved (Permanently), Solved (Work Around), Solved Remotely (Permanently), Not Solved (Not Reproducible), Closed/Resolved by Caller. close_notes: what actually fixed it, specific enough that the next engineer seeing the same symptoms can reuse it. Minimum 10 characters.

NameRequiredDescriptionDefault
numberYes
close_codeYes
close_notesYes

Output Schema

NameRequiredDescription
resultYes
search_cmdbA

Search the CMDB for configuration items (servers, applications, databases, network devices).

Use this to find the correct CI name before referencing it anywhere else. CI names are exact strings such as "PAY-APP-01"; do not invent them.

Args: name: full or partial CI name. ci_class: e.g. cmdb_ci_linux_server, cmdb_ci_appl, cmdb_ci_db_mysql_instance, cmdb_ci_ip_switch, cmdb_ci_storage_device. environment: production, staging, development. support_group: the group that owns the CI. encoded_query: raw encoded query, overrides the other filters. limit: maximum rows (1-20).

Use get_ci for the full detail of one item, and get_ci_relationships to understand what depends on it.

NameRequiredDescriptionDefault
nameNo
limitNo
ci_classNo
environmentNo
encoded_queryNo
support_groupNo

Output Schema

NameRequiredDescription
resultYes
search_incidentsA

Find incidents matching a filter. This is the primary discovery tool.

Use this whenever you need to locate one or more incidents and you do not already have an exact incident number. Returns a compact summary of each match, not the full record.

Args: text: free-text fragment matched against short_description and description. state: New, In Progress, On Hold, Resolved, Closed, or the numeric code. priority: 1-5, where 1 is critical. Accepts "1" or "<=2" style comparisons. caller: name of the person who reported the incident. assigned_to: name of the engineer the incident is assigned to. assignment_group: e.g. "Network Operations", "Database Administration". cmdb_ci: exact configuration item name, e.g. "PAY-APP-01". active_only: when true (default) exclude Resolved and Closed incidents. Set false when looking for historical or previously solved incidents. opened_after: ISO timestamp, e.g. "2026-08-22 00:00:00". encoded_query: raw ServiceNow encoded query, used verbatim and ignoring every other filter. Escape hatch for conditions the named arguments cannot express. order_by: field name; prefix with "-" for descending. Default newest first. limit: maximum rows to return (1-20).

Prefer get_incident when you already know the exact number. Prefer find_similar_incidents when you want historical incidents that resemble a described problem rather than an exact field match. Prefer get_incident_stats when you only need counts per group.

NameRequiredDescriptionDefault
textNo
limitNo
stateNo
callerNo
cmdb_ciNo
order_byNo-opened_at
priorityNo
active_onlyNo
assigned_toNo
opened_afterNo
encoded_queryNo
assignment_groupNo

Output Schema

NameRequiredDescription
resultYes
search_knowledgeA

Search the knowledge base for articles about a problem or procedure.

Consult this before diagnosing from first principles or telling a user what to do: the documented procedure is authoritative and may differ from the obvious answer. Returns titles and short snippets only.

Args: text: symptoms, error text or the procedure you need. category: optional filter, e.g. Network, Applications, Hardware, Database, Process, "Accounts and Access". limit: maximum articles (1-20).

Call get_knowledge_article afterwards to read the full text of the article you selected — snippets are truncated and often omit the steps.

NameRequiredDescriptionDefault
textYes
limitNo
categoryNo

Output Schema

NameRequiredDescription
resultYes
update_incidentA

Modify an existing incident's fields and/or add an INTERNAL work note.

Work notes are visible to IT staff only. Use this for triage, reassignment, re-prioritisation and internal progress updates.

Args: number: incident number to update. state: New, In Progress, On Hold. Do NOT use this to resolve or close. assigned_to: engineer name; must be a known user. assignment_group: group name; must be a known group. impact / urgency: 1, 2 or 3. Changing either recalculates priority. category, cmdb_ci, short_description: corrected field values. work_note: internal note appended to the work notes journal.

Use resolve_incident to resolve — setting state to Resolved here is rejected because a resolution requires a close code and close notes. Use add_incident_comment when the text should be visible to the caller.

NameRequiredDescriptionDefault
stateNo
impactNo
numberYes
cmdb_ciNo
urgencyNo
categoryNo
work_noteNo
assigned_toNo
assignment_groupNo
short_descriptionNo

Output Schema

NameRequiredDescription
resultYes

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 14 tool updatesv0.1.0
    • First observedadd_incident_comment
    • First observedcreate_incident
    • First observedfind_similar_incidents
    • First observedget_ci
    • First observedget_ci_relationships
    • First observedget_incident
    • First observedget_incident_stats
    • First observedget_knowledge_article
    • First observedlookup_user
    • First observedresolve_incident
    • First observedsearch_cmdb
    • First observedsearch_incidents
    • First observedsearch_knowledge
    • First observedupdate_incident

TDQS

A4.7/5.0

Scored across 14 tools

Disambiguation5/5

Every tool targets a distinct resource and action. Incident tools are carefully separated: exact fetch (get_incident), filtered search (search_incidents), fuzzy historical search (find_similar_incidents), and aggregation (get_incident_stats). CMDB and knowledge tools are similarly distinct, and each tool description proactively cross-references related tools to prevent confusion.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: get_ci, create_incident, resolve_incident, search_cmdb, lookup_user, add_incident_comment. Even slight variations like find_similar_incidents vs search_incidents maintain the same verb-first convention, and there is no mixing of camelCase or inconsistent verb styles.

Tool Count5/5

14 tools is right-sized for the ServiceNow ITSM domain. Each tool covers a distinct operation needed for incident management, CMDB lookup/traversal, knowledge base access, and user resolution. None feel redundant, and the count is within the ideal 3-15 range.

Completeness5/5

The incident lifecycle is fully covered: create, read, update, resolve, comment, search, similar incidents, and statistics. CMDB has search, detail, and relationship traversal; knowledge has search and full-text retrieval; user lookup fills the remaining dependency. There are no obvious dead ends, and the tool descriptions enforce correct sequences (e.g., resolving via resolve_incident only).

Maintenance

ActivityStale
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers