Skip to content

401 Unauthorized #611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
johnandersen777 opened this issue May 1, 2025 · 3 comments
Closed

401 Unauthorized #611

johnandersen777 opened this issue May 1, 2025 · 3 comments

Comments

@johnandersen777
Copy link

johnandersen777 commented May 1, 2025

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
@paxan
Copy link

paxan commented May 1, 2025

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 added a commit to paxan/mcp that referenced this issue May 2, 2025
@paxan
Copy link

paxan commented May 2, 2025

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
Copy link
Contributor

ihrpr commented May 2, 2025

related to #613

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

No branches or pull requests

3 participants