Summary
docs/http-transport.mdx ("Multi-User Authentication" → "Server/DC (PAT)") and docs/authentication.mdx describe the per-request PAT flow (Authorization: Token <PAT>) as if the operator only needs to set CONFLUENCE_URL/JIRA_URL on the server, with credentials supplied entirely per-request by the client. In practice, with the current (non---multi-user) streamable-http setup, this fails with:
Error calling tool 'get_page': Confluence global configuration (URL, SSL) is not available from lifespan context.
or, at listing time, silently registers zero tools (Total tools after filtering: 0), because main_lifespan() calls ConfluenceConfig.from_env()/JiraConfig.from_env() at startup, and that raises unless a real credential (e.g. CONFLUENCE_PERSONAL_TOKEN) is present — a bare CONFLUENCE_URL is not enough to populate MainAppContext.full_confluence_config, which the per-request PAT branch (_get_fetcher → _get_global_config) still depends on for URL/SSL/proxy settings.
The actual fix — setting a non-empty placeholder CONFLUENCE_PERSONAL_TOKEN/JIRA_PERSONAL_TOKEN on the server, whose value is never used once a real per-request token arrives (confirmed by reading _get_fetcher: credentials["personal_access_token"] = user_token always overrides it) — was confirmed by @sooperset directly in #575 ("Option 2: provide server-level authentication as fallback") over a year ago, but was never carried back into the docs pages. Meanwhile #590 (open since 2025-07-01, still active) has multiple independent reports of the same "0 tools" confusion with no pointer to that answer.
Suggested fix
Add a short note/callout to docs/http-transport.mdx's "Server Setup for Multi-User" section (the PAT tab specifically, which currently shows no server-env-var guidance at all — only the OAuth tab does) along the lines of:
Even in per-request PAT mode, the server needs a non-empty CONFLUENCE_PERSONAL_TOKEN / JIRA_PERSONAL_TOKEN set in its own environment to build its internal URL/SSL config template at startup. This value is never used for actual API calls once a client sends its own token via Authorization: Token <PAT> — any non-empty placeholder works.
Possibly also link this note from #590 to help people hitting that issue find the workaround faster.
Related
Summary
docs/http-transport.mdx("Multi-User Authentication" → "Server/DC (PAT)") anddocs/authentication.mdxdescribe the per-request PAT flow (Authorization: Token <PAT>) as if the operator only needs to setCONFLUENCE_URL/JIRA_URLon the server, with credentials supplied entirely per-request by the client. In practice, with the current (non---multi-user)streamable-httpsetup, this fails with:or, at listing time, silently registers zero tools (
Total tools after filtering: 0), becausemain_lifespan()callsConfluenceConfig.from_env()/JiraConfig.from_env()at startup, and that raises unless a real credential (e.g.CONFLUENCE_PERSONAL_TOKEN) is present — a bareCONFLUENCE_URLis not enough to populateMainAppContext.full_confluence_config, which the per-request PAT branch (_get_fetcher→_get_global_config) still depends on for URL/SSL/proxy settings.The actual fix — setting a non-empty placeholder
CONFLUENCE_PERSONAL_TOKEN/JIRA_PERSONAL_TOKENon the server, whose value is never used once a real per-request token arrives (confirmed by reading_get_fetcher:credentials["personal_access_token"] = user_tokenalways overrides it) — was confirmed by @sooperset directly in #575 ("Option 2: provide server-level authentication as fallback") over a year ago, but was never carried back into the docs pages. Meanwhile #590 (open since 2025-07-01, still active) has multiple independent reports of the same "0 tools" confusion with no pointer to that answer.Suggested fix
Add a short note/callout to
docs/http-transport.mdx's "Server Setup for Multi-User" section (the PAT tab specifically, which currently shows no server-env-var guidance at all — only the OAuth tab does) along the lines of:Possibly also link this note from #590 to help people hitting that issue find the workaround faster.
Related
--multi-userflag that removes the need for this placeholder entirely; once merged, this doc gap becomes moot for that mode, but the current default flow still needs the note until then.