Sitemap

Spring AI Recipe: Securing an MCP Server with an API Key

--

Tools give agents power. Security determines who gets to use that power.

Press enter or click to view image in full size

In a previous recipe, we built MCP servers and exposed tools over HTTP.

But once your MCP server is accessible over the network, there’s an obvious question: Who is allowed to use it?

In this recipe, we’ll secure a Streamable HTTP MCP server using a simple API key.

NOTE: This recipe has been updated since it’s original publication to reflect changes in Spring AI 2.0.0.

Why Secure an MCP Server?

MCP servers expose capabilities — tools that agents can invoke.

Without security:

  • anyone who can reach your server can use those tools
  • there’s no control over access

Adding an API key is a simple and effective way to:

  • restrict access
  • identify clients
  • protect your MCP server

Adding Dependencies

Start with the Streamable HTTP MCP server from the previous recipe.

Then add Spring Security and MCP server security support:

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springaicommunity:mcp-server-security:0.1.6'

Configuring Security

Define a SecurityFilterChain to require authentication and enable API key support:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) {
return http.authorizeHttpRequests(auth ->
auth.anyRequest().authenticated())
.with(McpApiKeyConfigurer.mcpServerApiKey(),
(apiKey) -> {
apiKey.apiKeyRepository(apiKeyRepository());
})
.build();
}
private ApiKeyEntityRepository<ApiKeyEntityImpl> apiKeyRepository() {
var apiKey = ApiKeyEntityImpl.builder()
.name("demo api key")
.id("agent1")
.secret("somesecret")
.build();
return new InMemoryApiKeyEntityRepository<>(List.of(apiKey));
}
}

A few important things are happening here:

  • All requests require authentication
  • API key authentication is enabled
  • A repository of valid API keys is configured

How API Key Authentication Works

Each request must include an HTTP header containing the API key. The value is derived from the ID and the secret. Generically “<id>.<secret>”. Specific to this example, the key is “agent1.somesecret”. This value is checked against entries in the ApiKeyEntityRepository.

Customizing the Header Name

By default, the header name is “X-API-Key”. But you can change it if needed:

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) {
return http.authorizeHttpRequests(auth ->
auth.anyRequest().authenticated())
.with(McpApiKeyConfigurer.mcpServerApiKey()
.headerName("X-MCP-API-KEY"), // <--Custom Header Name
(apiKey) -> {
apiKey.apiKeyRepository(apiKeyRepository());
})
.build();
}

Trying It Out

Start your MCP server and connect using either MCP Inspector or MCPJam:

First Attempt (Without API Key)

Click Connect. It will fail. But that’s expected. Authentication is now required.

Adding the API Key

Open the Authentication panel in MCP Inspector or edit the server in MCPJam to add the API Key as a custom header.

Under Custom Headers, add:

  • Header Name: X-API-Key (or your custom header name
  • Value: agent1.somesecret

Then try to connect again. This time, it should succeed. Now you can:

  • list tools
  • invoke them
  • interact with the server

Production Considerations

This example uses an in-memory API key repository for simplicity.

In a real application, you would likely:

  • store API keys in a database
  • implement your own ApiKeyEntityRepository
  • rotate or revoke keys as needed

What’s more, InMemoryApiKeyEntityRepository uses BCrypt which is computationally expensive. Just one more reason to create your own ApiKeyEntityRepository implementation for production use.

Key Takeaway

With just a small amount of configuration, you’ve added:

  • authentication
  • access control
  • protection for your MCP tools

Your MCP server is no longer just accessible — it’s secure.

In an upcoming recipe, you’ll see how to secure an MCP server with OAuth.

You can find the code for this recipe and my other Spring AI recipes at https://github.com/habuma/spring-ai-recipes.

If you’re exploring Spring AI, I’ve written a book (Spring AI in Action) that covers the core foundations — and I’ll continue sharing newer patterns like this here as the ecosystem evolves. You can find my book on the publisher’s website, at Amazon, or anywhere you buy technical books.

--

--

Craig Walls
Craig Walls

Written by Craig Walls

Author Spring AI in Action, Spring in Action, and Build Talking Apps for Alexa