plugins/opencode/forge.ts returns without registering anything when FORGE_TOKEN is unset (if (!url || !token) return;). A person who has only the forge's URL gets no forge in OpenCode at all. OpenCode's remote MCP servers can sign in with OAuth, and the forge's /mcp advertises its protected-resource metadata on its 401.
Done when:
[ ] With only FORGE_URL set, the plugin registers the remote forge MCP server with no Authorization header, so OpenCode takes the forge's OAuth sign-in, and it registers the forge command. With FORGE_TOKEN set, it sends the token as today
[ ] With neither set, it still registers nothing
[ ] The README says both ways
[ ] test/plugin-opencode-oauth.test.ts calls the plugin's config hook with and without a token and proves the three shapes. It fails without the change
Files: plugins/opencode/forge.ts, plugins/opencode/README.md, test/plugin-opencode-oauth.test.ts
Risk: OpenCode's config key for OAuth may need oauth: {} rather than just leaving out headers. Follow its documented shape and name it in the pull.
plugins/opencode/forge.tsreturns without registering anything whenFORGE_TOKENis unset (if (!url || !token) return;). A person who has only the forge's URL gets no forge in OpenCode at all. OpenCode's remote MCP servers can sign in with OAuth, and the forge's/mcpadvertises its protected-resource metadata on its 401.Done when:
FORGE_URLset, the plugin registers the remoteforgeMCP server with no Authorization header, so OpenCode takes the forge's OAuth sign-in, and it registers theforgecommand. WithFORGE_TOKENset, it sends the token as todaytest/plugin-opencode-oauth.test.tscalls the plugin'sconfighook with and without a token and proves the three shapes. It fails without the changeFiles: plugins/opencode/forge.ts, plugins/opencode/README.md, test/plugin-opencode-oauth.test.ts Risk: OpenCode's config key for OAuth may need
oauth: {}rather than just leaving out headers. Follow its documented shape and name it in the pull.