Skip to content

Allow dynamic ports for localhost redirect domains #137

@dylanbr

Description

@dylanbr

CLI agents like Claude Code, Codex CLI, and so on, will authenticate using the OAuth 2 /register endpoint if given a laravel/mcp URL. By default, however, they do not use a static port for their redirect URL, and will instead use a randomly allocated port with a URL like http://localhost:60000/callback or http://127.0.0.1:50000/callback.

Currently it is only possible to allow * any redirect domain, or a list of allowed domains with static hostnames, ports and paths. No dynamic parts are supported.

While it would be possible for a bad actor to use localhost redirect domains with dynamic ports to their advantage, it is less of a problem than allowing * any redirect domain. The person / project integrating laravel/mcp should be able to make this decision for themselves.

After some consideration, I have identified a few different potential solutions, all with their own pros and cons:

  1. Allow * wildcards within each redirect_domains entry. This would allow any part of the redirect URL to be dynamic. However, it is likely the most difficult to implement securely, because it would require a custom URL parser that supports wildcards.
  2. Allow structured entries in redirect_domains which specify different parts of the URL and whether they should be static, dynamic or allow wildcards. To implement this, parse_url or Uri would be used on the requested URL, and then compared component by component with the structured entry. eg. ['scheme' => 'http', 'host' => 'localhost', 'port' => '*']. This avoids needing to parse the redirect_domans URLs, and allows for wildcards in any component.
  3. Instead of changing the processing of redirect_domains, instead add a new configuration entry for allow_local_with_any_port. When this is true, any URL with host localhost, 127.0.0.1, or [::1] would be allowed, regardless of the port. This is probably the easiest to implement, but is also the least versatile.
  4. Allow closure entries in redirect_domains which are given either the raw redirect URL, or an already parsed Uri, and the closure code can determine if the given URL should be allowed.

The existing string based redirect_domains entries can be kept for backwards compatibility. It would also be possible to implement more than one of these, say 2 and 4, for the most flexibility.

I am more than happy to put together a PR implementing this change, but I first wanted to get feedback from the maintainers and community on what they think would be the best approach.

Let me know your thoughts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions