Skip to content

401 Unauthorized #611

Duplicate of#613
Duplicate of#613
@johnandersen777

Description

@johnandersen777

Describe the bug

Connecting from OpenAI SDK gives 401 Unauthorized, pretty sure #255 is related from 1.7.0 release. This worked with 1.6.0

To Reproduce

  • Ubuntu 24.10
  • Python 3.12.7
pip install \
  mcp==1.7.0 \
  openai==1.76.2 \
  openai-agents==0.0.14

openai_agent_mcp.py

import asyncio

import agents.mcp as openai_agents_mcp
from agents import Agent, Runner


async def main():
    async with openai_agents_mcp.MCPServerSse(
        name="files",
        params={
            "url": f"http://localhost:8000/sse",
        },
    ) as mcp_server:

        agent = Agent(
            name="Assistant",
            instructions="Use the tools to read the filesystem and answer questions based on those files.",
            mcp_servers=[mcp_server],
        )

        # List the files it can read
        message = "Read the os-release file and tell us what OS we are on"
        print(f"Running: {message}")
        result = await Runner.run(starting_agent=agent, input=message)
        print(result.final_output)

if __name__ == "__main__":
    asyncio.run(main())

mcp_server_files.py

import sys
import click
import pathlib

import uvicorn
from mcp.server.fastmcp import FastMCP

import logging

logging.basicConfig(level=logging.DEBUG)


os_release_path = pathlib.Path("/usr/lib/os-release")
if not os_release_path.exists():
    os_release_path = pathlib.Path("/etc/os-release")
if not os_release_path.exists():
    os_release_path = pathlib.Path(__file__)


SAMPLE_RESOURCES = {
    "/usr/lib/os-release": os_release_path.read_text(),
    "/etc/os-release": os_release_path.read_text(),
}


@click.command()
@click.option("--port", default=8000, help="Port to listen on for SSE")
@click.option(
    "--transport",
    type=click.Choice(["stdio", "sse"]),
    default="stdio",
    help="Transport type",
)
def main(port: int, transport: str) -> int:
    # Create server
    mcp = FastMCP("OS info sever")


    @mcp.tool()
    def get_files() -> list[str]:
        print("[debug-server] get_files()")
        return list(SAMPLE_RESOURCES.keys())


    @mcp.tool()
    def get_file_content(file: str) -> str:
        print("[debug-server] get_file_content()")
        return SAMPLE_RESOURCES[file]


    mcp.run(transport="sse")

if __name__ == "__main__":
    sys.exit(main())

Expected behavior

DEBUG:mcp.server.sse:Setting up SSE connection
DEBUG:mcp.server.sse:Created new session with ID: 4c94bb47-1858-45f1-8f07-9a2cc31ae840
DEBUG:mcp.server.sse:Starting SSE response task
DEBUG:mcp.server.sse:Yielding read and write streams
INFO:     127.0.0.1:62467 - "GET /sse HTTP/1.1" 200 OK

Screenshots

DEBUG:mcp.server.lowlevel.server:Registering handler for ListToolsRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for CallToolRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for ListResourcesRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for ReadResourceRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for PromptListRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for GetPromptRequest
DEBUG:mcp.server.lowlevel.server:Registering handler for ListResourceTemplatesRequest
DEBUG:asyncio:Using selector: KqueueSelector
DEBUG:mcp.server.sse:SseServerTransport initialized with endpoint: /messages/
INFO:     Started server process [60590]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:62493 - "GET /sse HTTP/1.1" 401 Unauthorized
Error initializing MCP server: unhandled errors in a TaskGroup (1 sub-exception)
  + Exception Group Traceback (most recent call last):
  |   File "/home/johnandersen777/sshai-client/openai_agent_mcp.py", line 26, in <module>
  |     asyncio.run(main())
  |   File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
  |     return runner.run(main)
  |            ^^^^^^^^^^^^^^^^
  |   File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
  |     return self._loop.run_until_complete(task)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
  |     return future.result()
  |            ^^^^^^^^^^^^^^^
  |   File "/home/johnandersen777/sshai-client/openai_agent_mcp.py", line 6, in main
  |     async with openai_agents_mcp.MCPServerSse(
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/home/johnandersen777/.local/.venv/lib/python3.12/site-packages/agents/mcp/server.py", line 94, in __aenter__
  |     await self.connect()
  |   File "/home/johnandersen777/.local/.venv/lib/python3.12/site-packages/agents/mcp/server.py", line 107, in connect
  |     transport = await self.exit_stack.enter_async_context(self.create_streams())
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/usr/lib/python3.12/contextlib.py", line 659, in enter_async_context
  |     result = await _enter(cm)
  |              ^^^^^^^^^^^^^^^^
  |   File "/usr/lib/python3.12/contextlib.py", line 210, in __aenter__
  |     return await anext(self.gen)
  |            ^^^^^^^^^^^^^^^^^^^^^
  |   File "/home/johnandersen777/.local/.venv/lib/python3.12/site-packages/mcp/client/sse.py", line 43, in sse_client
  |     async with anyio.create_task_group() as tg:
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/home/johnandersen777/.local/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__
  |     raise BaseExceptionGroup(
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/home/johnandersen777/.local/.venv/lib/python3.12/site-packages/mcp/client/sse.py", line 53, in sse_client
    |     event_source.response.raise_for_status()
    |   File "/home/johnandersen777/.local/.venv/lib/python3.12/site-packages/httpx/_models.py", line 829, in raise_for_status
    |     raise HTTPStatusError(message, request=request, response=self)
    | httpx.HTTPStatusError: Client error '401 Unauthorized' for url 'http://localhost:8000/sse'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401

Activity

paxan

paxan commented on May 1, 2025

@paxan

Can confirm same impact. Just upgraded to 1.7.0, and unit tests in our app started to fail, where they didn't before. We don't yet rely on new OAuth capability of MCP server SDK.

I made a disgusting workaround in my project:

from mcp.server.auth.middleware.bearer_auth import RequireAuthMiddleware
from starlette.routing import Mount, Route

# Note:
# - mcp_server is an instance of FastMCP initialized elsewhere
# - app on the last line is a Starlette app that has other unrelated routes
#   in addition to the routes managed by mcp_server

for r in mcp_server.sse_app().routes:
    # Workaround for https://github.com/modelcontextprotocol/python-sdk/issues/611
    # in which we unwrap SSE handlers from the RequireAuthMiddleware.
    match r:
        case Route():
            if isinstance(r.app, RequireAuthMiddleware):
                r.endpoint = r.app.app
                r.app = r.app.app
        case Mount():
            if isinstance(r.app, RequireAuthMiddleware):
                r.app = r.app.app
    app.router.routes.append(r)
paxan

paxan commented on May 2, 2025

@paxan

I made a draft of a fix: main...paxan:mcp:paxan/require-auth-if-configured

Still thinking how to test. Currently FastMCP.sse_app() has no existing tests.

ihrpr

ihrpr commented on May 2, 2025

@ihrpr
Contributor

related to #613

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @paxan@johnandersen777@ihrpr

        Issue actions

          401 Unauthorized · Issue #611 · modelcontextprotocol/python-sdk