Install
$ agentstack add skill-kentico-xperience-by-kentico-kenticopilot-automation-action-create ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
You implement a custom automation process action in an Xperience by Kentico project — a step type that appears in the Automation Builder and runs Execute for every contact (or other processed object) that reaches it.
What you must produce
- A class extending
CMS.Automation.AutomationAction(no properties) orCMS.Automation.AutomationAction(with properties). - An assembly-level
[assembly: RegisterAutomationAction(identifier, displayName, IconName = ..., Description = ...)]. - If properties: a
TPropertiesclass implementingCMS.Automation.IAutomationActionPropertieswith form-component-annotated public read/write properties, in its own file (Properties.cs) — not co-located in the action's file. - If the action shares cross-step state: an
IAutomationProcessDataimplementation with a uniquestatic abstract string Identifier. - If the project uses
.resxlocalization inRegister*attributes (look for"{$...$}"strings): the new display name, description, and labels in the existing.resx, referenced via the{$...$}syntax.
Steps
1. Read context
- Read
references/guardrails.md— code quality guardrails beyond the API spec. - Study
references/example-actions.md— canonical action samples covering distinct patterns (service injection, typedHttpClient, cross-step process data, no-properties actions). Mirror their structure and conventions, including one class per file. - Fetch the action API contract from the live documentation via the Kentico Docs MCP — the Custom automation steps page listed in
references/docs.mdis authoritative for the base classes, theRegisterAutomationActionattribute and its parameters (identifier,displayName, optionalIconName,Description), identifier constraints, theAutomationProcessContext(processed contact viaGetProcessedObject, process name, trigger data, cross-stepGetProcessData/SetProcessData), andIAutomationProcessData. Do not rely on memorized API shapes — confirm against the page. - Fetch the supplementary docs listed in
references/docs.mdvia the Kentico Docs MCP as needed (form-component reference, visibility conditions, validation rules — seereferences/docs.mdfor the catalog of pages worth fetching on demand).
2. Discover the project and the surrounding APIs
- Search for
AutomationAction,INotificationEmailMessageProvider) before calling its methods — check the actual method signatures, return types, and whether they are sync or async. Do not assume. - If the action integrates with an external service (Twilio, Slack, HubSpot, Salesforce, a webhook, an SDK, etc.) — briefly research that service's documentation and request shape (via Kentico Docs MCP for Kentico-side concerns, and via WebSearch/WebFetch for the third-party API). Enough to make the SDK call or HTTP payload look realistic, including: the canonical SDK entry point or HTTP endpoint, required authentication shape, the request body, and how the provider signals errors / duplicates. Capture credentials in a typed
*Optionsclass bound toappsettings.json— never onTProperties.
3. Confirm the design
Walk through assets/ACTION_TEMPLATE.md with the user in chat — identifier, display name, icon, tooltip, base class, properties (name, type, form component, default, validation rules, visibility conditions), runtime behavior (inputs, side effects, failure handling), injected dependencies, and any IAutomationProcessData types the action reads or writes. Do not save the template to disk — it is an in-chat scaffold, not an artifact.
Ask only what you cannot reasonably infer. Propose defaults the user can override.
4. Implement
Write the files following these rules (full detail in guardrails.md):
- One class per file: the action, its
TProperties, eachIAutomationProcessData, and any typed*Optionseach go in their own file named after the class. - Constructor injection for dependencies; verify every injected service is registered with the DI container.
- Use
ILoggerfor logging — notIEventLogService. - Never
.Result/.Wait(); no static mutable state; no per-execution state in instance fields. - Retrieve the processed contact with
ContactInfo contact = await context.GetProcessedObject(cancellationToken);(extension method inCMS.ContactManagement) — see the canonical pattern inguardrails.md. Do not readcontext.ProcessedObjectdirectly; it is not part of the public API. - External calls keyed by a stable identifier on the cast contact (typically
ContactInfo.ContactID; preferContactInfo.ContactGUIDwhen the external system needs a globally stable key) for idempotency. - No secrets in
TProperties— read them fromIConfiguration/IOptions. - Outbound HTTP uses typed
HttpClientregistered withservices.AddHttpClient(). - Prefer declarative validation attributes (
RequiredValidationRule,MaxLengthValidationRule,MinimumIntegerValueValidationRule,MaximumIntegerValueValidationRule,MinimumDecimalValueValidationRule, ...) onTPropertiesinstead of hand-rolled checks inExecute. ReserveExecutevalidation for cross-property or runtime conditions only. - Form-component attributes and validation rules come from
Kentico.Xperience.Admin.Base.FormAnnotations(plusKentico.Xperience.Admin.Content.FormAnnotationsandKentico.Xperience.Admin.DigitalMarketing.FormAnnotationsfor content- and marketing-specific selectors). Do not importKentico.Forms.Web.Mvc— that namespace contains obsolete classes with matching names (ValidationRule,RegisterFormValidationRule, ...) for the live-site Form Builder, which is the wrong API surface here.
5. Verify
- Run
dotnet buildon the web project. - Confirm the identifier is unique in the solution (grep the identifier string).
- If you added
.resxstrings, confirm the.resxand its registration class compile.
Report what you produced and the manual steps (if any) the user still owes — typically registering a new dependency in DI or adding a configuration value to appsettings.json.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Kentico
- Source: Kentico/xperience-by-kentico-kenticopilot
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.