Skip to content

Added CORS middleware to allow cross-origin requests #371

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
wants to merge 61 commits into from

Conversation

jerome3o-anthropic
Copy link
Member

  • Allow any origin to make requests
  • Allow GET, POST, and OPTIONS HTTP methods
  • Allow any headers
  • Allow sending credentials with requests

Also added OPTIONS method to auth routes to handle CORS preflight requests.

Motivation and Context

How Has This Been Tested?

Breaking Changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

@Kludex
Copy link
Member

Kludex commented Mar 25, 2025

This needs to wrap the Starlette application.

Ref.: https://www.starlette.io/middleware/#corsmiddleware-global-enforcement

Comment on lines 563 to 572
middleware = [
# Add CORS middleware to allow cross-origin requests
Middleware(
CORSMiddleware,
allow_origins=["*"], # Allow any origin
allow_methods=["GET", "POST", "OPTIONS"],
allow_headers=["*"],
allow_credentials=True,
),
Copy link
Member

Choose a reason for hiding this comment

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

The CORSMiddleare needs to wrap the application, not be included in the middleware parameter.

Base automatically changed from praboud/auth to main May 1, 2025 18:43
@wanghsinche
Copy link

any updates?

@christopherorea
Copy link

How can I help to make this a reality?

@christopherorea
Copy link

christopherorea commented Jun 28, 2025

I added the following code, but it requires to connect to Starlett. Not a very clear pathway to many. This works, maybe use some of this code to add the option to pass an option object and integrate when declaring it.

from mcp.server.fastmcp import FastMCP
from starlette.middleware.cors import CORSMiddleware
import random

# Create an MCP server
mcp = FastMCP(
        "Weather Service",
        stateless_http=True,
    )

# Tool implementation
@mcp.tool()
def get_weather(location: str) -> str:
    """Get the current weather for a specified location."""
    return f"Weather in {location}: Sunny, 72°F"


@mcp.tool()
def greet(name: str) -> str:
    """Greet a user by name."""
    return f"Hello, {name}!"


@mcp.tool()
def add_numbers(a: float, b: float) -> float:
    """Add two numbers together."""
    return a + b


jokes = [
    "Why do programmers prefer dark mode? Because light attracts bugs.",
    "How many programmers does it take to change a light bulb? None, it's a hardware problem.",
    "Why was the computer cold? It left its Windows open.",
    "Bugs come in through open Windows."
]

@mcp.tool()
def get_random_joke() -> str:
    """Tell a random programming joke."""
    return random.choice(jokes)


programming_facts = [
    "The first computer programmer was Ada Lovelace.",
    "Python is named after the British comedy group Monty Python.",
    "The first ever computer virus was created in 1971 and was called the 'Creeper' program."
]

@mcp.tool()
def get_programming_fact() -> str:
    """Get a random programming fact."""
    return random.choice(programming_facts)

# Resource implementation
@mcp.resource("weather://{location}")
def weather_resource(location: str) -> str:
    """Provide weather data as a resource."""
    return f"Weather data for {location}: Sunny, 72°F"


# Prompt implementation
@mcp.prompt()
def weather_report(location: str) -> str:
    """Create a weather report prompt."""
    return f"""You are a weather reporter. Weather report for {location}?"""

# Generates the base Starlette/ASGI application
fastmcp_asgi_app = mcp.streamable_http_app() #  IMO: Here should be an option to add cors dict with configuration

# Set up the CORSMiddleware
cors_middleware = CORSMiddleware(
    app=fastmcp_asgi_app, # Wraps the app generated by mcp
    allow_origins=["*"], # Allows any origin. Change '*' to a list of your domains in production.
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# The final app to run is the middleware wrapping the base app
app_with_cors = cors_middleware


# Run the server
if __name__ == "__main__":
    import uvicorn
    # Ejecuta la aplicación envuelta con el middleware
    uvicorn.run(app_with_cors, host="127.0.0.1", port=8000)

@ihrpr
Copy link
Contributor

ihrpr commented Jul 9, 2025

This looks quite stale, @jerome3o-anthropic closing it

@ihrpr ihrpr closed this Jul 9, 2025
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.

7 participants