plugins/lt-offers/skills/creating-offers/SKILL.md
Creates and edits business offers on the lenne.tech Offers platform (angebote.lenne.tech) and its demo deployment (demo-angebote.lenne.tech). Knows all 16 content block types, offer lifecycle (draft/sent/viewed/template), custom HTML with Tailwind CSS and NuxtUI components (via rich-component block). Activates when working with offers, content blocks, or the Offers API. Uses MCP tools (offers-api for production, offers-api-demo for demo) for all CRUD operations.
npx skillsauth add lennetech/claude-code creating-offersInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill enables Claude Code to create, optimize, and manage business offers on the lenne.tech Offers platform via MCP tools.
order values must be ascending without gaps — Gaps in the sequence (e.g., 1, 3, 5) cause rendering glitches on the offers frontend. When deleting a block, re-normalize remaining orders; when inserting, pick the next consecutive integer. The API does not validate this — the bug only surfaces client-side.global-ref block type is NOT listed in the standard MCP tool catalog — It's created automatically by the /offers:create workflow when a block is promoted to the offers repository. Users attempting to use it directly via create_offer will get a schema error. The workflow guards this via the @lenne.tech git email check.offers-api and offers-api-demo MCP OAuth cookies are tied to the current Claude session and tracked per-server. Resuming an earlier offers session (via --resume) often hits a 401 on the first MCP call without a clear error. Re-authenticate by running a trivial MCP tool first. The first call against offers-api-demo triggers its own OAuth flow even if offers-api is already authenticated.git config user.email detection is fragile — The reusable-block detection uses this to gate the lenne.tech-only flow. It fails for developers with a non-@lenne.tech email configured locally (CI machines, temporary clones, rebased-from-fork setups). The step silently skips in those cases, which is the intended fail-safe.isTemplate: true cannot be mark_sent. Attempting to publish a template silently returns the unchanged offer. To publish, first create_from_template to produce a regular offer, then send that one.| User Intent | Correct Skill |
|------------|---------------|
| Create/edit offers via MCP | THIS SKILL |
| Develop the offers codebase (API/Frontend) | generating-nest-servers / developing-lt-frontend |
| Deploy offers infrastructure | devops |
Works closely with:
generating-nest-servers — For backend development on the offers APIdeveloping-lt-frontend — For frontend development on the offers appAll offer operations go through one of two MCP servers — the platform ships a production and a demo deployment:
| MCP Server | URL | When to use |
|---|---|---|
| offers-api | https://api.angebote.lenne.tech/mcp | Default. Production — real customer-facing offers. |
| offers-api-demo | https://api.demo-angebote.lenne.tech/mcp | Demo stage — sandbox for prospect demos. Use when the user mentions "demo", "Demo-Angebot", "demo-angebote", "Demo-Stage", or "Demo-Umgebung". |
Routing rule. If the user prompt mentions "demo" in an offers context, route ALL tool calls in that prompt to offers-api-demo. Otherwise — including for ambiguous prompts — default to offers-api (production). The UserPromptSubmit hook emits a one-line stage hint that names the correct server; honor that hint.
Both connections use OAuth 2.1 with automatic browser-based login. The OAuth session is per-MCP-server, so the first call against offers-api-demo triggers its own browser-auth flow even if offers-api is already authenticated.
When working inside the offers project repository (local development), the project-level .mcp.json overrides offers-api to http://localhost:3000/mcp so production-flavored tool calls hit your local API. offers-api-demo is unaffected — still points at the deployed demo stage — which is useful for testing demo-only flows from a local dev environment.
Available MCP Tools (identical on both servers):
add_lottie_animation — Upload a Lottie JSON file and create a lottie content block in one atomic call (validates the JSON, rejects unsupported features, ≤ 2 MB)add_offer_source — Add a source (text/link/file) to an offercreate_from_template — Create offer from templatecreate_knowledge — Create a knowledge base entrycreate_offer — Create new offer (returns offer + access code). Accepts an optional theme: { enabled, light, dark } per-offer overridedelete_knowledge — Delete a knowledge base entrydelete_offer — Delete offer permanentlyduplicate_offer — Clone offer with new slug + access code (theme is carried over)generate_snippet — Generate sharing text with link + access codeget_default_theme — Read the app-wide default theme that the renderer applies to offers without their own themeget_global — Get global block with versionsget_knowledge — Get a knowledge base entry with full contentget_offer — Get offer with all content blocks (globals auto-resolved). Returns the effective theme — i.e. the per-offer override when enabled, otherwise the settings default merged in transparentlyget_offer_analytics — Get offer analytics (views, downloads, scroll depth, dwell time)get_offer_context — Get full AI context (knowledge + globals + optional offer/sources)get_offer_sources — Get all sources for an offerlist_globals — List reusable global content blockslist_knowledge — List knowledge base entrieslist_offers — List offers (with optional status filter)list_templates — List template offersmark_draft — Reset to draft (sent → draft)mark_sent — Mark offer as sent (draft → sent)remove_offer_source — Remove a source from an offerset_default_theme — Configure the app-wide default theme (light/dark hex palettes). Admin-only on the underlying SettingsServiceupdate_knowledge — Update a knowledge base entryupdate_lottie_animation — Replace the Lottie JSON of an existing block (keeps the block ID + position; resets first-frame snapshot)update_offer — Update offer fields and content blocks. Accepts an optional theme to set/clear the per-offer paletteupload_knowledge_file — Upload file to knowledge entry (base64)upload_offer_source_file — Upload file as offer source (base64)${CLAUDE_SKILL_DIR}/reference/content-blocks.md — All 17 block types with schemas (incl. lottie)${CLAUDE_SKILL_DIR}/reference/offer-model.md — Offer model, status lifecycle, per-offer theme field${CLAUDE_SKILL_DIR}/reference/knowledge-base.md — Knowledge base schema and categories${CLAUDE_SKILL_DIR}/reference/custom-html-guide.md — HTML + Tailwind + NuxtUI guide (incl. WYSIWYG editor)${CLAUDE_SKILL_DIR}/reference/theming.md — Per-offer theme override, app-wide default theme, MCP & UI workflows${CLAUDE_SKILL_DIR}/reference/best-practices.md — Content structure and examplesget_offer_context → Company knowledge + global blocksadd_offer_source / upload_offer_source_filecreate_offerget_offer / update_offermark_sent → generate_snippetget_offer with the offer IDupdate_offer with improved content blocksThis feature is exclusively for lenne.tech developers. Before evaluating reusable blocks, silently run git config user.email and check if the result contains @lenne.tech. If not, skip this entire section without any mention — the user must not see any hint of this feature.
command -v git >/dev/null 2>&1 && git config user.email 2>/dev/null | grep -q '@lenne.tech'
@lenne.tech email → skip silently@lenne.tech email → proceed with reusable block evaluationDuring offer creation or optimization, evaluate whether any content block could be useful across multiple offers (e.g., company introduction, standard team section, recurring FAQ, legal disclaimers, standard CTA). If so:
list_globals MCP toolglobal-ref block pointing to the new global ID via update_offerThe offers platform repository is hosted at: https://gitlab.lenne.tech/intern/offers
Workflow:
~/code/lenneTech/offers, ~/projects/offers, or use find / locate)git clone https://gitlab.lenne.tech/intern/offersgenerating-nest-servers / developing-lt-frontend skills for codebase changesUse get_offer_analytics to check how an offer performs. In Claude Desktop, an interactive dashboard with KPI cards, charts, and download stats renders directly in the chat.
get_offer_analytics with the offer IDupdate_offer with optimized blocks| Metric | Interpretation |
|--------|---------------|
| totalViews | How many times the offer was opened |
| avgScrollDepth | How far customers scroll (< 50% = content needs restructuring) |
| avgTimeOnPage | Engagement level (< 30s = not reading, > 5min = very engaged) |
| pdfDownloadCount | PDF saves (high = serious interest) |
| attachmentDownloads | Per-file download tracking |
| timeToFirstViewHours | Response time after sharing |
pricing-table block for prices, not inline textfileId values. No file upload via MCP yet.order from 0)visible: true unless intentionally hiddenvalidUntil date is set if offer has an expirationdevelopment
Single source of truth for the lenne.tech fullstack production-readiness checklist. Defines the eight pillars (configuration & secrets, observability & logging, health & lifecycle, security hardening, data durability, resilience under load, deployment hygiene, runbook & rollback) with concrete file/line evidence requirements per pillar, severity classification (Critical / Major / Minor), and a canonical machine-parseable report block. Activates whenever an agent or command needs to gate a release on production-readiness — currently used by /lt-dev:production-ready, lt-dev:production-readiness-orchestrator, and the devops-reviewer (read-only). NOT for OWASP-style code-level security review (use security-reviewer). NOT for npm dependency audits (use maintaining-npm-packages).
development
Single source of truth for executing GitLab CI/CD pipelines locally with the same image, env vars, and service containers as the real runner — so pipeline failures are caught before push. Defines pipeline discovery (.gitlab-ci.yml + includes), per-job execution via gitlab-runner exec, service-container orchestration (Mongo, Redis, MailHog), env injection without secrets, cache/artifact handling, and a job-by-job verdict report. Also describes the GitHub Actions equivalent via act for projects that mirror to GitHub. Activates whenever an agent or command needs to validate that the CI pipeline will pass — currently used by /lt-dev:production-ready and lt-dev:production-readiness-orchestrator. NOT for running the local check script (use running-check-script). NOT for writing or refactoring CI configs (use the devops agent).
development
Single source of truth for designing, running, and interpreting k6 load tests against lenne.tech fullstack APIs. Defines installation paths (brew, docker, npm), the three canonical scenarios (smoke / load / soak), endpoint discovery from the generated SDK, realistic Better-Auth login flows, threshold defaults for ~10 concurrent users (p95 < 500ms, error rate < 1%, http_req_failed < 1%), result interpretation, and the optimisation ladder when the system fails (DB indices, query rewrites, caching, connection pool sizing, rate-limit relaxation, payload trimming). Activates whenever an agent or command needs to validate that the API is stable for ~10 concurrent users performing many actions in short time, or to detect performance regressions via k6. Currently used by /lt-dev:production-ready, lt-dev:production-readiness-orchestrator, and lt-dev:performance-reviewer. NOT for Lighthouse frontend performance (use a11y-reviewer). NOT for unit performance assertions (use the test runner directly).
tools
Migrates lenne.tech projects from the legacy jest+eslint+prettier toolchain to the current vitest+oxlint+oxfmt baseline used by nest-server-starter and nuxt-base-starter. Covers swc decoratorMetadata config, the @Prop union-type fix for SWC, supertest default-import correction, ESM/CJS interop, the Nitro PORT-vs-NITRO_PORT bug, ANSI escape stripping in workspace runners (lerna/nx), free-port logic for check-server-start.sh, the offers-pattern config.env.ts (NSC__-only + fail-fast + auto-derived appUrl), and the multi-phase check-envs.sh smoke test. Activates whenever someone is migrating an existing project to the new toolchain, debugging "Cannot determine a type for the X field" Mongoose errors, ERR_SOCKET_BAD_PORT crashes from check-server-start, or wants to align an existing project with the current starter conventions.