MCP
Point MCP clients at a self-hosted ctx| origin, then diagnose routing and OAuth with ctxpipe doctor mcp and MCPJam.
Self-hosted ctx| exposes the same organisation-scoped Streamable HTTP endpoint as hosted ctx|:
{AUTH_BASE_URL}/mcp?orgSlug=<org-slug>orgSlug is required. AUTH_BASE_URL must be the public origin clients use,
including TLS. Client JSON shapes and OAuth install paths are unchanged from
hosted ctx|; see Remote MCP and
Authentication.
This page is for operators: confirm the endpoint is reachable, then debug OAuth and tools on a test organisation.
Ready for OAuth is not authenticated proof
npx ctxpipe doctor mcp checks HTTP routing, TLS or reachability, the
unauthenticated Bearer challenge, and OAuth discovery. A ready-for-oauth
result does not prove that browser OAuth, authenticated tools/list, or
ctx_advisor work. The command does not accept bearer tokens and does not
test STDIO servers.
Connect a client
Use the same config as Quickstart, with your deployment origin:
{
"mcpServers": {
"ctxpipe": {
"type": "streamable-http",
"url": "https://ctx.example.com/mcp?orgSlug=your-org-slug"
}
}
}The MCP client must complete OAuth against this deployment. CLI setup sign-in and MCP client OAuth are separate flows.
Diagnose discovery
Run the lightweight doctor against the exact organisation-scoped URL:
npx ctxpipe doctor mcp \
--url "$AUTH_BASE_URL/mcp?orgSlug=<slug>"
npx ctxpipe doctor mcp \
--url "$AUTH_BASE_URL/mcp?orgSlug=<slug>" \
--json--json is machine-readable. Failures set a non-zero exit code. Loopback HTTP
is allowed with a warning; remote endpoints must use HTTPS.
| Check | Passes when |
|---|---|
| Target | Path is /mcp and orgSlug is present |
| Backend status | GET /.status returns JSON with status: "ok" |
| OAuth challenge | Unauthenticated Streamable HTTP initialize returns 401 with a Bearer WWW-Authenticate challenge that includes resource_metadata |
| Protected resource | RFC 9728 metadata matches the /mcp audience and names an authorisation server |
| Authorisation server | RFC 8414 metadata exposes authorisation, token, and registration endpoints |
Overall status is ready-for-oauth, warning, or failed.
If TLS fails from a Node CLI against a local CA (Portless or a private CA), set
NODE_EXTRA_CA_CERTS to the CA file. Do not disable TLS verification.
Authenticated checks with MCPJam
MCPJam is an external diagnostic client. It is not bundled into ctxpipe or the
self-hosted backend. Pin the versions below; do not use @latest. Use a test
organisation, not a customer organisation.
npx @mcpjam/[email protected] oauth login \
--url "$AUTH_BASE_URL/mcp?orgSlug=<slug>" \
--protocol-version 2025-11-25 \
--registration dcr \
--credentials-out .mcpjam/credentials.json \
--debug-out .mcpjam/oauth-debug.json
npx @mcpjam/[email protected] tools list \
--url "$AUTH_BASE_URL/mcp?orgSlug=<slug>" \
--credentials-file .mcpjam/credentials.json
npx @mcpjam/[email protected] tools call \
--url "$AUTH_BASE_URL/mcp?orgSlug=<slug>" \
--credentials-file .mcpjam/credentials.json \
--tool-name ctx_advisor \
--tool-args '{"prompt":"Health check: confirm org MCP access."}'For a visual OAuth and JSON-RPC timeline on a local origin:
npx @mcpjam/[email protected] \
--url "$AUTH_BASE_URL/mcp?orgSlug=<slug>" \
--name "ctxpipe self-host" \
--oauth \
--tab serversThe hosted MCPJam application only reaches public HTTPS. It cannot use
localhost or refresh against a local authorisation server.
Artefacts and credentials
Keep OAuth credentials and debug traces out of Git. Write them under .mcpjam/
(gitignored in the ctx| repository). Review files before sharing. The
credentials file can include an access token, refresh token, client id, and
client secret even when stdout is redacted.
The ctx| doctor never accepts or prints bearer tokens. Do not put access_token
on the MCP URL.
MCPJam does not prove token refresh races, dropped-session recovery, or concurrent clients. Do not gate CI on interactive OAuth or LLM evals.
Common failures
- Missing
orgSlug— use/mcp?orgSlug=<slug>, not/mcp. AUTH_BASE_URLmismatch — issuer, callbacks, and MCP discovery must use the same public origin clients see.- Remote HTTP — production MCP must be HTTPS.
- Status unreachable or timed out — backend, DNS, TLS, or an untrusted CA.
- HTTP 401 without
resource_metadata— clients cannot start OAuth discovery. - Protected-resource audience mismatch — RFC 9728
resourcecanonicalises to/mcpwithout the query string. - Authorisation-server metadata missing registration — dynamic client registration cannot proceed.
- CLI setup sign-in worked, but the MCP client still asks for authorisation — expected. Setup auth and MCP OAuth are separate.