Skip to main content

Responses Proxy dashboard

The Responses console is implemented in the Morph Cloud frontend at the Responses page. It presents a provider registry with Providers, Metrics, and Proxy Keys tabs, plus Claude Code BYOS setup controls when enabled. The browser never calls the backend proxy service directly for admin workflows. Instead, it calls same-origin BFF routes that obtain Morph service delegation auth server-side and forward safe requests to the backend.

Topology

Browser -> Morph Cloud BFF (/api/responses/*) -> agent-responses-proxy -> provider upstreams

This means:

  • no browser-held admin credential
  • no CORS requirement for the backend service
  • admin calls use Morph org auth or service delegation, never a static proxy token
  • data-plane calls still require an org-scoped proxy key
  • the backend injects provider credentials only after alias and org resolution

What the dashboard shows

Use the dashboard to manage and inspect:

  • registered providers
  • provider credential rows
  • model, agent, and compound-agent aliases
  • org-scoped proxy keys
  • live resources and routing state
  • request and decision history
  • metrics such as requests per minute, active sessions, and total requests
  • provider health and routability

Backend data sources

The BFF calls these backend endpoints:

  • GET /admin/providers
  • GET /admin/provider-presets
  • GET|POST|PATCH|DELETE /admin/providers/{provider_id}/credentials
  • POST /admin/providers/{provider_id}/credentials/{credential_id}/validate
  • GET /admin/models
  • POST /admin/models/test
  • GET /admin/keys
  • GET /admin/state
  • GET /admin/events
  • GET /admin/overview
  • GET /admin/metrics
  • GET /admin/requests
  • GET /admin/decisions
  • GET /admin/routing
  • POST|GET|DELETE /admin/claude-code/oauth/sessions

All of these backend calls require Morph admin bearer auth. The BFF sends X-Morph-Org-Id for the active organization.

Provider setup flow

The dashboard can create providers and aliases. A normal setup flow is:

  1. Load provider presets from /admin/provider-presets.
  2. Validate unsaved provider settings with /admin/providers/test.
  3. Save the provider through /admin/providers.
  4. Add or reference one or more provider credentials through /admin/providers/{provider_id}/credentials.
  5. Validate the stored credential and upstream model id.
  6. For Claude Code, choose the matching compatibility profile, review media/tool toggles, and run the alias test against the claude_code surface.
  7. Save the alias through /admin/models.
  8. Confirm /admin/routing includes the provider resource and alias.
  9. Mint a proxy key from the Proxy Keys tab or /admin/keys before sending data-plane traffic.

After a provider or alias mutation, the backend refreshes the current process immediately. Other replicas refresh from SQL within PROXY_ROUTING_REFRESH_INTERVAL_SECONDS.

The provider and credential forms accept $NAME in the API-key field as an organization secret reference. The BFF validates that the org secret exists and forwards credential_ref=env:NAME; raw secret values are not stored in SQL. Stored credential rows are the preferred BYOS path because they can be rotated or deleted without changing aliases.

Claude Code BYOS setup

The model-alias editor includes a Claude Code profile selector and expandable Compatibility settings. Auto resolves the profile from the selected provider protocol. The explicit options are Anthropic native, OpenAI Responses, and OpenAI Chat; the console only offers profiles valid for the provider wire_api.

These controls appear only for anthropic_messages, responses, and chat_completions. Custom protocols retain the normal Responses model test and do not submit unsupported Claude capability metadata.

Compatibility toggles control alias discovery and request validation for Claude Code, images, documents, client tools, parallel tools, and hosted web search. All Boolean fields default on; hosted web search defaults off and is disabled for Chat Completions. Saving writes these values under capabilities.claude_code without replacing unrelated model capabilities such as Anthropic reasoning settings.

The alias Test action calls POST /admin/models/test with surface="claude_code". It verifies text request conversion and upstream connectivity. It does not probe image, document, hosted-tool, or multi-step client-tool support; test those features with real /v1/messages requests before leaving their toggles enabled.

For Claude Code subscription setup, the dashboard creates a pending OAuth setup session and shows a one-time setup token plus a responses-proxy-claude-code teleport command. The command must run on the machine where Claude Code is already logged in.

When teleport completes, the backend stores an encrypted claude_code_oauth provider credential row, reloads routing, and the dashboard can show the credential status. If a stored subscription expires and cannot refresh, the row is marked needs_reauth and should be set up again.

See Claude Code BYOS for the full flow.

Proxy keys

The Proxy Keys tab creates, lists, and revokes data-plane keys for the active org. A key secret is shown only once when created. Later lists show metadata such as name, prefix, created time, last used time, and active or revoked state.

Use the secret as:

Authorization: Bearer rprx-...

on POST /v1/responses. Keys scope routing to the owning org's providers and aliases.

Metrics

The Metrics tab primarily uses GET /admin/overview, which returns filtered metrics, recent request rows, and recent load-balancer decisions in one backend call. GET /admin/metrics, GET /admin/requests, and GET /admin/decisions remain available for direct API use and focused debugging.

Metric tiles include:

TileBackend key
Requests/minrequests_last_minute
Active sessionsactive_sessions
Total requeststotal_requests
Input tokensinput_tokens
Output tokensoutput_tokens
Total tokenstotal_tokens
Telemetry queue depthtelemetry_queue_depth

The response can include series for a requests-over-time chart. If aggregate token fields are missing, the frontend can fall back to recent request rows, but current backend builds write request rows inline so aggregate metrics should update after request completion without waiting for the telemetry worker.

Requests and decisions

Request rows include fields such as:

  • request_id
  • provider_id
  • model_alias
  • status_code
  • token counts
  • timestamps

Decision rows include:

  • id
  • request_id
  • provider_id
  • model_alias
  • resource_id
  • reason
  • timestamp

The dashboard can filter requests and decisions by provider_id. The BFF clamps limit to 1..1000 and drops unapproved query parameters before forwarding.

Live state

/admin/state and /admin/events expose Redis live state: resources, recent decisions, affinity count, queue depth, and current timestamp. /admin/events is server-sent events and should not be buffered.

Redis live counters and health can reset on container lifecycle. SQL-backed providers, aliases, requests, decisions, and metrics persist when the same database is reused.

Security behavior

The BFF strips secret-shaped keys from admin responses before they reach the browser, including nested fields that look like API keys, passwords, tokens, private keys, or bearer values. Status booleans such as api_key_configured, credential_configured, and credential_resolved are preserved.

Error messages containing secret or infrastructure terms can be redacted by the BFF. Keep backend errors user-actionable without exposing secret values.

Troubleshooting

If providers appear but data-plane requests fail:

  • confirm the request includes a valid proxy key for the active org
  • confirm the request model is a registered alias
  • confirm the provider has a supported wire_api
  • confirm resolved_key_count and pool_size are greater than zero
  • check /admin/routing
  • run /admin/providers/test and /admin/models/test

If metrics are empty:

  • confirm PROXY_DATABASE_URL points at the expected Neon/Postgres database
  • confirm the request completed; streaming rows are written when the stream closes
  • check /admin/overview?limit=5 and /admin/requests?limit=5
  • check telemetry_queue_depth; a growing queue means the worker is lagging on raw event persistence, but request and decision rows should still be written inline
  • wait for the request to complete before checking history