Skip to main content

Generate Entry Point

The generateEntryPoint | gep task will generate a module in Infrastructure layer, this task has one required parameter type.
Whether you'll use generic one also parameter name is required.

gradle generateEntryPoint --type=[entryPointType]
gradle gep --type [entryPointType]
TypeNameParameterValuesDefault
genericEmpty Entry Point--nameString-
asynceventhandlerAsync Event Handler--edatrue, falsefalse
--techrabbitmq, kafka, rabbitmq,kafkarabbitmq
graphqlAPI GraphQL--pathgqlString (path)/graphql
kafkaKafka Consumer---
mcpMCP Server (Model Context Protocol)--nameString-
--enable-toolstrue, falsetrue
--enable-resourcestrue, falsetrue
--enable-promptstrue, falsetrue
--enable-securitytrue, falsetrue
--enable-audittrue, falsetrue
mqJMS MQ Client to listen messages---
restmvcAPI REST (Spring Boot Starter Webmvc)--servertomcat, jettytomcat
--authorizationtrue, falsefalse
--versioningHEADER, PATH, NONENONE
--from-swaggerFile pathswagger.yaml
--swaggertrue, falsefalse
rsocketRsocket Controller Entry Point---
sqsSQS Listener---
webfluxAPI REST (Spring Boot Starter WebFlux)--routertrue, falsetrue
--authorizationtrue, falsefalse
--versioningHEADER, PATH, NONENONE
--from-swaggerFile pathswagger.yaml
--swaggertrue, falsefalse
kafkastrimziKafka Strimzi Consumer Entry Point--nameString-
--topic-consumerString (topic name)test-with-registries

Additionally, if you'll use a restmvc, you can specify the web server on which the application will run. By default, Tomcat.

Reference for serverOptionName
tomcatTomcat server (default)
jettyJetty server
gradle generateEntryPoint --type=restmvc --server=[serverOption]
gradle gep --type=restmvc --server=[serverOption]

This task will generate something like that:

πŸ“¦infrastructure
┣ πŸ“‚entry-points
┃ β”— πŸ“‚generic
┃ ┃ ┣ πŸ“‚src
┃ ┃ ┃ ┣ πŸ“‚main
┃ ┃ ┃ ┃ β”— πŸ“‚java
┃ ┃ ┃ ┃ ┃ β”— πŸ“‚[package]
┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚generic
┃ ┃ ┃ β”— πŸ“‚test
┃ ┃ ┃ ┃ β”— πŸ“‚java
┃ ┃ ┃ ┃ ┃ β”— πŸ“‚[package]
┃ ┃ ┃ ┃ ┃ ┃ β”— πŸ“‚generic
┃ ┃ β”— πŸ“œbuild.gradle

Usage Example for Kafka Strimzi Consumer​

gradle generateEntryPoint --type=kafkastrimzi 
gradle gep --type=kafkastrimzi
gradle generateEntryPoint --type=kafkastrimzi --name=myConsumer --topic-consumer=myTopic
gradle gep --type=kafkastrimzi --name=myConsumer --topic-consumer=myTopic

This will generate a specialized entry point for consuming Kafka messages using Strimzi, with custom parameters.

Usage Example for MCP (Model Context Protocol)​

The mcp entry point type generates a reactive MCP server with Tools, Resources, and Prompts capabilities, based on Spring AI.

Basic Command​

gradle generateEntryPoint --type=mcp
gradle gep --type=mcp

Available Parameters​

ParameterValuesDefaultDescription
--nameStringnullMCP Server Name
--enable-toolstrue/falsetrueEnable Tools
--enable-resourcestrue/falsetrueEnable Resources
--enable-promptstrue/falsetrueEnable Prompts
--enable-securitytrue/falsetrueEnable OAuth2/Entra ID Security
--enable-audittrue/falsetrueEnable Audit Logging (requires AOP)

Usage Examples​

# Generate with all capabilities enabled (default: includes security and audit)
gradle generateEntryPoint --type=mcp

# Only Tools
gradle generateEntryPoint --type=mcp --enable-tools=true --enable-resources=false --enable-prompts=false

# Only Resources
gradle generateEntryPoint --type=mcp --enable-tools=false --enable-resources=true --enable-prompts=false

# With custom name
gradle generateEntryPoint --type=mcp --name=BancolombiaAssistant

# Without security (development mode only)
gradle generateEntryPoint --type=mcp --enable-security=false

# Without audit logging
gradle generateEntryPoint --type=mcp --enable-audit=false

Generated Structure​

infrastructure/
└── entry-points/
└── mcp-server/
β”œβ”€β”€ build.gradle
└── src/
β”œβ”€β”€ main/java/[package]/mcp/
β”‚ β”œβ”€β”€ tools/
β”‚ β”‚ β”œβ”€β”€ HealthTool.java
β”‚ β”‚ └── ExampleTool.java
β”‚ β”œβ”€β”€ resources/
β”‚ β”‚ β”œβ”€β”€ SystemInfoResource.java
β”‚ β”‚ └── UserInfoResource.java
β”‚ β”œβ”€β”€ prompts/
β”‚ β”‚ └── ExamplePrompt.java
β”‚ └── audit/ # If audit enabled
β”‚ └── McpAuditAspect.java
└── test/java/[package]/mcp/
β”œβ”€β”€ tools/
β”œβ”€β”€ resources/
β”œβ”€β”€ prompts/
└── audit/ # If audit enabled
└── McpAuditAspectTest.java

