Configuring CORS
Configuring CORS
Control browser access to your MCP server
This article describes CORS configuration that's specific to Apollo MCP Server. For a more general introduction to CORS and common considerations, see MDN's CORS documentation.
By default, Apollo MCP Server has CORS disabled. If your MCP server serves tools to browser-based applications, you need to enable CORS and configure one of the following in the cors section of your server's YAML config file:
Add the origins of those web applications to the server's list of allowed
origins.Use this option if there is a known, finite list of web applications that consume your MCP server.
Add a regex that matches the origins of those web applications to the server's list of allowed
match_origins.This option comes in handy if you want to match origins against a pattern, see the example below that matches subdomains of a specific namespace.
Enable the
allow_any_originoption.Use this option if your MCP server is a public API with arbitrarily many web app consumers.
With this option enabled, the server sends the wildcard (*) value for the
Access-Control-Allow-Originheader. This enables any website to initiate browser connections to it (but they can't provide cookies or other credentials).
If clients need to authenticate their requests with cookies, you must use either
origins,match_origins, or the combination of both options. When using both options, note thatoriginsis evaluated beforematch_origins.
The following snippet includes an example of each option (use either allow_any_origin, or origins and/or match_origins):
1transport:
2 type: streamable_http
3 port: 8000
4
5cors:
6 # Enable CORS support
7 enabled: true
8
9 # Set to true to allow any origin
10 # (Defaults to false)
11 allow_any_origin: true
12
13 # List of accepted origins
14 # (Ignored if allow_any_origin is true)
15 #
16 # An origin is a combination of scheme, hostname and port.
17 # It does not have any path section, so no trailing slash.
18 origins:
19 - https://www.your-app.example.com
20
21 # List of origin patterns (regex matching)
22 match_origins:
23 - "^https://([a-z0-9]+[.])*api[.]example[.]com$" # any host that uses https and ends with .api.example.comYou can also disable CORS entirely by setting enabled to false or omitting the cors section:
1cors:
2 enabled: falseIf your MCP server serves exclusively non-browser-based clients, you probably don't need to enable CORS configuration.
Passing credentials
If your MCP server requires requests to include a user's credentials (e.g., via cookies), you need to modify your CORS configuration to tell the browser those credentials are allowed.
You can enable credentials with CORS by setting the Access-Control-Allow-Credentials HTTP header to true.
To allow browsers to pass credentials to the server, set allow_credentials to true, like so:
1cors:
2 enabled: true
3 origins:
4 - https://www.your-app.example.com
5 allow_credentials: trueTo support credentialed requests, your server's config file must specify individual origins or match_origins. If your server enables allow_any_origin, your browser will refuse to send credentials.
All cors options
The following snippet shows all CORS configuration defaults for Apollo MCP Server:
1#
2# CORS (Cross Origin Resource Sharing)
3#
4cors:
5 # Enable CORS support
6 enabled: false
7
8 # Set to true to allow any origin
9 allow_any_origin: false
10
11 # List of accepted origins
12 # (Ignored if allow_any_origin is set to true)
13 #
14 # An origin is a combination of scheme, hostname and port.
15 # It does not have any path section, so no trailing slash.
16 origins: []
17
18 # List of origin patterns (regex matching)
19 # Useful for matching dynamic ports or subdomains
20 match_origins: []
21
22 # Set to true to add the `Access-Control-Allow-Credentials` header
23 allow_credentials: false
24
25 # Allowed request methods
26 allow_methods:
27 - GET
28 - POST
29
30 # The headers to allow.
31 # These are the default headers required for MCP protocol and trace context
32 allow_headers:
33 - accept
34 - content-type
35 - mcp-protocol-version
36 - mcp-session-id
37 - traceparent # W3C Trace Context
38 - tracestate # W3C Trace Context
39
40 # Which response headers are available to scripts running in the
41 # browser in response to a cross-origin request.
42 # The mcp-session-id header should be exposed for MCP session management.
43 # Trace context headers are exposed for distributed tracing.
44 expose_headers:
45 - mcp-session-id
46 - traceparent # W3C Trace Context
47 - tracestate # W3C Trace Context
48
49 # Adds the Access-Control-Max-Age header
50 # Maximum age (in seconds) for preflight cache
51 max_age: 7200 # 2 hoursOrigin matching
Apollo MCP Server supports two types of origin matching:
Exact origins
Use the origins array for exact origin matches:
1cors:
2 enabled: true
3 origins:
4 - http://localhost:3000
5 - https://myapp.example.comPattern matching
Use the match_origins array for regex pattern matching:
1cors:
2 enabled: true
3 match_origins:
4 - "^https://localhost:[0-9]+$" # Any localhost HTTPS port
5 - "^http://localhost:[0-9]+$" # Any localhost HTTP port
6 - "^https://.*\\.example\\.com$" # Any subdomain of example.comCommon configurations
Development setup
For local development with hot reloading and various ports:
1cors:
2 enabled: true
3 match_origins:
4 - "^http://localhost:[0-9]+$"
5 allow_credentials: trueProduction setup
For production with specific known origins:
1cors:
2 enabled: true
3 origins:
4 - https://myapp.example.com
5 allow_credentials: true
6 max_age: 86400 # 24 hoursPublic API setup
For public APIs that don't require credentials:
1cors:
2 enabled: true
3 allow_any_origin: true
4 allow_credentials: false # Cannot use credentials with any originBrowser integration example
Here's a simple example of connecting to Apollo MCP Server from a browser:
1async function connectToMCP() {
2 const response = await fetch("http://127.0.0.1:8000/mcp", {
3 method: "POST",
4 headers: {
5 Accept: "application/json, text/event-stream",
6 "Content-Type": "application/json",
7 "MCP-Protocol-Version": "2025-06-18",
8 },
9 body: JSON.stringify({
10 jsonrpc: "2.0",
11 method: "initialize",
12 params: {
13 protocolVersion: "2025-06-18",
14 capabilities: {},
15 clientInfo: { name: "Browser Client", version: "1.0" },
16 },
17 id: 1,
18 }),
19 });
20
21 // Extract session ID from response headers (automatically exposed)
22 const sessionId = response.headers.get("mcp-session-id");
23
24 // Handle SSE format response (starts with "data: ")
25 const responseText = await response.text();
26 const jsonData = responseText.startsWith("data: ")
27 ? responseText.slice(6) // Remove "data: " prefix
28 : responseText;
29
30 const result = JSON.parse(jsonData);
31 console.log("Connected:", result);
32 console.log("Session ID:", sessionId);
33}
34
35connectToMCP();