Skip to content

MCP OAuth: redirect_uri mismatch with local callback server prevents Figma auth from completing #11586

Description

@loeyae

Before opening, please confirm:

Operating System

Windows 10 Home China (or newer) - build 26200

Kiro Version

2.22.1

Bug Description

MCP OAuth: redirect_uri (no path, 127.0.0.1) does not match the local callback server (localhost + /oauth/callback), so the authorization code is never received

Environment

  • kiro-cli: 2.22.1 (kiro-cli-chat 2.22.1)
  • OS: Windows (x86_64)
  • MCP server: Figma (https://mcp.figma.com/mcp), streamable-http, protocolVersion 2026-07-28
  • Auth flow: OAuth 2.1 Authorization Code + PKCE (S256), RFC 9207 iss returned by the provider

Summary

Authenticating an OAuth-protected MCP server (Figma) from kiro-cli never completes. The browser side succeeds and redirects back with a valid code and iss, the page says it can be closed, but kiro-cli keeps reporting that authentication is still required. It eventually surfaces the internal error string Authorization server response missing required issuer: expected https://api.figma.com, even though the provider metadata and the redirect both carry the correct issuer.

Root cause: the redirect_uri registered in the authorization request and the address the local callback server actually listens on do not match — neither in path nor in host.

Evidence

  1. Authorization request built by kiro-cli registers a path-less redirect_uri on 127.0.0.1:

    https://www.figma.com/oauth/mcp?response_type=code&client_id=...&state=...
      &code_challenge=...&code_challenge_method=S256
      &redirect_uri=http%3A%2F%2F127.0.0.1%3A54279
      &resource=https%3A%2F%2Fmcp.figma.com%2Fmcp
    

    (redirect_uri = http://127.0.0.1:54279, no path)

  2. The provider redirects back to the root path with a valid code + iss:

    http://127.0.0.1:54279/?code=...&iss=https%3A%2F%2Fapi.figma.com&state=...
    
  3. But the local callback server started by kiro-cli listens on localhost + /oauth/callback:

    [MCP OAuth] Redirect server started on http://localhost:<port>/oauth/callback
    

    The binary also contains the format string http://localhost:/oauth/callback and the log line Started callback server for External IdP.

So there are two mismatches:

  • Path: server handles /oauth/callback, provider returns to /.
  • Host: server binds localhost (may resolve to IPv6 ::1), redirect_uri uses literal 127.0.0.1 (IPv4).

The authorization code delivered to / on 127.0.0.1 is never consumed, the token exchange never happens, and the flow stalls / falls through to the "missing required issuer" branch.

Expected

The redirect_uri sent in the authorization request must exactly match the host + path the callback server listens on (e.g. both http://127.0.0.1:<port>/oauth/callback, or both a path-less root on the same host), so the returned code is received and exchanged for a token.

Actual

Authorization code is delivered to an address the callback server is not listening on. Flow never completes; kiro-cli keeps prompting for authentication.

Notes

  • Figma's metadata is well-formed and returns the correct issuer:
    • https://mcp.figma.com/.well-known/oauth-protected-resource → authorization_servers:["https://api.figma.com"]
    • https://api.figma.com/.well-known/oauth-authorization-server → "issuer":"https://api.figma.com", authorization_response_iss_parameter_supported:true
  • The Kiro IDE uses a different OAuth implementation and authenticates the same Figma server successfully, which isolates the defect to the kiro-cli callback routing.
  • Previously succeeded on an earlier kiro-cli version — appears to be a regression in the redirect_uri / callback-server wiring.

Repro

  1. Configure the Figma MCP server in mcp.json (type: http, url: https://mcp.figma.com/mcp).
  2. Trigger OAuth from kiro-cli and complete consent in the browser.
  3. Observe the browser redirect to http://127.0.0.1:<port>/?code=...&iss=... while the CLI's callback server is on http://localhost:<port>/oauth/callback.
  4. CLI never receives the code; still reports authentication required.

Steps to Reproduce

  1. Configure the Figma MCP server in mcp.json:
    { "figma": { "type": "http", "url": "https://mcp.figma.com/mcp" } }
  2. From kiro-cli, trigger the OAuth flow for the Figma server and complete the consent in the browser.
  3. Observe the authorization request built by kiro-cli: it registers a path-less redirect_uri on 127.0.0.1, e.g.
    https://www.figma.com/oauth/mcp?response_type=code&client_id=...&code_challenge_method=S256&redirect_uri=http%3A%2F%2F127.0.0.1%3A54279&resource=https%3A%2F%2Fmcp.figma.com%2Fmcp
  4. The provider redirects back to the ROOT path with a valid code and iss:
    http://127.0.0.1:54279/?code=...&iss=https%3A%2F%2Fapi.figma.com&state=...
    The browser page reports success and says it can be closed.
  5. Meanwhile kiro-cli's local callback server is listening on a DIFFERENT host+path:
    [MCP OAuth] Redirect server started on http://localhost:/oauth/callback
  6. The authorization code delivered to "/" on 127.0.0.1 is never received by the server on "localhost:/oauth/callback".
    kiro-cli still reports that authentication is required and eventually surfaces:
    "Authorization server response missing required issuer: expected https://api.figma.com"

Expected Behavior

The redirect_uri sent in the authorization request must exactly match the host and path that
kiro-cli's local callback server listens on (same host — both 127.0.0.1 or both localhost — and
the same path). The provider then redirects the authorization code to an address the callback
server is actually handling, the code is received and exchanged for a token via PKCE, and
authentication completes without further prompting.

(Figma's metadata is well-formed — issuer is "https://api.figma.com" — and the Kiro IDE, which
uses a different OAuth implementation, authenticates the same server successfully. This isolates
the defect to the kiro-cli redirect_uri / callback-server wiring, and it worked on an earlier
kiro-cli version, so it appears to be a regression.)

Conversation ID

No response

Additional Context

[q-details]
version = "2.22.1"
hash = "300880ceb10a3e9c12ebcef5cb7403335581e118"
date = "2026-09-18T01:25:22.088739Z (7d ago)"

[system-info]
os = "Windows 10 Home China (or newer) - build 26200"
chip = "12th Gen Intel(R) Core(TM) i5-12400F"
total-cores = 6
memory = "31.73 GB"

[environment]
cwd = 'C:\Users\loeye.kiro\crew\workspace'
cli-path = 'C:\Users\loeye\AppData\Local\Kiro-Cli\kiro-cli.exe'
install-method = "unknown"

[cloud]
remote-sandbox-rollout = true
remote-sessions-endpoint-configured = false
cloud-config-rollout = true
cloud-config-endpoint-configured = false
extracted-kas-versions = []

[env-vars]
ASBX_KIRO_MANDATORY_MCPS = "kirocrew-computer,kirocrew-core,kirocrew-crew-log,kirocrew-cron,kirocrew-dashboard,kirocrew-panel,kirocrew-work"
KIRO_SESSION_ID = "e28a9c58-697d-43fe-8898-66dd9a296edb"
PATH = 'C:\Users\loeye.kiro\crew\playwright-cli\managed-bin;C:\Users\loeye.kiro\crew\playwright-cli\bin;C:\Users\loeye.kiro\crew\playwright-cli;C:\Users\loeye/.local/bin;C:\Users\loeye/.toolbox/bin;C:\Users\loeye/.npm-packages/bin;C:\Users\loeye.local\share\mise/shims;C:\Users\loeye/.volta/bin;/opt/homebrew/bin;/usr/local/bin;C:\Program Files\KiroCrew\resources\backend-dist\kirocrew-backend\Lib\site-packages\kiro_crew_vendor\llama_cpp_libs\win_amd64;F:\App\Java\jdk-21\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Windows\System32\OpenSSH;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;D:\Program Files\Microsoft VS Code\bin;D:\Program files\JetBrains\scripts;F:\App\Choco\bin;F:\Program Files\Git\cmd;F:\Program Files\Git\usr\bin;F:\Program Files\Git\mingw64\bin;D:\Users\loeye\AppData\Roaming\nvm;F:\App\nodejs;F:\App\Choco\lib\maven\apache-maven-3.9.11\bin;E:\Work\repo\node;E:\wamp64\bin\mysql\mysql8.0.27\bin;E:\wamp64\bin\apache\apache2.4.51\bin;E:\wamp64\bin\php\php7.4.26;D:\Program Files (x86)\Tencent\微信web开发者工具\dll;D:\Program Files (x86)\Gpg4win..\GnuPG\bin;E:\Work\repo\android\platform-tools;F:\ProgramData\opencv45\opencv\build\x64\vc15\bin;F:\Program Files\CMake\bin;F:\ProgramData\miniconda3\condabin;C:\Program Files\dotnet;C:\Users\loeye\AppData\Local\Microsoft\WindowsApps;C:\Users\loeye\AppData\Local\JetBrains\Toolbox\scripts;C:\tools\Cmder;C:\Users\loeye\AppData\Local\gitkraken\bin;E:\Work\src\loeyae\net-disk\node_modules.bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;d:\Program Files\Microsoft VS Code\bin;C:\Program Files\NVIDIA Corporation\NVIDIA App\NvDLISR;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;F:\ProgramData\Anaconda3\envs\python310;F:\ProgramData\Anaconda3\envs\python310\Scripts;C:\Program Files\KeePassXC;C:\Users\loeye.local\bin;D:\Program Files\Qoder CN IDE\bin;C:\Users\loeye\AppData\Local\pnpm;d:\Programs\Trae CN\bin;C:\Users\loeye\AppData\Local\Microsoft\WindowsApps;C:\Users\loeye\AppData\Local\JetBrains\Toolbox\scripts;C:\tools\Cmder;D:\Users\loeye\AppData\Roaming\nvm;F:\App\nodejs;C:\Users\loeye\AppData\Local\gitkraken\bin;C:\Users\loeye\AppData\Local\Microsoft\WindowsApps;F:\Programs\Kiro\bin;C:\Users\loeye\AppData\Local\Microsoft\WinGet\Packages\Anthropic.ClaudeCode_Microsoft.Winget.Source_8wekyb3d8bbwe;C:\Users\loeye.bun\bin;C:\kubectl;C:\Users\loeye\AppData\Local\Kiro-Cli;C:\Program Files\KiroCrew\resources\backend-dist\kirocrew-backend'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions