The MCP plugin (v0.1.0) can list organizations and projects but cannot read into any project. Every project-internal endpoint returns HTTP 403 with Unauthorized: collection_index_view failed permission check, regardless of the user's actual permissions.
Environment
- Plugin:
upsun/ai @ v0.1.0 (installed via Claude Code marketplace)
- Claude Code host: macOS, Darwin 25.4.0
- User: organization owner of the org being queried, full rights via the Upsun console and
upsun CLI
Steps to reproduce
- Install the plugin and authenticate via the MCP's OAuth flow.
- Optionally also set
UPSUN_API_TOKEN in the environment so the upsun-api-token header is populated.
- Call any project-internal MCP tool, e.g.
list-environment, list-domain, list-certificate, list-activity, info-project.
Expected
Tool returns project data — same data the user can read via upsun environment:list etc.
Actual
HTTP 403 Forbidden
{
"status": "error",
"code": 403,
"title": "Forbidden",
"message": "Access was denied to this resource.",
"detail": {
"error": "Unauthorized: collection_index_view failed permission check"
}
}
Reproduced against multiple projects under the same organization, ruling out a per-project ACL issue. list-organization and list-project work fine.
Root cause (suspected)
The OAuth authorize URL emitted by authenticate requests only scope=offline_access:
https://auth.upsun.com/oauth2/authorize?...&scope=offline_access&...
offline_access only grants refresh-token capability — no project-data scope is requested, so the resulting access token cannot read project resources.
Setting UPSUN_API_TOKEN (so the upsun-api-token header carries a valid personal API token) does not change the outcome — the header path appears to be ignored, or is gated by the same scope check.
Suggested fixes
- Have the OAuth client request the scopes needed to read project resources (e.g.
project:read, or whatever the equivalent is on auth.upsun.com).
- Document and honor the
upsun-api-token header as a working alternative to OAuth — at the moment its presence has no visible effect on project-content endpoint authorization.
- Surface the
enable-write header in plugin.json as a configurable plugin option. Currently it is hardcoded "false" in .mcp.json and /plugin provides no UI to toggle it. (Lower priority than the read scope, since reads themselves are blocked first.)
Workaround
Use the upsun CLI directly (upsun login produces a session with full delegated rights). The plugin's upsun skill already recommends this — but the MCP tools should be usable on their own merit.
The MCP plugin (v0.1.0) can list organizations and projects but cannot read into any project. Every project-internal endpoint returns HTTP 403 with
Unauthorized: collection_index_view failed permission check, regardless of the user's actual permissions.Environment
upsun/ai@ v0.1.0 (installed via Claude Code marketplace)upsunCLISteps to reproduce
UPSUN_API_TOKENin the environment so theupsun-api-tokenheader is populated.list-environment,list-domain,list-certificate,list-activity,info-project.Expected
Tool returns project data — same data the user can read via
upsun environment:listetc.Actual
Reproduced against multiple projects under the same organization, ruling out a per-project ACL issue.
list-organizationandlist-projectwork fine.Root cause (suspected)
The OAuth authorize URL emitted by
authenticaterequests onlyscope=offline_access:offline_accessonly grants refresh-token capability — no project-data scope is requested, so the resulting access token cannot read project resources.Setting
UPSUN_API_TOKEN(so theupsun-api-tokenheader carries a valid personal API token) does not change the outcome — the header path appears to be ignored, or is gated by the same scope check.Suggested fixes
project:read, or whatever the equivalent is onauth.upsun.com).upsun-api-tokenheader as a working alternative to OAuth — at the moment its presence has no visible effect on project-content endpoint authorization.enable-writeheader inplugin.jsonas a configurable plugin option. Currently it is hardcoded"false"in.mcp.jsonand/pluginprovides no UI to toggle it. (Lower priority than the read scope, since reads themselves are blocked first.)Workaround
Use the
upsunCLI directly (upsun loginproduces a session with full delegated rights). The plugin'supsunskill already recommends this — but the MCP tools should be usable on their own merit.