Authentication
Authentication
This page details the example found in the /examples/auth
directory, demonstrating how to add a simple authentication layer to an MCP server, typically implemented as middleware in the transport layer.
MCP itself doesn’t prescribe a specific authentication mechanism, allowing flexibility. This example uses a simple token check within HTTP middleware.
Authenticated Server (examples/auth/server
)
This example builds upon the HTTP+SSE transport, adding middleware to check for a valid Authorization
header on incoming HTTP requests (both for the /message
POSTs and the initial /events
SSE connection).
Key parts:
package main
import (
"fmt" // Added for root handler
"log"
"net/http"
"strings"
// ... other imports: server, protocol, types, sse ...
)
// Simple authentication middleware
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authToken := r.Header.Get("Authorization")
// In a real app, validate the token properly!
// This is a placeholder check.
expectedToken := "Bearer my-secret-token"
if authToken != expectedToken {
log.Printf("Auth failed for %s: Invalid token '%s'", r.URL.Path, authToken)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return // Stop processing if auth fails
}
log.Printf("Auth successful for %s", r.URL.Path)
next.ServeHTTP(w, r) // Call the next handler if auth succeeds
})
}
func main() {
// 1. Setup MCP Server (as usual)
serverInfo := types.Implementation{Name: "auth-server", Version: "0.1.0"}
opts := server.NewServerOptions(serverInfo)
srv := server.NewServer(opts)
// Register tools, etc.
// 2. Create SSE Transport Server
sseServer := sse.NewServer(srv, opts.Logger)
// 3. Setup HTTP Handlers
mux := http.NewServeMux()
// Apply middleware *only* to the MCP handlers
authedEventsHandler := authMiddleware(http.HandlerFunc(sseServer.HTTPHandler))
authedMessageHandler := authMiddleware(http.HandlerFunc(srv.HTTPHandler))
mux.Handle("/events", authedEventsHandler)
mux.Handle("/message", authedMessageHandler)
// Add an unauthenticated root handler for testing
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "MCP Auth Server running. Use /events and /message with Authorization header.")
})
// 4. Start HTTP Server
log.Println("Starting Auth MCP server on :8080...")
if err := http.ListenAndServe(":8080", mux); err != nil {
log.Fatalf("HTTP server error: %v", err)
}
}
To Run:
- Navigate to
examples/auth/server
and rungo run main.go
. - Use an MCP client (like the one in
examples/auth/client
) or tools likecurl
to interact:curl -H "Authorization: Bearer my-secret-token" http://localhost:8080/events
(for SSE)curl -X POST -H "Authorization: Bearer my-secret-token" -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "method":"initialize", ...}' http://localhost:8080/message
Requests without the correct Authorization: Bearer my-secret-token
header will receive a 401 Unauthorized
response.