170 lines
11 KiB
Plaintext
170 lines
11 KiB
Plaintext
# Use agents and skills.sh
|
|
|
|
An external agent creates one widget at a time with the Homarr MCP server. The agent harness manages the list for multiple widgets.
|
|
|
|
Homarr does not create widget packs or drafts for multiple widgets.
|
|
|
|
The MCP API key must belong to a Homarr administrator. Non-administrator keys do not list Custom Widget tools, prompts,
|
|
or resources. The same administrator requirement applies to the matching HTTP authoring endpoints.
|
|
|
|
<a className="button button--primary" href="https://www.skills.sh/homarr-labs/homarr/homarr-custom-widget">
|
|
View the Custom Widget Skill on skills.sh
|
|
</a>
|
|
|
|
Install the Agent Skill from the verified Homarr repository:
|
|
|
|
```sh
|
|
npx skills add https://github.com/homarr-labs/homarr --skill homarr-custom-widget
|
|
```
|
|
|
|
The portable skill gives concise authoring guidance. For connected agents, Homarr returns the complete `SKILL.md` and
|
|
all bundled skill references once in one lazy tool response. The Homarr MCP prompt then gives the agent a
|
|
retrieval workflow: read the live schema and fetch only the component documentation needed for the widget.
|
|
|
|
The workbench's **Copy AI prompt** action is separate. It creates a self-contained prompt below 12,000 characters for an ordinary ChatGPT or Claude conversation. It includes the lean contract, bindings, recommended components, and two polished examples. It never tells an offline model to call MCP tools.
|
|
|
|
The source is in [`.agents/skills/homarr-custom-widget`](https://github.com/homarr-labs/homarr/tree/HEAD/.agents/skills/homarr-custom-widget). `HEAD` follows the repository default branch, so the link is not tied to an unreleased feature branch. Homarr does not provide a ZIP archive.
|
|
|
|
After publication, run the installation command once. This action registers installation activity.
|
|
|
|
Then, verify the skills.sh page. Request official maker attribution for `homarr-labs` from skills.sh.
|
|
|
|
Repository code cannot give this attribution.
|
|
|
|
## Get MCP resources
|
|
|
|
- Prompt: `homarr-custom-widget-author`
|
|
- Resources: `homarr://custom-widgets/schema`, `components`, `components/{name}`, `examples/{name}`, and `skill`
|
|
- HTTP: `GET /api/custom-widgets/authoring-prompt`, `schema`, `components`, and `skill`
|
|
|
|
The authoring-prompt tool description contains one sentence. The prompt contains the workflow instructions and resource links.
|
|
|
|
`GET /api/custom-widgets/skill` and `customWidget_getSkill` return a self-contained structured skill payload:
|
|
|
|
```ts
|
|
{
|
|
name: "homarr-custom-widget";
|
|
version: string;
|
|
skillMd: string; // Complete SKILL.md
|
|
references: Record<string, string>;
|
|
skillsShUrl: string;
|
|
sourceUrl: string;
|
|
installCommand: string;
|
|
}
|
|
```
|
|
|
|
The `homarr://custom-widgets/skill` MCP resource returns the same `SKILL.md` and references once as bundled Markdown.
|
|
|
|
The component catalog is a compact index of names, categories, safety levels, shared prop names, policies, and example
|
|
IDs. Per-component results contain only component-specific props and a reference to shared prop documentation. Use
|
|
`customWidget_getSharedProps` once with only the shared prop names needed across the selected components. This avoids
|
|
repeating hundreds of global props in every tool result. The catalog is deliberately not embedded in the skill or
|
|
clipboard prompt; the skill response still contains the complete authoring, schema, runtime, and security references.
|
|
|
|
These interfaces do not return an archive URL or archive hash.
|
|
|
|
## Create a Custom Widget with MCP
|
|
|
|
1. Load `customWidget_getSkill`, then get the prompt and live schema.
|
|
2. Call `customWidget_getComponentCatalog`, followed by `customWidget_getComponent` for only the relevant installed
|
|
components and `customWidget_getExample` when one catalog example matches the interaction pattern. Fetch at most
|
|
eight component documents before the first validation (or four after a complete example already matches). If shared
|
|
props are needed, collect their catalog names and call `customWidget_getSharedProps` once for that set.
|
|
3. Read the external API documentation.
|
|
4. Build one definition, using `templateLines` for multiline JSX tool input.
|
|
5. Validate the definition without saving it and repair every reported issue.
|
|
6. Create a preview session.
|
|
7. Run `customWidget_previewQuery` for every query returned by the preview and inspect its actual status and data shape. Assistant conversations retain a bounded response preview so large APIs cannot exhaust the model context. Use
|
|
`{}` for load queries; manual queries require exactly the returned primitive `parameterNames`.
|
|
8. Test relevant actions in simulation mode.
|
|
9. Open the returned preview path with browser tools.
|
|
10. Inspect the redacted journal and revise the local candidate until validation, data, and rendering all work. Keep the
|
|
exact tested preview candidate locally. Any definition, template, or source change requires a new validation and preview;
|
|
earlier query evidence belongs to the previous preview revision.
|
|
11. Create the widget from that final tested preview with `customWidget_createFromPreview`. The preview session already carries
|
|
the source URLs and encrypted credentials supplied during preview; the create call accepts only its session ID plus an
|
|
optional target board and persists that tested preview.
|
|
12. Open its returned management path, and use a structured question when the user must choose whether to place it on a board.
|
|
13. Otherwise, ask the user to configure the saved definition with the ten-minute Homarr source-setup URL.
|
|
14. Create a final preview with the saved definition ID so Homarr loads its stored credentials, then test it again.
|
|
15. Update the saved definition if the final verification finds a problem. `customWidget_update` also accepts
|
|
`templateLines` for multiline JSX without resetting omitted options.
|
|
16. Repeat the procedure for the next widget.
|
|
|
|
Successful validation returns a compact summary instead of echoing the full widget and template. Preview creation
|
|
returns its session, links, and query checklist without repeating the submitted definition. Keep the candidate locally
|
|
and reuse it for the next lifecycle step.
|
|
|
|
Each source-configuration URL applies to one definition or preview and one source. It is short-lived, single-use, and
|
|
can only be opened and completed by an authenticated Homarr administrator. The administrator confirms the server URL,
|
|
network scope, and required credential fields directly in Homarr. The agent receives only request status and never
|
|
receives plaintext credentials. Preview-scoped values expire with that preview; definition-scoped values persist.
|
|
|
|
Agents can install existing widgets without regenerating them:
|
|
|
|
1. Search with `customWidget_workshopSearch`.
|
|
2. Inspect and validate a result with `customWidget_workshopGet`.
|
|
3. Install it with `customWidget_workshopInstall`.
|
|
4. Configure deployment-specific URLs and supplied credentials with `customWidget_sourceConfigure`.
|
|
5. If the agent does not have those values, call `customWidget_configurationRequestUser` and wait for completion.
|
|
6. Test the installed definition, then use `board_addItem` with kind `customApi` and the returned definition ID.
|
|
|
|
Homarr encrypts the plaintext immediately. Homarr does not return the plaintext.
|
|
|
|
## Evaluate the copied prompt
|
|
|
|
Homarr maintainers can run the same self-contained prompt that the workbench copies through the live generation-quality suite:
|
|
|
|
```sh
|
|
OPENROUTER_API_KEY=... pnpm --filter @homarr/custom-widgets test:ai
|
|
```
|
|
|
|
The manifest suite covers nine complex and public-API prompts. Its deterministic fixture-backed cases include a fake
|
|
homelab health API, CoinMarketCap's keyless public API, Bored, Agify, and a multi-request Pokédex. Before the configured
|
|
model judges a result, the candidate must pass Homarr's real clipboard parser, canonical schema, and deterministic
|
|
checks for documented endpoints, authentication, request triggers, query bindings, response fields, and essential
|
|
runtime components.
|
|
|
|
To exercise the real Assistant lifecycle instead of accepting a returned JSON block, run:
|
|
|
|
```sh
|
|
OPENROUTER_API_KEY=... pnpm --filter @homarr/custom-widgets test:assistant-ai
|
|
```
|
|
|
|
The same suites can target the Homarr provider with a Workshop PocketBase token instead of an OpenRouter key:
|
|
|
|
```sh
|
|
AI_PROVIDER_BASE_URL=https://homarr.dev/api/ai/v1 \
|
|
AI_PROVIDER_API_KEY=<workshop-token> \
|
|
AI_PROVIDER_MODEL=homarr/model \
|
|
pnpm --filter @homarr/custom-widgets test:assistant-ai
|
|
```
|
|
|
|
`AI_PROVIDER_JUDGE_MODEL` can select a separate judge when the configured endpoint offers one. The Homarr provider
|
|
offers exactly one model, so generation and review both use `homarr/model`.
|
|
|
|
The assistant test exposes the same lazy skill, live schema, component catalog, targeted component references,
|
|
validation, preview-query, and create-from-preview tools as the product. It refuses to save a definition that was not
|
|
validated exactly or whose preview queries were not all tested. Multi-request fixtures return a different payload for
|
|
each documented path and require manual-query parameters. Use `--case=pokedex`, `--case=coinmarketcap-keyless`,
|
|
`--case=bored-activity`, or `--case=agify-name` for a focused run.
|
|
|
|
Both suites use the configured provider models for generation and harsh review. They save tool traces, validated
|
|
manifests, raw reviews, and detailed category scores under
|
|
`packages/custom-widgets/.ai-evaluations/`. These live tests are maintainer-invoked rather than CI-required because
|
|
they consume a configured provider account and exercise a nondeterministic model. The repository's ordinary tests
|
|
cover the lifecycle enforcement, fixture routing, score calculation, and failure behavior without network access.
|
|
|
|
Each scenario stops as soon as it passes and has a hard limit of ten generation attempts. Override the endpoint,
|
|
models, or per-scenario limit with `AI_PROVIDER_BASE_URL`, `AI_PROVIDER_API_KEY`, `AI_PROVIDER_MODEL`,
|
|
`AI_PROVIDER_JUDGE_MODEL`, and
|
|
`CUSTOM_WIDGET_AI_MAX_LOOPS`. Generated artifacts are local and ignored by Git; promote a reviewed, validated result
|
|
into the bundled-widget source deliberately.
|
|
|
|
The reference API check uses a real PokeAPI list/detail request and a read-only Portainer container query when `PORTAINER_BASE_URL` and `PORTAINER_API_KEY` are set. Use `pnpm --filter @homarr/custom-widgets test:reference-apis -- --pokeapi-only` for the public PokeAPI check alone. To exercise start, restart, and stop against a disposable container, also set `PORTAINER_TEST_CONTAINER_ID` and the explicit safeguard `PORTAINER_ALLOW_MUTATIONS=1`; the script restores the container's original running state.
|
|
|
|
Use `pnpm --filter @homarr/custom-widgets test:reference-apis -- --public-ai-apis-only` to verify the live Bored and
|
|
CoinMarketCap response shapes used by the assistant fixtures. The same command also verifies Agify when
|
|
`AGIFY_API_KEY` is configured; otherwise it reports the authenticated check as skipped without weakening the
|
|
deterministic Agify fixture tests.
|