Skip to content

Client/CLI lacks support for extra request headers (e.g. x-adcp-tenant) #583

@bokelley

Description

@bokelley

Problem

Neither AgentConfig (Python SDK) nor uvx adcp (CLI) exposes a way to send arbitrary request headers alongside auth_token. This blocks any caller that needs to pass routing/context headers in addition to the bearer token.

Concrete use case

In salesagent (PSA reference impl), the verify scripts target a localhost server that resolves tenant via the 4-strategy chain in src/core/resolved_identity.py:

  1. Host header → virtual host / subdomain
  2. x-adcp-tenant header
  3. Apx-Incoming-Host header
  4. localhost fallback → \"default\" tenant

When a verify script provisions a fresh test tenant on http://localhost:8000, strategy 1 fails (Host is localhost), so it must send x-adcp-tenant: <provisioned_id> to route to the right tenant. The SDK has no way to do this:

# Today (custom transport works because fastmcp.client accepts a `headers` dict):
from fastmcp.client import Client
from fastmcp.client.transports import StreamableHttpTransport
transport = StreamableHttpTransport(
    url=\"http://localhost:8000/mcp/\",
    headers={\"x-adcp-auth\": token, \"x-adcp-tenant\": tenant_id},
)

# Migrating to the adcp SDK — no equivalent:
from adcp.client import ADCPClient, AgentConfig
config = AgentConfig(
    id=\"verify\",
    agent_uri=\"http://localhost:8000/mcp/\",
    protocol=Protocol.MCP,
    auth_token=token,
    auth_header=\"x-adcp-auth\",
    # ❌ No `headers={\"x-adcp-tenant\": tenant_id}` parameter
)

CLI side has the same gap

$ uvx adcp http://localhost:8000/mcp/ get_products '{...}' --auth TOKEN
# ❌ No --header / -H flag to add x-adcp-tenant

Why this matters for adopters

  • Multi-tenant decisioning platforms behind nginx commonly use a tenant header for path-based routing.
  • Reverse-proxy setups (Cloudflare Workers / Apx-Incoming-Host) need pass-through headers.
  • Test/verify scripts can't migrate from fastmcp.client to the SDK without losing functionality.

Proposed fix

SDK

Add headers: Mapping[str, str] | None = None to AgentConfig. Merge into the request headers after auth_header/auth_token are set, so the SDK retains control of auth but adopters can layer routing/context headers.

config = AgentConfig(
    ...,
    auth_token=token,
    headers={\"x-adcp-tenant\": tenant_id},
)

CLI

Add --header KEY=VALUE (repeatable) to uvx adcp and the --save-auth agent config schema:

adcp <agent> get_products '{...}' --auth TOKEN --header x-adcp-tenant=acme --header x-foo=bar

Persist via --save-auth:

{
  \"agents\": {
    \"local\": {
      \"url\": \"http://localhost:8000/mcp\",
      \"protocol\": \"mcp\",
      \"auth_token\": \"...\",
      \"headers\": {\"x-adcp-tenant\": \"acme\"}
    }
  }
}

Acceptance criteria

  • AgentConfig(headers=...) is plumbed through both the MCP and A2A adapters.
  • uvx adcp --header K=V ... works for ad-hoc invocations.
  • ~/.adcp/config.json per-agent headers field is honored on saved agents.
  • Headers do NOT clobber the auth header; auth wins on conflict (with a warning).

Related

  • Companion issue filed against the JS/TS CLI in adcontextprotocol/adcp-client (same gap).
  • salesagent migration tracking: replacing fastmcp.client direct calls with the SDK — currently blocked on this for verify scripts that hit localhost with x-adcp-tenant.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions