Skip to content

Conversation

@abMatGit
Copy link
Contributor

@abMatGit abMatGit commented Apr 15, 2025

Add support for custom authentication strategies in FastMCP

This PR updates the authentication system with more flexible configuration options. This is outlined in #24 as a feature request.

  • Multiple Authentication Strategies:
    • Token-based authentication (default)
    • Proc-based authentication for custom logic
    • HTTP Basic authentication
  • Structured Authentication Configuration:
    • Reorganized authentication into a nested auth_options hash
  • Environment Variable Integration:
    • Authentication can be configured via environment variables
      • MCP_AUTH_TOKEN: Token for token-based authentication
      • MCP_AUTH_HEADER: Custom header name (defaults to 'Authorization')
      • MCP_AUTH_USER: Username for HTTP Basic authentication
      • MCP_AUTH_PASSWORD: Password for HTTP Basic authentication

Updated the documentation, code commentary and default boiler installation code to handle these changes.

@abMatGit abMatGit force-pushed the issue-24-custom-authentication branch 2 times, most recently from a9ffe6b to e43b629 Compare April 15, 2025 02:25
@abMatGit abMatGit force-pushed the issue-24-custom-authentication branch from e43b629 to c357ac9 Compare April 15, 2025 08:31
@JulianPasquale
Copy link
Contributor

This is great @abMatGit! I like the idea of supporting multiple auth methods 🙂

@yjacquin just wondering, what was in your mind regarding #18? Are you planning to add something for "refresh tokens"?

if authenticate_request(request)
super
else
unauthorized_response(request)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we support Forbidden error responses as well as mentioned in the protocol specs? Maybe is something we want to do at resource/tool level? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JulianPasquale I don't think Forbidden should exist at this layer -- it is too difficult when the application knows permission levels with-respect-to resources.

However we could implement some kind of Forbidden response if there is no access to the application point-blank. We would need some kind of RBAC integration or usage of JWT.

Copy link
Contributor

@JulianPasquale JulianPasquale Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I agree this adds complexity and depends on the specific implementation/use case.

I was just thinking we could provide some kind of "hook" or method to trigger a forbidden response from a resource/tool.

class MyTool < ActionTool::Base
  description "My awesome tool"

  arguments do
    ...
  end

  authorized? do
    true # return true by default

    user.admin? # or any business logic needed here
  end

  def call(input:)
    ...
  end
end

I realise now this is a candidate for a follow up PR 😁 but you made some really good progress towards that!

@abMatGit
Copy link
Contributor Author

@JulianPasquale yes the updated protocol specs should have us rethink this a bit 🤔 .

Maybe an extension to this work is properly handling oauth flows by providing various /authorize, /token routes against the /mcp namespace.

@k0va1
Copy link
Contributor

k0va1 commented May 23, 2025

any updates here? i'd really like to get this merged

@vestimir
Copy link

An idea — passing the token so it's accessible in the ApplicationTool class, this way the tool can also understand who's asking for the information and provide additional context or authorization.

@Kevin-K
Copy link
Contributor

Kevin-K commented Jun 19, 2025

Plus 1 to getting this added. the proc-based auth looks flexible enough to support my desires to do Rails active-record lookups for API tokens.

@JrmKrb
Copy link

JrmKrb commented Jun 24, 2025

Would also love to see this merged, the proc-based auth seems perfect to authenticate with custom JWTs.

@cromulus
Copy link

cromulus commented Jul 3, 2025

As it stands, it is impossible to use this gem for multi-tenant, multi-user applications. proc based auth that passes the token/user/context back to the tools/resources/etc. would be invaluable.

the modelcontextprotocol/ruby-sdk currently does this:

class ApplicationController < ActionController::Base

  def index
    server = MCP::Server.new(
      name: "my_server",
      version: "1.0.0",
      tools: [SomeTool, AnotherTool],
      prompts: [MyPrompt],
      server_context: { user_id: current_user.id },
    )
    render(json: server.handle_json(request.body.read))
  end
end

@PedroAugustoRamalhoDuarte

@cromulus It’s not impossible, but does require a bit of extra work. In my app, I use the api_keys gem with fast_mcp to handle authentication for "multi-tenant" setups. I explain more in this blog post

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants