@@ -10,9 +10,11 @@ use axum::extract::State;
1010use axum:: http:: Request ;
1111use axum:: http:: StatusCode ;
1212use axum:: http:: header:: AUTHORIZATION ;
13+ use axum:: http:: header:: CONTENT_TYPE ;
1314use axum:: middleware;
1415use axum:: middleware:: Next ;
1516use axum:: response:: Response ;
17+ use axum:: routing:: get;
1618use rmcp:: ErrorData as McpError ;
1719use rmcp:: handler:: server:: ServerHandler ;
1820use rmcp:: model:: CallToolRequestParam ;
@@ -256,14 +258,35 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
256258 } ;
257259 eprintln ! ( "starting rmcp streamable http test server on http://{bind_addr}/mcp" ) ;
258260
259- let router = Router :: new ( ) . nest_service (
260- "/mcp" ,
261- StreamableHttpService :: new (
262- || Ok ( TestToolServer :: new ( ) ) ,
263- Arc :: new ( LocalSessionManager :: default ( ) ) ,
264- StreamableHttpServerConfig :: default ( ) ,
265- ) ,
266- ) ;
261+ let router = Router :: new ( )
262+ . route (
263+ "/.well-known/oauth-authorization-server/mcp" ,
264+ get ( {
265+ move || async move {
266+ let metadata_base = format ! ( "http://{bind_addr}" ) ;
267+ #[ expect( clippy:: expect_used) ]
268+ Response :: builder ( )
269+ . status ( StatusCode :: OK )
270+ . header ( CONTENT_TYPE , "application/json" )
271+ . body ( Body :: from (
272+ serde_json:: to_vec ( & json ! ( {
273+ "authorization_endpoint" : format!( "{metadata_base}/oauth/authorize" ) ,
274+ "token_endpoint" : format!( "{metadata_base}/oauth/token" ) ,
275+ "scopes_supported" : [ "" ] ,
276+ } ) ) . expect ( "failed to serialize metadata" ) ,
277+ ) )
278+ . expect ( "valid metadata response" )
279+ }
280+ } ) ,
281+ )
282+ . nest_service (
283+ "/mcp" ,
284+ StreamableHttpService :: new (
285+ || Ok ( TestToolServer :: new ( ) ) ,
286+ Arc :: new ( LocalSessionManager :: default ( ) ) ,
287+ StreamableHttpServerConfig :: default ( ) ,
288+ ) ,
289+ ) ;
267290
268291 let router = if let Ok ( token) = std:: env:: var ( "MCP_EXPECT_BEARER" ) {
269292 let expected = Arc :: new ( format ! ( "Bearer {token}" ) ) ;
@@ -282,6 +305,9 @@ async fn require_bearer(
282305 request : Request < Body > ,
283306 next : Next ,
284307) -> Result < Response , StatusCode > {
308+ if request. uri ( ) . path ( ) . contains ( "/.well-known/" ) {
309+ return Ok ( next. run ( request) . await ) ;
310+ }
285311 if request
286312 . headers ( )
287313 . get ( AUTHORIZATION )
0 commit comments