Skip to main content
Glama
VajraM-dev

ServiceNow Incident MCP

by VajraM-dev
README.md
# ServiceNow Incident MCP

FastMCP server exposing 6 ServiceNow incident tools over streamable HTTP at `/mcp`.

The caller's bearer token is forwarded straight to ServiceNow — no credentials are stored
server-side, and every call runs under the ACLs of whoever the token belongs to.

| Tool | Purpose |
|---|---|
| `list_incidents` | search with a ServiceNow encoded query |
| `get_incident` | fetch by `INC…` number or sys_id, with the journal thread |
| `create_incident` | new incident |
| `update_incident` | patch arbitrary fields |
| `add_comment` | append a work note or customer comment |
| `resolve_incident` | state=6 + close_code + close_notes in one write |

## Run it

```bash
uv sync
uv run --env-file .env server.py          # http://localhost:8000/mcp
```

Or in a container:

```bash
docker build -t servicenow-mcp .
docker run -p 8000:8000 -e SERVICENOW_INSTANCE_URL=https://dev12345.service-now.com servicenow-mcp
```

Call it with `Authorization: Bearer <servicenow-oauth-token>`:

```bash
eval "$(uv run --env-file .env login.py)"   # browser login, returns a token
SERVICENOW_TOKEN=$SERVICENOW_TOKEN uv run test_client.py
```

`.env` needs `SERVICENOW_INSTANCE_URL`, plus `SN_CLIENT_ID` / `SN_CLIENT_SECRET` for `login.py`.
The server itself only reads `SERVICENOW_INSTANCE_URL`.

## Test

```bash
uv run test_server.py    # offline self-check: token extraction, path-traversal rejection
```

## Docs

```bash
uv run --group docs mkdocs serve -a 127.0.0.1:8001
```

Covers the passthrough pattern, ServiceNow setup and its traps, the tool reference, troubleshooting,
design decisions, and a build log.

## Branches

- `master` — this: a plain HTTP MCP server, no cloud coupling
- `bedrock-agentcore` — a working deployment to AWS Bedrock AgentCore Runtime, with IAM SigV4
  inbound auth and one-command teardown
- `jwt-inbound-auth` — an experiment in using the ServiceNow token as the AgentCore inbound JWT.
  It does not work, and the branch records why