Creates Spring Security configuration class with authentication, authorization, and HTTP protection setup. For securing REST APIs, OAuth2/OIDC login, or JWT resource servers.
npx claudepluginhub amplicode/spring-skills --plugin spring-toolsThis skill uses the workspace's default tool permissions.
Generates a `@Configuration @EnableWebSecurity` class with a `filterChain()` method, DSL chains for authentication and authorization, beans, dependencies, and properties in application.properties.
examples/_beans/jwt-converter/java.mdexamples/_beans/jwt-converter/kotlin.mdexamples/_beans/ldap-auth-manager/java.mdexamples/_beans/ldap-auth-manager/kotlin.mdexamples/_beans/ldap-context-source/java.mdexamples/_beans/ldap-context-source/kotlin.mdexamples/_beans/logout-handler/java.mdexamples/_beans/logout-handler/kotlin.mdexamples/_beans/role-mapper/java.mdexamples/_beans/role-mapper/kotlin.mdexamples/_beans/user-storage/java.mdexamples/_beans/user-storage/kotlin.mdexamples/_dependencies/authorization-server.mdexamples/_dependencies/base.mdexamples/_dependencies/ldap.mdexamples/_dependencies/oauth-client.mdexamples/_dependencies/resource-server.mdexamples/_fragments/anonymous/java.mdexamples/_fragments/anonymous/kotlin.mdexamples/_fragments/authorize-requests/java.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Generates a @Configuration @EnableWebSecurity class with a filterChain() method, DSL chains for authentication and authorization, beans, dependencies, and properties in application.properties.
CRITICAL: Code ONLY from examples/ files. If no matching example -- STOP and ask user. CRITICAL: For questions with a fixed set of choices, prefer
AskUserQuestion> its analogue > plain text list. Plain numbered text lists are the last resort when no interactive tool is available. CRITICAL: Read the conversation context BEFORE running Step 1. Half the questions in Steps 2–3 may already be answered by the user's prompt and prior turns. Re-asking what was already said is the #1 reason this skill feels slow.
| Option | Default | Always ask? | Notes |
|---|---|---|---|
| Authentication type | — | YES | main branching |
| Disable CSRF | no | NO | |
| Disable headers | no | NO | |
| Disable anonymous access | no | NO | |
| Authorization rules | anyRequest().authenticated() | NO | |
| language | from get_project_summary | NO | auto-detected |
| bootVersion | from get_project_summary | NO | auto-detected |
| className | SecurityConfiguration | NO | suggest, confirm only |
| packageName | same as existing @Configuration | NO | auto-detected |
| appPrefix | from existing @Value properties or app | NO | auto-detected from project |
Smart defaults: If user says "use defaults", "all defaults", "default settings", or similar -- skip ALL questions where "Always ask?" = NO. Only ask mandatory questions.
Smart answer recognition: When user provides a value instead of choosing from a numbered list, accept it directly. Examples:
Batch questions: Group closely related questions into a single
AskUserQuestion call (up to 4 questions per call) when they:
Rules:
AskUserQuestion call(Recommended) and place it firstAskUserQuestion for choices; fall back to plain text lists only if the tool is unavailableBefore asking the user any question, attempt to derive the answer from the context already gathered: project summary, module dependencies, existing security configurations, prior turns of this conversation, and the user's original prompt. Only ask when the context yields no clear default or when the choice is genuinely user-specific (e.g. authentication type, authorization rules).
Hierarchy of decisions:
Context is unambiguous → decide silently, do NOT ask.
Examples: language and Boot version from get_project_summary; existing
dependencies from list_module_dependencies; packageName from existing
@Configuration classes; className = SecurityConfiguration; appPrefix
from existing @Value annotations.
Context gives a strong signal → state the decision + alternatives in one line, let the user override or stay silent. Format:
Will create SecurityConfiguration with JWT (spring-boot-starter-oauth2-resource-server found in dependencies).
Alternatives: Form Login, OIDC, LDAP, Custom. OK?
The user can answer "ok" / "yes" / silence → accept; or name an alternative → switch.
Context yields no clear default → ask with AskUserQuestion (preferred), with the recommended option first.
Mark the recommended option with (Recommended) in its label and place
it first. If no interactive choice tool is available, fall back to a
plain text list.
Context is fully empty for a critical input → ask plainly. This applies to: authentication type (when no deps hint at it), authorization rules, variant-specific settings.
AskUserQuestionWhen a question must be asked, prefer the AskUserQuestion tool over
writing a numbered list in the response body. Fall back to plain text only
if no interactive choice tool is available.
Rules for AskUserQuestion calls in this skill:
(Recommended)
appended to the label.header is a 12-char chip label (e.g. "Auth Type", "CSRF", "Headers").When AskUserQuestion is not the right tool:
The question lists in Steps 2–3 and in reference files are a fallback for case 4. They are NOT a script to execute top-to-bottom. If a question's answer is already determined by principles 1–3, skip the question.
Before any MCP call, before any question, re-read the user's prompt and the prior turns of this conversation and extract whatever is already stated. This step costs nothing and prevents the most common failure mode of this skill — asking the user something they already said.
Build a mental checklist of inputs and tick off everything the user has already provided, explicitly or implicitly:
| Input | Look for in the prompt / context |
|---|---|
| authentication type | "JWT", "form login", "OIDC", "Keycloak", "LDAP", "OAuth2", "authorization server" — any direct or implied mention |
| provider | "Keycloak", "Google", "GitHub", "Okta", "AWS Cognito" — implies OIDC or JWT variant |
| authorization rules | "only for ADMIN", "public API", "all endpoints secured" |
| language | Kotlin / Java — also implied by file extensions in discussion |
| className | "name it SecurityConfig", "class name XxxConfiguration" |
| smart defaults | "use defaults", "all defaults", "default settings", "minimal configuration" |
| prior project facts | language, Boot version, dependencies — already known if discussed earlier in this conversation; do not re-fetch |
For every input that is explicitly or strongly implicitly answered: mark it as decided and skip the corresponding question in Steps 2–3. Do NOT ask "Authentication type?" if the user wrote "configure JWT" — JWT is the answer. Do NOT ask language if the user wrote "in Kotlin".
For every input that is not answered: defer to the Decision-making principle above — try to derive it from project context first (Step 1), and only then ask.
Step 0 is mental, not a tool call. Do not announce it to the user. Do not write "Step 0 done". Just internalize what the user already said before proceeding to Step 1.
Call Amplicode MCP tools (in parallel where possible).
| Tool | What to extract | Variable name |
|---|---|---|
get_project_summary | language, springBootVersion, moduleName, buildFile, mainPackage | language, bootMajor, moduleName, buildFile, mainPackage |
list_module_dependencies(moduleName) | artifact IDs | presentDeps |
list_application_properties_files(moduleName) | path to properties file | propsFile |
list_security_configurations | existing security configs | existingConfigs |
list_spring_security_roles | existing roles for authorize rules | existingRoles |
If multi-module project (multiple modules in get_project_summary):
Ask which module to use. Then re-call module-specific MCP tools with that module.
If existingConfigs is not empty:
{className} that does not collide with existing namesDetermine appPrefix: scan existing @Value annotations in the project for a common custom prefix
(e.g. @Value("${myapp.something}") → appPrefix = myapp). If none found, default to app.
Ask:
Authentication type?
1. Form Login (HTTP Session) -- form login with session
2. JWT (OAuth2 Resource Server) -- stateless JWT
3. OAuth2/OIDC Login -- login via external provider (Keycloak, Google, GitHub...)
4. Authorization Server -- own authorization server (Spring Boot >= 3.1)
5. LDAP -- LDAP authentication
6. Custom -- empty filterChain, only common DSL blocks
Map answer to reference file:
references/http-session.mdreferences/jwt.mdreferences/oidc.mdreferences/authorization-server.md (requires bootMajor >= 3.1 — if lower, warn user and ask to choose another type)references/ldap.mdreferences/custom.mdRead the mapped reference file and follow its questions flow. Only asked if user did NOT say "all defaults".
Each reference file specifies:
Read skeleton from examples/_skeletons/{lang}.md where {lang} = java or kotlin (from Step 1)
Create the configuration class file using the skeleton, substituting {packageName} and {className}
Read the reference file for the chosen variant. For each fragment listed:
examples/_fragments/{feature}/{lang}.mdreturn http.build();bootMajor from Step 1 (some fragments have Boot < 3.1 / Boot >= 3.1 sections — use the matching one)DSL ordering inside filterChain method (IMPORTANT — order is VARIANT-DEPENDENT):
See references/common-dsl.md → "Generation Order" for the exact ordering per variant.
Always end with return http.build();
For each bean listed in the reference:
examples/_beans/{bean-type}/{lang}.mdclientRegistrationRepository), add them to the classVariable substitution rules:
{packageName} -> from Step 1 context{className} -> from user or defaultnew org.springframework.security.web.SecurityFilterChain(...)).
When generating code, extract FQNs into import statements and use short class names
in the code body. The generated file must look like normal hand-written code._dependencies/base.md (always)bootMajor from Step 1:
bootMajorspring-boot-starter-oauth2-* → spring-boot-starter-security-oauth2-*spring-security-oauth2-authorization-server:1.1.0 (no starter)presentDeps:
buildFile from Step 1refresh_build_system_model_properties/{variant}/properties.mdBefore writing ANY code, verify:
http.userDetailsService(...) call is present in filterChainbootMajor: Boot 4.x uses spring-boot-starter-security-oauth2-* (not spring-boot-starter-oauth2-*); session-management concurrent sessions API changed in Boot 3.1