Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/advanced/auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ It also supports the full OAuth 2 flow, compliant with [MCP Spec 2025-03-26](htt

It's worth noting that most MCP clients currently do not support the latest MCP spec, so for our examples we might use a bridge client such as `npx mcp-remote`. We recommend you use it as well, and we'll show our examples using it.

<Warning>
`auth_config` is entirely opt-in. If you don't pass one to `FastApiMCP(...)`, no authentication or authorization is applied to the MCP endpoint — anyone who can reach it can list and call every tool it exposes, the same way an unprotected FastAPI route is open to anyone who can reach it. This is fine for local development or fully internal/trusted networks, but make sure to configure `auth_config` before exposing an MCP server publicly.
</Warning>

## Basic Token Passthrough

If you just want to be able to pass a valid authorization header, without supporting a full authentication flow, you don't need to do anything special.
Expand Down
6 changes: 5 additions & 1 deletion fastapi_mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,11 @@ def _setup_auth(self):
f"Unsupported MCP spec version: {self._auth_config.version}. Please check your AuthConfig."
)
else:
logger.info("No auth config provided, skipping auth setup")
logger.warning(
"No auth_config provided: MCP tools will be exposed without authentication. "
"Anyone who can reach this server's MCP endpoint can call every wrapped route. "
"Pass an AuthConfig if this server is not intended to be publicly/anonymously accessible."
)

def mount_http(
self,
Expand Down
30 changes: 30 additions & 0 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from fastapi import FastAPI
import pytest

Expand Down Expand Up @@ -581,3 +583,31 @@ async def empty_tags():
exclude_tags_mcp = FastApiMCP(app, exclude_tags=["items"])
assert len(exclude_tags_mcp.tools) == 1
assert {tool.name for tool in exclude_tags_mcp.tools} == {"empty_tags"}


def test_warns_when_mounted_without_auth_config(simple_fastapi_app: FastAPI, caplog: pytest.LogCaptureFixture):
"""Mounting without an auth_config should warn that the MCP endpoint is unauthenticated (see #324)."""
mcp_server = FastApiMCP(simple_fastapi_app)

with caplog.at_level(logging.WARNING, logger="fastapi_mcp.server"):
mcp_server.mount_http()

assert any("without authentication" in record.message for record in caplog.records)


def test_no_auth_warning_when_auth_config_provided(simple_fastapi_app: FastAPI, caplog: pytest.LogCaptureFixture):
"""Mounting with an auth_config should not warn about missing authentication."""
from fastapi import Depends
from fastapi.security import HTTPBearer

from fastapi_mcp import AuthConfig

mcp_server = FastApiMCP(
simple_fastapi_app,
auth_config=AuthConfig(dependencies=[Depends(HTTPBearer())]),
)

with caplog.at_level(logging.WARNING, logger="fastapi_mcp.server"):
mcp_server.mount_http()

assert not any("without authentication" in record.message for record in caplog.records)