Skip to content

[backend/frontend] feat(mcp): add embed native MCP server with Streamable HTTP transport (#5219)#5220

Open
SamuelHassine wants to merge 11 commits intomasterfrom
issue/5219
Open

[backend/frontend] feat(mcp): add embed native MCP server with Streamable HTTP transport (#5219)#5220
SamuelHassine wants to merge 11 commits intomasterfrom
issue/5219

Conversation

@SamuelHassine
Copy link
Copy Markdown
Member

@SamuelHassine SamuelHassine commented Mar 24, 2026

Summary

Embeds a native Model Context Protocol (MCP) server directly into OpenAEV, exposing 29 adversarial exposure validation tools via the Streamable HTTP transport (MCP spec 2025-03-26).

Any MCP-compatible AI client (Claude Desktop, Cursor, Filigran Copilot, etc.) can now connect directly to OpenAEV at POST /api/mcp and interact with scenarios, assets, payloads, and findings -- no intermediary platform required.

Closes #5219

Changes

Backend (openaev-api)

  • New config/McpServerConfig.java: Spring @Configuration that registers HttpServletStreamableServerTransportProvider as a Servlet bean mapped to /api/mcp/*. Creates a McpSyncServer with all 29 tools.
  • New rest/mcp/McpToolProvider.java: All 29 SyncToolSpecification definitions. Each tool handler extracts the Bearer token from the request and calls the internal REST API via shared Spring RestTemplate. Includes path traversal protection (validatePathSegment + UriComponentsBuilder), case-insensitive Bearer handling, auth exception on missing token, and runtime MCP enabled check via DB setting.
  • New rest/settings/form/SettingsMcpUpdateInput.java: Settings update DTO.
  • Modified pom.xml: Added io.modelcontextprotocol.sdk:mcp-core and mcp-json-jackson2 (Jackson 2.x compatible with Spring Boot 3.5).
  • Modified PlatformSettingsApi.java: Added PUT /api/settings/platform_mcp endpoint.
  • Modified PlatformSettings.java: Added platformMcpEnabled field.
  • Modified PlatformSettingsService.java: Read/write MCP setting from DB.
  • Modified SettingKeys.java: Added PLATFORM_MCP_ENABLED enum constant.

Frontend (openaev-front)

  • Modified profile/Index.jsx: New "MCP access" section on the user profile page showing the endpoint URL and a ready-to-copy JSON configuration snippet for MCP clients.
  • Modified settings/Parameters.tsx: Admin toggle for MCP server enable/disable.
  • Modified actions/Application.ts: MCP settings update action.
  • Modified utils/api-types.d.ts: TypeScript types for MCP settings.
  • Modified utils/lang/en.json and fr.json: Added MCP-related translation keys.

Tools exposed (29)

Category Tools
Assets search_openaev_assets, get_openaev_asset, search_openaev_asset_groups, get_openaev_asset_group
Teams & Players search_openaev_teams, get_openaev_team, search_openaev_players
Attack Patterns search_openaev_attack_patterns, get_openaev_attack_pattern
Scenarios search_openaev_scenarios, get_openaev_scenario, create_openaev_scenario, update_openaev_scenario, delete_openaev_scenario
Payloads create_openaev_payload, get_openaev_payload, search_openaev_payloads
Injects add_openaev_inject_to_scenario, search_openaev_injector_contracts, get_openaev_injector_contract
Testing create_openaev_atomic_testing
Findings search_openaev_findings, get_openaev_vulnerability
Search full_text_search_openaev
Reference Data list_openaev_kill_chain_phases, list_openaev_tags, list_openaev_domains
Exercises search_openaev_exercises, get_openaev_exercise

Test plan

  • Verify POST /api/mcp returns proper JSON-RPC responses
  • Test tools/list returns all 29 tools with correct schemas
  • Test tools/call for search, CRUD, and scenario operations
  • Verify authentication is enforced (401 without token)
  • Verify MCP access section appears on user profile page
  • Test copy configuration button works correctly
  • Verify MCP can be disabled via admin settings toggle
  • Verify path traversal protection rejects malicious IDs

…port (#5219)

Adds a native Model Context Protocol (MCP) server to OpenAEV, exposing 29 tools
for adversarial exposure validation via the Streamable HTTP transport. Any
MCP-compatible AI client (Claude Desktop, Cursor, Filigran Copilot, etc.) can now
connect directly to OpenAEV and interact with scenarios, assets, payloads, and
findings.

Backend:
- New POST /api/mcp endpoint using io.modelcontextprotocol.sdk:mcp Java SDK
- HttpServletStreamableServerTransportProvider registered as Servlet bean
- Auth via existing TokenAuthenticationFilter (Bearer token)
- 29 tools calling internal REST API with user context
- Configurable via openaev.mcp.enabled (default: true)

Frontend:
- New MCP access section on user profile page
- Shows endpoint URL and ready-to-copy client configuration
- Translation keys for en/fr locales

Made-with: Cursor
@github-actions github-actions bot added the filigran team use to identify PR from the Filigran team label Mar 24, 2026
@savacano28 savacano28 changed the title [backend/frontend] Embed native MCP server with Streamable HTTP transport [backend/frontend] feat(mcp) : add embed native MCP server with Streamable HTTP transport (#5219) Mar 24, 2026
@savacano28 savacano28 changed the title [backend/frontend] feat(mcp) : add embed native MCP server with Streamable HTTP transport (#5219) [backend/frontend] feat(mcp): add embed native MCP server with Streamable HTTP transport (#5219) Mar 24, 2026
@SamuelHassine SamuelHassine requested a review from Copilot March 24, 2026 11:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Embeds an MCP (Model Context Protocol) server into OpenAEV (backend) and exposes connection details in the user profile (frontend), enabling MCP-compatible clients to call OpenAEV tools over Streamable HTTP.

Changes:

  • Add embedded MCP server configuration and register a servlet at /api/mcp/*.
  • Implement 29 MCP tools that proxy to existing internal REST APIs for parity and permission enforcement.
  • Add “MCP access” section in the profile page and introduce related EN/FR translations.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
openaev-api/src/main/java/io/openaev/config/McpServerConfig.java Registers MCP transport servlet and builds the MCP sync server (feature-flagged).
openaev-api/src/main/java/io/openaev/rest/mcp/McpToolProvider.java Defines 29 MCP tools and internal HTTP proxy helpers.
openaev-api/pom.xml Adds MCP SDK BOM + core/Jackson2 modules.
openaev-front/src/admin/components/profile/Index.jsx Adds UI section to display MCP endpoint + copyable client config.
openaev-front/src/utils/lang/en.json Adds MCP-related translation keys (EN).
openaev-front/src/utils/lang/fr.json Adds MCP-related translation keys (FR).

…ttings toggle

- Add path traversal protection with validatePathSegment() and UriComponentsBuilder
- Use shared Spring RestTemplate bean instead of creating a new instance
- Fix Bearer token case-insensitive check
- Throw exception on missing authentication instead of silent failure
- Use constants for hardcoded payload source strings
- Fix empty string validation for Command payload fields
- Fix clipboard API error handling in frontend
- Add platform_mcp_enabled DB-backed setting (SettingKeys + PlatformSettings)
- Add PUT /api/settings/platform_mcp endpoint
- Add MCP toggle in admin Parameters page
- Check MCP enabled at runtime in tool handlers
- Add rate limiting TODO note

Made-with: Cursor
@RomuDeuxfois
Copy link
Copy Markdown
Member

@SamuelHassine Impossible to run the back-end on my side

Do we need this lib or I am missing something ?
com.networknt
json-schema-validator
1.5.7

Caused by: java.lang.NoClassDefFoundError: com/networknt/schema/dialect/Dialects
	at io.modelcontextprotocol.json.schema.jackson.DefaultJsonSchemaValidator.<init>(DefaultJsonSchemaValidator.java:45)
	at io.modelcontextprotocol.json.schema.jackson.DefaultJsonSchemaValidator.<init>(DefaultJsonSchemaValidator.java:40)
	at io.modelcontextprotocol.json.schema.jackson.JacksonJsonSchemaValidatorSupplier.get(JacksonJsonSchemaValidatorSupplier.java:26)
	at io.modelcontextprotocol.json.schema.jackson.JacksonJsonSchemaValidatorSupplier.get(JacksonJsonSchemaValidatorSupplier.java:17)
	at io.modelcontextprotocol.json.schema.JsonSchemaInternal.lambda$createDefaultValidator$1(JsonSchemaInternal.java:55)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
	at java.base/java.util.stream.Streams$StreamBuilderImpl.tryAdvance(Streams.java:397)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:280)
	at java.base/java.util.ServiceLoader$ProviderSpliterator.tryAdvance(ServiceLoader.java:1499)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at io.modelcontextprotocol.json.schema.JsonSchemaInternal.createDefaultValidator(JsonSchemaInternal.java:61)
	at io.modelcontextprotocol.json.schema.JsonSchemaInternal.getDefaultValidator(JsonSchemaInternal.java:30)
	at io.modelcontextprotocol.json.schema.JsonSchemaValidator.getDefault(JsonSchemaValidator.java:61)
	at io.modelcontextprotocol.server.McpServer$StreamableSyncSpecification.build(McpServer.java:867)
	at io.openaev.config.McpServerConfig.mcpServer(McpServerConfig.java:62)
	at io.openaev.config.McpServerConfig$$SpringCGLIB$$0.CGLIB$mcpServer$0(<generated>)
	at io.openaev.config.McpServerConfig$$SpringCGLIB$$FastClass$$1.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:348)
	at io.openaev.config.McpServerConfig$$SpringCGLIB$$0.mcpServer(<generated>)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:146)
	... 23 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.networknt.schema.dialect.Dialects
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	... 52 common frames omitted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

filigran team use to identify PR from the Filigran team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Embed native MCP server (Model Context Protocol) with Streamable HTTP transport

3 participants