ServiceNow Incident Copilot

ServiceNow Incident Copilot

Enables conversational triage of ServiceNow incidents via Claude Desktop, automatically classifying and routing them based on company knowledge.

Category
访问服务器

README

ServiceNow Incident Copilot

CI Python 3.12 Code style: ruff

Zero-touch L1 incident triage: new incidents are automatically classified by Azure OpenAI, grounded in company knowledge embeddings, and routed to the right enterprise team in ServiceNow — no manual effort. Exposed as both a FastAPI service and an MCP server (connect it to Claude Desktop and triage incidents conversationally).

Live demo

▶ Live app: https://servicenow-incident-copilot.onrender.com/docs — interactive API docs (free tier; first load may take ~50s if asleep, then it's instant)

Mock-mode demo: six incidents auto-triaged and routed in one call, then the routing dashboard

The recording above is the real APP_MODE=mock pipeline — deterministic, credential-free, and exactly what CI runs.

Deploy to Render

Deployed in mock mode — the entire pipeline runs offline with a deterministic LLM and an in-memory ServiceNow, so no credentials are needed and nothing sensitive is exposed. Try it:

  • /docs — interactive Swagger UI; click "Try it out" on POST /demo/run-all to auto-triage six incidents
  • /stats — live routing-accuracy dashboard (JSON)

Hosted on Render's free tier, which sleeps after inactivity — the first request may take ~50s to wake, then it's instant. The GIF above is the same output with no wait.

Why I built this

I'm drawn to the intersection of ServiceNow and applied AI, and I wanted to see what "AI integration" should really look like inside an ITSM platform — not a chatbot bolted onto the side, but AI wired into the operational flow where it removes genuine toil. L1 triage is the ideal target: high-volume, repetitive, and every misroute burns an SLA. So instead of a demo snippet, I built the entire zero-touch loop the way I'd want to run it in production — webhook in, RAG-grounded decision, write-back with an audit note — and pushed on the parts that are easy to hand-wave and hard to get right:

  • It runs with zero credentials. The offline APP_MODE=mock stack implements the exact same interfaces as the live one (in-memory ServiceNow + a rule-based LLM double), so the pipeline can't tell the difference — and neither can pytest. I wanted anyone to be able to clone it and see it work in 60 seconds, and I wanted CI to exercise the real orchestration, not a stub.
  • The AI is accountable, not magic. The model can only route to teams in the catalog; a hallucinated team name zeros the confidence; anything under the threshold parks in a human queue with the full reasoning written to the incident's work note. I care more about trustworthy automation than a flashy accuracy number.
  • It's provider- and infra-agnostic on purpose. Swapping the LLM (Azure OpenAI ↔ OpenAI) or the vector store (in-memory ↔ ChromaDB ↔ Azure AI Search) is one env var, because everything depends on a protocol, not a concrete class. That's the difference between a proof-of-concept and something a team could actually adopt.

I built it in visible phases (see the commit history) — mock-first, then observability, then a second vector backend, then the MCP surface — because that's how I like to work: get a thin end-to-end slice running, then deepen it one honest layer at a time.

How the zero-touch pipeline works

 ServiceNow                    Incident Copilot (FastAPI)                ServiceNow
┌───────────┐  Business Rule  ┌─────────────────────────────────┐  PATCH  ┌───────────┐
│ Incident   │───(webhook)───▶│ 1. Fetch incident (Table API)     │───────▶│ assignment │
│ created    │                │ 2. Embed & retrieve:              │        │ _group set │
└───────────┘                │    • company KB articles           │        │ + priority │
                              │    • similar past incidents        │        │ + category │
                              │      (with historical routing)     │        │ + AI work  │
                              │ 3. Azure OpenAI triage             │        │   note     │
                              │    (forced function calling →      │        └───────────┘
                              │     Pydantic-validated output)     │
                              │ 4. Confidence gate:                │
                              │    ≥ 0.7 → auto-route              │
                              │    < 0.7 → park in L1 queue        │
                              └─────────────────────────────────┘

