Skip to content

HTTP MCP server enters error state on startup; tools never advertised to Copilot CLI (Unwrap MCP repro) #4418

@cmcnally

Description

@cmcnally

Symptom

Custom HTTP MCP server connects per the post-startup probe (✓ <name>: connected) but the gateway's own health endpoint reports status: error. Downstream Copilot CLI receives no tools from that server, even though built-in safeoutputs and github MCPs work fine.

Reproduction

mcp-servers: block in the workflow markdown (gh-aw v0.68.3, gh-aw-mcpg v0.2.19):

mcp-servers:
  unwrap:
    type: http
    url: https://nlp.api.production.unwrap.ai/mcp
    headers:
      Authorization: "Bearer ${{ secrets.UNWRAP_API_TOKEN }}"
    allowed:
      - list_views
      - get_started
      - search_actionable_groups
      # ...

The same config (URL + Bearer token) works against the same Unwrap MCP server when used directly with Copilot CLI on a developer machine via ~/.copilot/mcp-config.json.

Gateway log evidence

Within ~80ms of gateway startup:

Health response body: {"status":"unhealthy","specVersion":"1.9.0","gatewayVersion":"v0.2.19","servers":{"github":{"status":"running","uptime":2},"safeoutputs":{"status":"running","uptime":2},"unwrap":{"status":"error","uptime":0}}}

Then the converter's connectivity check passes anyway:

Attempting connection (timeout: 10s)...
✓ unwrap: connected
TIMING: Server check for unwrap took 73ms

So the persistent server registration is in error state, but a one-shot probe succeeds. Copilot CLI subsequently advertises only github-* and safeoutputs-* tools to the model; no unwrap-* tools appear in the model's tool inventory.

Run logs

Three real runs in github/customer-intel:

In each, Opus (claude-opus-4.6, id: copilot) calls safeoutputs-report_incomplete because the unwrap tools are absent from its inventory. Same outcome with allowed: ["*"] and with an explicit allowlist of 12 tool names.

Likely cause

Gateway's HTTP MCP transport implementation handshakes differently from what the Unwrap MCP server expects. Possibly related to #23153 (Streamable HTTP session tracking).

Workaround being used

Falling back to direct bash + curl against http://host.docker.internal:80/mcp/<server> from inside the workflow, bypassing Copilot CLI's MCP layer entirely.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions