This project implements the “Parametric Collapse” strategy to consolidate multiple tool classes into a single, generic KeycloakTool class. This design pattern significantly reduces tool proliferation and improves API maintainability.
Before the implementation, the project had 7+ separate tool classes:
UserTool (9 methods)RealmTool (3 methods)ClientTool (9 methods)RoleTool (2 methods)GroupTool (5 methods)IdentityProviderTool (3 methods)AuthenticationTool (6 methods)This resulted in 37+ individual tool methods exposed through the MCP protocol, creating a cluttered API surface.
The new KeycloakTool class consolidates all operations into:
executeKeycloakOperation()KeycloakOperation (45+ values)params containing operation-specific arguments
KeycloakTool
(Single Unified Tool Class)
+ executeKeycloakOperation()
- operation: KeycloakOperation
- params: JSON
Routes to appropriate service
UserService RealmService ...etc
{
"operation": "GET_USERS",
"params": {
"realm": "quarkus"
}
}
{
"operation": "CREATE_USER",
"params": {
"realm": "quarkus",
"username": "jdoe",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"password": "SecurePass123!"
}
}
{
"operation": "ADD_ROLE_TO_USER",
"params": {
"realm": "quarkus",
"userId": "1eed6a8e-a853-4597-b4c6-c4c2533546a0",
"roleName": "admin"
}
}
{
"operation": "RESET_PASSWORD",
"params": {
"realm": "quarkus",
"userId": "1eed6a8e-a853-4597-b4c6-c4c2533546a0",
"newPassword": "NewSecurePass456!",
"temporary": false
}
}
{
"operation": "GET_REALMS",
"params": {}
}
{
"operation": "CREATE_REALM",
"params": {
"realmName": "my-new-realm",
"displayName": "My New Realm",
"enabled": true
}
}
{
"operation": "GET_CLIENTS",
"params": {
"realm": "quarkus"
}
}
{
"operation": "CREATE_CLIENT",
"params": {
"realm": "quarkus",
"clientId": "my-app",
"redirectUris": "http://localhost:8080/*"
}
}
{
"operation": "GENERATE_CLIENT_SECRET",
"params": {
"realm": "quarkus",
"clientId": "my-app"
}
}
{
"operation": "GET_GROUPS",
"params": {
"realm": "quarkus"
}
}
{
"operation": "CREATE_GROUP",
"params": {
"realm": "quarkus",
"groupName": "Developers"
}
}
{
"operation": "CREATE_SUBGROUP",
"params": {
"realm": "quarkus",
"parentGroupId": "abc123",
"subGroupName": "Backend Developers"
}
}
{
"operation": "GET_AUTHENTICATION_FLOWS",
"params": {
"realm": "quarkus"
}
}
{
"operation": "GET_FLOW_EXECUTIONS",
"params": {
"realm": "quarkus",
"flowAlias": "browser"
}
}
GET_USERS - List all users in a realmGET_USER_BY_USERNAME - Find a user by usernameGET_USER_BY_ID - Get user by IDCREATE_USER - Create a new userDELETE_USER - Delete a userUPDATE_USER - Update user detailsGET_USER_GROUPS - Get groups for a userADD_USER_TO_GROUP - Add user to groupREMOVE_USER_FROM_GROUP - Remove user from groupGET_USER_ROLES - Get roles for a userADD_ROLE_TO_USER - Assign role to userREMOVE_ROLE_FROM_USER - Remove role from userRESET_PASSWORD - Reset user passwordSEND_VERIFICATION_EMAIL - Send verification emailCOUNT_USERS - Count users in realmGET_REALMS - List all realmsGET_REALM - Get specific realmCREATE_REALM - Create new realmGET_CLIENTS - List all clientsGET_CLIENT - Get specific clientCREATE_CLIENT - Create new clientDELETE_CLIENT - Delete a clientGENERATE_CLIENT_SECRET - Generate new client secretGET_CLIENT_ROLES - Get client rolesCREATE_CLIENT_ROLE - Create client roleDELETE_CLIENT_ROLE - Delete client roleGET_REALM_ROLES - List realm rolesGET_REALM_ROLE - Get specific realm roleGET_GROUPS - List all groupsGET_GROUP_MEMBERS - Get group membersCREATE_GROUP - Create new groupUPDATE_GROUP - Update groupDELETE_GROUP - Delete groupCREATE_SUBGROUP - Create subgroupGET_IDENTITY_PROVIDERS - List identity providersGET_IDENTITY_PROVIDER - Get specific identity providerGET_IDENTITY_PROVIDER_MAPPERS - Get IDP mappersGET_AUTHENTICATION_FLOWS - List authentication flowsGET_AUTHENTICATION_FLOW - Get specific flowCREATE_AUTHENTICATION_FLOW - Create new flowDELETE_AUTHENTICATION_FLOW - Delete flowGET_FLOW_EXECUTIONS - Get flow executionsUPDATE_FLOW_EXECUTION - Update flow executionThe KeycloakTool directly injects and uses all service classes:
UserServiceRealmServiceClientServiceRoleServiceGroupServiceIdentityProviderServiceAuthenticationServiceAll operations are wrapped in try-catch blocks with:
io.quarkus.logging.LogToolCallExceptionUses Jackson ObjectMapper for:
If you were using the old individual tool classes, here is how to migrate:
@Tool(description = "Get all users from a keycloak realm")
String getUsers(String realm)
executeKeycloakOperation(
KeycloakOperation.GET_USERS,
"{\"realm\": \"quarkus\"}"
)
To add a new operation:
KeycloakOperation:
public enum KeycloakOperation {
// ... existing operations
MY_NEW_OPERATION
}
executeKeycloakOperation():
case MY_NEW_OPERATION:
return myService.myNewMethod(
paramsNode.get("param1").asText(),
paramsNode.get("param2").asInt()
);
UserTool {
getUsers()
createUser()
deleteUser()
...
}
ClientTool {
getClients()
createClient()
deleteClient()
...
}
// 7+ more tool classes...
KeycloakTool {
executeKeycloakOperation(
operation: KeycloakOperation,
params: JSON
)
}
The AI model sees 1 tool definition instead of 37+ tool definitions, making it:
To test the implementation:
# Compile the project
mvn clean compile
# Run tests
mvn test
# Build the native executable
mvn package -Pnative
The Parametric Collapse strategy successfully reduced the Keycloak MCP Server from 37+ individual tools to 1 unified tool, while maintaining all functionality and improving maintainability. This pattern can be applied to any domain where you have multiple similar operations that can be categorized and parameterized.