Design decisions worth noting:

  • One IncidentService layer serves both the REST API and the MCP tools — no duplicated logic.
  • The LLM tool schema is generated from the TriageResult Pydantic model, so the AI contract and app contract can't drift.
  • Guardrails, not vibes: the LLM can only route to teams in the catalog; hallucinated team names zero the confidence; low confidence falls back to a human queue with full reasoning in the work note.
  • Feedback loop: POST /learn/{sys_id} indexes resolved incidents back into the vector store, so routing accuracy improves with history.

Stack

FastAPI · Pydantic v2 · httpx (async) · OAuth 2.0 · ServiceNow Table API · Azure OpenAI (chat + embeddings, standard OpenAI fallback) · ChromaDB (swappable for Azure AI Search) · MCP (FastMCP) · Docker Compose · pytest + respx · GitHub Actions · structured JSON logging

Quick start

60-second demo, zero credentials (mock mode)

pip install -r requirements.txt
APP_MODE=mock uvicorn app.main:app --port 8000
curl -X POST localhost:8000/demo/run-all | jq

Six realistic incidents get triaged and routed instantly by a deterministic offline stack (in-memory ServiceNow + rule-based LLM double) that implements the exact same interfaces as the live one — the pipeline can't tell the difference.

Live mode (real PDI + Azure OpenAI)

cp .env.example .env          # fill in PDI + OpenAI credentials
pip install -r requirements.txt -r requirements-dev.txt
python -m scripts.seed_data --snow   # index KB + history, create demo incidents
uvicorn app.main:app --reload

Zero-touch setup: create the Business Rule + Outbound REST Message from integration/servicenow_business_rule.js (use ngrok http 8000 locally). Now every new incident routes itself.

Manual demo without the webhook:

curl -X POST localhost:8000/triage/<sys_id> | jq

Observability

Every request gets a correlation ID (honored from an inbound X-Correlation-ID header — e.g. propagated from MuleSoft — or minted fresh) that tags every log line in that incident's journey and is echoed back in the response header. Grep one cid to trace a single incident end to end.

GET /stats returns a live routing dashboard:

{
  "processed": 6, "auto_routed": 6, "auto_route_rate": 1.0,
  "low_confidence_fallbacks": 0, "avg_confidence": 0.84,
  "by_group": { "Network Operations": 1, "Security Operations": 1, ... },
  "by_priority": { "P1": 1, "P2": 3, "P3": 2 },
  "avg_stage_ms": { "retrieval": 0.6, "triage": 1.0, "writeback": 0.1 }
}

The auto_route_rate and per-group distribution are the metrics you'd watch to tune the confidence threshold. Counters map 1:1 onto Prometheus if real scraping is needed.

Swappable vector backend

Three implementations satisfy one VectorStore protocol (app/services/vector_store.py):

Backend VECTOR_BACKEND Used for
In-memory (cosine) (mock mode) zero-credential demo & tests
ChromaDB chroma (default) local live dev
Azure AI Search azure_ai_search production (HNSW vector search)

Switching is one env var — IncidentService never changes, because it depends on the protocol, not a concrete store. The Azure backend creates its indexes idempotently on startup and pushes our own text-embedding-3-small vectors, so retrieval quality is identical across backends. A test asserts all three expose the same method signatures.

MCP server (Claude Desktop)

Copy integration/claude_desktop_config.example.json into your Claude Desktop config (set the absolute cwd). With "APP_MODE": "mock" it works with zero credentials — flip to live once the PDI is wired.

Then ask Claude: "Triage the incident about the CEO gift card email and explain your routing" or "What are the routing stats for this session?"

A full 3-minute recording script lives in integration/DEMO_SCRIPT.md.

Docker

docker compose up --build

Tests

pytest -v    # ServiceNow mocked with respx, LLM mocked — no credentials needed

Enterprise topology (MuleSoft)

See integration/MULESOFT_DESIGN.md — API-led connectivity design with a servicenow-sapi System API owning credentials and policies. The client here is a one-file swap away from pointing at CloudHub.

Roadmap

  • Azure AI Search backend ✅ done — see VECTOR_BACKEND=azure_ai_search
  • Multi-turn clarification: agent asks the caller for missing details via chat/email
  • Routing accuracy dashboard (auto-routed vs. reassigned rate)

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选