15 -- Interceptor Discovery

Prerequisite: 14 -- Upgrade: Digest Pinning You will need: Docker, curl, jq Time: 10 minutes Adds: SEP-1763 interceptor discovery client checks

The Problem

MCP Hangar exposes its validator and mutator capabilities through /interceptors/list. Clients can use this endpoint to discover what Hangar can validate or mutate before sending traffic through it.

The interceptor framework shipped in v1.2.0, and since v1.2.1 the two interceptor entries have distinct names:

  • mcp-hangar-validator
  • mcp-hangar-mutator

If your client still assumes one shared mcp-hangar name, it can overwrite one entry with the other or fail uniqueness validation.

The Config

Create a minimal config for a local Docker smoke test:

mkdir -p /tmp/hangar-interceptors
printf 'mcp_servers: {}\n' > /tmp/hangar-interceptors/config.yaml

No MCP servers are required. /interceptors/list describes Hangar itself.

Try It

  1. Start Hangar in HTTP mode

    docker run -d --name hangar-interceptors \
      -p 127.0.0.1:8000:8000 \
      -v /tmp/hangar-interceptors/config.yaml:/config.yaml:ro \
      python:3.11-slim sh -lc '
        pip install --quiet "mcp-hangar>=1.3.0" &&
        mcp-hangar --config /config.yaml serve \
          --http --host 0.0.0.0 --port 8000 --unsafe-no-auth
      '

    --unsafe-no-auth is only for this local smoke test. Do not use it for a production deployment.

  2. Wait for readiness

    until curl -fsS http://localhost:8000/health/ready 2>/dev/null; do sleep 2; done

    Expected output:

    {"status":"healthy","ready_mcp_servers":0,"total_mcp_servers":0}
  3. Fetch interceptor capabilities

    curl -s http://localhost:8000/interceptors/list | jq

    Expected output:

    {
      "interceptors": [
        {
          "name": "mcp-hangar-validator",
          "version": "1.4.0",
          "type": "validator",
          "supportedEvents": ["tools/call", "tools/list"],
          "modes": ["audit", "enforce"],
          "trustBoundary": "host"
        },
        {
          "name": "mcp-hangar-mutator",
          "version": "1.4.0",
          "type": "mutator",
          "supportedEvents": ["tools/call"],
          "modes": ["enforce"],
          "trustBoundary": "host"
        }
      ]
    }
  4. Verify names are unique

    curl -s http://localhost:8000/interceptors/list | jq -e '
      .interceptors as $items |
      ($items | length) == ($items | map(.name) | unique | length)
    '

    Expected output:

    true
  5. Build a lookup table by interceptor name

    curl -s http://localhost:8000/interceptors/list | jq '
      .interceptors | map({key: .name, value: .}) | from_entries | keys
    '

    Expected output:

    [
      "mcp-hangar-mutator",
      "mcp-hangar-validator"
    ]
  6. Check the capabilities your client needs

    curl -s http://localhost:8000/interceptors/list | jq -e '
      any(.interceptors[];
        .name == "mcp-hangar-validator" and
        .type == "validator" and
        (.supportedEvents | index("tools/list")) and
        (.modes | index("audit"))
      )
    '

    Expected output:

    true
  7. Stop the smoke-test container

    docker rm -f hangar-interceptors

What Just Happened

/interceptors/list returns a list of Hangar interceptor instances. Since v1.2.1 the validator and mutator entries use different names so SEP-1763 clients can treat them as separate capabilities.

The important client rule is: key interceptors by name, then validate the fields you care about (type, supportedEvents, and modes). Do not collapse all Hangar entries into a single hard-coded mcp-hangar record.

Key Config Reference

No config keys are required for discovery. The endpoint is exposed by the HTTP server when Hangar runs in HTTP mode.

FieldMeaning
nameUnique interceptor instance name
versionMCP Hangar package version
typeInterceptor role, such as validator or mutator
supportedEventsMCP event names the interceptor handles
modesSupported operation modes
trustBoundaryWhere the interceptor runs relative to the client

What's Next

Use this check in integration tests for clients that consume SEP-1763 metadata. For implementation details, see Interceptor Framework.