applications/
└── app-service/
└── src/
β”œβ”€β”€ main/java/co/com/bancolombia/config/
β”‚ └── McpSecurityConfig.java # If security enabled
└── test/java/co/com/bancolombia/config/
└── McpSecurityConfigTest.java # If security enabled

Generated Components​

Java Classes:

  • HealthTool.java - Health check tool
  • ExampleTool.java - Example tool (echo, add)
  • SystemInfoResource.java - System info resource
  • UserInfoResource.java - Resource template with parameters
  • ExamplePrompt.java - Prompt templates

Tests:

  • HealthToolTest.java
  • ExampleToolTest.java
  • SystemInfoResourceTest.java
  • UserInfoResourceTest.java
  • ExamplePromptTest.java

Security & Audit (if enabled):

  • McpSecurityConfig.java - OAuth2/Entra ID configuration
  • McpSecurityConfigTest.java
  • McpAuditAspect.java - Automatic audit logging
  • McpAuditAspectTest.java

Automatic Configuration​

The command also automatically updates application.yaml with the MCP configuration:

spring:
ai:
mcp:
server:
protocol: "STATELESS"
name: "${spring.application.name}"
version: "1.0.0"
type: "ASYNC"
instructions: |
Reactive MCP Server with capabilities:
- Tools: Executable tools
- Resources: Access to system and user data
- Prompts: Custom conversation templates

Security: Authenticated via Entra ID (Bearer Token)
streamable-http:
mcp-endpoint: "/mcp/${spring.application.name}"
capabilities:
tool: true
resource: true
prompt: true
request-timeout: "30s"
# Security configuration (if --enable-security=true)
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
client-id: ${CLIENT_ID}

jwt:
json-exp-roles: /roles # JSON path for role extraction

Security and Audit Features​

By default, the MCP entry point is generated with security and audit enabled.

Security (McpSecurityConfig)​

When --enable-security=true (default), the generator creates a complete OAuth2/Entra ID security configuration:

  • OAuth2 Resource Server: Validates JWT tokens from Entra ID
  • JWT Validation: Validates audience (aud), app ID (appid), and issuer
  • Role Extraction: Extracts roles from JWT claims using configurable JSON path
  • Method Security: Enables @PreAuthorize annotations for RBAC
  • Public Endpoints: Actuator health and info endpoints remain public
  • Access Denied Logging: Explicitly logs security rejections with user and path details

Dependencies added to app-service:

  • spring-boot-starter-security
  • spring-boot-starter-oauth2-resource-server
  • spring-boot-starter-actuator
  • spring-boot-starter-webflux

Audit Logging (McpAuditAspect)​

When --enable-audit=true (default), the generator creates an AOP aspect that automatically logs all MCP operations:

  • What is audited: All calls to @Tool, @McpResource, and @McpPrompt methods
  • Information logged:
    • Who: Client ID extracted from JWT token (appid, azp, or aud)
    • What: Class, method name, and arguments
    • When: Timestamp (automatic via logging framework)
    • Result: Success or failure
    • Performance: Execution time in milliseconds
  • Reactive Support: Integrates seamlessly with Mono return types
  • Security Context: Extracts authentication details from ReactiveSecurityContextHolder

Dependency added to mcp-server:

  • spring-boot-starter-aop (conditionally added only if audit is enabled)

Example audit log output:

πŸ“Š [AUDIT] TOOL llamado por: a1b2c3d4-client-id | MΓ©todo: ExampleTool.echo | Args: ["hello"]
βœ… [AUDIT] TOOL exitoso | Client: a1b2c3d4-client-id | MΓ©todo: ExampleTool.echo | Tiempo: 45ms

Component Development​

Create a Tool​


@Component
public class CalculatorTool {
@McpTool(name = "multiply", description = "Multiplies two numbers")
public Mono<Integer> multiply(
@McpToolParam(description = "First number", required = true) int a,
@McpToolParam(description = "Second number", required = true) int b) {
return Mono.just(a * b);
}
}

Create a Resource​


@Component
public class ConfigResource {
@McpResource(
uri = "resource://config/app",
name = "app-config",
description = "Application configuration")
public Mono<ReadResourceResult> getConfig() {
return Mono.fromCallable(() -> {
// Implementation
});
}
}

Create a Prompt​


@Component
public class SupportPrompt {
@McpPrompt(
name = "customer-support",
description = "Generates a customer support prompt")
public Mono<GetPromptResult> customerSupport(
@McpArg(name = "issue", required = true) String issue) {
return Mono.fromCallable(() -> {
// Implementation
});
}
}