Authentication and headers
On this page
Prove who’s calling
DeepWiki and other public MCP servers accept any caller, which is consistent with their purpose. As soon as you expose your own tools, things change: without authentication, anyone who guesses the URL can query your CRM or trigger your processes. xAI provides two parameters to address this—authorization for the access token, and headers or extra_headers for everything else.
The authorization parameter
It sends an authentication token to the MCP server. Specifically, the string you provide is placed as is in the HTTP Authorization header of every request sent to that server.
mcp(
server_url="https://api.example.com/mcp",
server_label="internal",
authorization="Bearer sk-your-token-here"
)
The expected format depends entirely on the target server, because authorization accepts any string: the MCP server validates it, not xAI. Three forms cover almost all cases you’ll encounter.
- Bearer token:
"Bearer sk-xxxx"— the most common, used by the majority of REST APIs - API key:
"ApiKey your-key"— some services use a custom prefix - Basic auth:
"Basic base64(user:password)"— basic authentication encoded in base64
Since this token goes with every request, handling it requires care. Never hardcode it in your source: a secret written in a versioned file eventually ends up in a repository, a log, or a screenshot. Always use an environment variable. If the server allows, prefer a scoped token that only opens the tools you actually need—this is the server-side counterpart to the allowed_tool_names restriction. And plan for regular rotation, especially in production, where an eternal token is a token that will eventually leak.
import os
mcp(
server_url="https://api.example.com/mcp",
server_label="internal",
authorization=f"Bearer {os.getenv('MCP_SERVER_TOKEN')}"
)
headers and extra_headers
The token answers the question “who are you”. Many servers need additional answers: for which organization, on which environment, with which API version. This information passes via the headers parameter, or extra_headers depending on the SDK.
mcp(
server_url="https://api.example.com/mcp",
server_label="internal",
authorization="Bearer sk-token",
headers={
"X-Organization-Id": "org-123",
"X-Project-Id": "proj-456"
}
)
The most common case is multi-tenant platforms, where the same endpoint serves multiple clients and relies on a header to route the request to the right data. Next comes API versioning, with a header like "X-API-Version": "2024-01" that pins a specific version and protects you from server changes. Some systems also expect tracking metadata—session ID, agent ID—to trace the origin of calls, or rate limiting headers that determine the applied billing plan.
The parameter name varies depending on the interface you use. The native xAI SDK uses headers in most cases; the OpenAI-format Responses API may require extra_headers, to avoid any collision with headers that this SDK manages automatically for itself. The behavior, however, is exactly the same: headers are added to every request to the MCP server. If your requests go out without your headers, check this parameter name first before looking elsewhere.
A complete production configuration
Here’s how these parameters assemble with those from previous lessons, in a realistic internal server case.
from xai_sdk.tools import mcp
import os
tools = [
mcp(
server_url="https://api.monentreprise.com/mcp",
server_label="internal",
server_description="Internal tools: CRM, documentation, tickets",
authorization=f"Bearer {os.getenv('INTERNAL_MCP_TOKEN')}",
headers={
"X-Organization-Id": os.getenv("ORG_ID"),
"X-Environment": "production"
},
allowed_tool_names=["search_docs", "get_ticket", "search_contacts"]
)
]
This configuration connects to the internal MCP server over HTTPS, authenticates with a Bearer token stored in an environment variable, sends the organization ID in a header, and restricts access to three read operations. Note that each line locks a different aspect: encryption protects transport, the token proves identity, the header defines the data scope, and the allowlist limits potential damage. None of these layers replaces the others.
Key takeaways
authorizationsends the access token to the MCP server via the HTTP Authorization header- Always store your tokens in environment variables, never hardcoded in code
headers/extra_headersadd extra HTTP headers to every request- Headers serve multi-tenant identification, API versioning, and tracking
- Combine authentication and tool restriction for maximum security