Skip to content

Bundle external Keboola skills (ai-kit) into the kbagent plugin — start with data-app authoring #375

Description

@padak

Summary

Today the kbagent plugin ships only kbagent's own skill/agent surface. Other
high-value Keboola Claude skills live in a separate marketplace,
keboola/ai-kit ("Claude Kit",
marketplace keboola-claude-kit). The most obvious example is
dataapp-developer, which teaches Claude how to write a Keboola data app —
exactly the half kbagent does not cover.

Proposal: make the kbagent plugin compose selected ai-kit skills so that a
user who installs kbagent gets the full data-app loop — write the code (ai-kit)
+ deploy and operate it (kbagent) — without hunting down a second
marketplace. Data apps are the flagship use case; the mechanism should generalize
to other ai-kit skills (sl-toolkit, component-developer, …).

Background — two marketplaces, complementary halves

Marketplace What it owns for data apps
kbagent keboola-agent-cli (this repo, keboola/cli) Lifecycle via API: data-app create / deploy / start / stop / password / secrets-* / logs / validate-repo, plus references/data-app-workflow.md which encodes the four documented deploy footguns (3-call create contract, PAT encryption, simpleAuth password, transient stopped state).
ai-kit keboola-claude-kit (keboola/ai-kit) Authoring know-how, plugin dataapp-developer (v1.1.0), two skills:
dataapp-dev — Streamlit SQL-first architecture, validate → build → verify loop, MCP schema validation + Playwright verification.
dataapp-deployment — repo structure for the keboola/data-app-python-js Docker base image (nginx :8888, supervisord, keboola-config/, uv sync, the "POST to /" gotcha).

These dovetail almost perfectly:

  • dataapp-deployment documents the keboola-config/ repo structure that
    kbagent's data-app validate-repo already pre-flight-checks.
  • dataapp-dev produces the code that kbagent data-app create then deploys.
  • Right now a user/agent has to discover, add, and install a second
    marketplace to get both halves. That friction is the gap.

Note: ai-kit also ships a keboola-cli plugin, but it wraps the legacy Go
kbc CLI
(kbc-pull / kbc-push / kbc-diff), not kbagent. Worth flagging
as a separate consolidation question (see Open questions), but out of scope for
the data-app pilot.

What the Claude Code plugin system actually allows

Researched against the current docs (code.claude.com/docs/en/plugin-dependencies,
/plugins-reference, /plugin-marketplaces). Relevant primitives:

  1. dependencies in plugin.json (Claude Code ≥ 2.1.110) — a plugin can
    declare other plugins it requires, bare-name or with a semver range:
    "dependencies": ["audit-logger", { "name": "secrets-vault", "version": "~2.1.0" }]
    On install, Claude Code resolves + installs them and enables them
    transitively (≥ 2.1.143).
  2. Cross-marketplace dependencies — by default a dependency resolves within
    the same marketplace
    . To depend on a plugin in another marketplace, the
    root marketplace must allowlist it:
    "allowCrossMarketplaceDependenciesOn": ["keboola-claude-kit"]
    and the dependency entry carries "marketplace": "keboola-claude-kit".
    Critical limitation: "Dependencies from a marketplace you have not added
    are left unresolved."
    A cross-marketplace dep does not auto-add the other
    marketplace — the user must claude plugin marketplace add keboola/ai-kit
    first, otherwise the dependency silently stays unresolved.
  3. git-subdir plugin source — a marketplace entry can point at a
    subdirectory of another git repo (sparse clone):
    "source": { "source": "git-subdir", "url": "https://github.com/keboola/ai-kit.git",
                "path": "plugins/dataapp-developer", "ref": "main" }
    This lets the kbagent marketplace re-export an ai-kit plugin as its own
    entry — so a same-marketplace dependency resolves cleanly with no
    cross-marketplace allowlist and no second marketplace add.
  4. Version resolution is git-tag based ({plugin-name}--v{version}, e.g.
    dataapp-developer--v1.1.0). ai-kit currently has no git tags, and its
    bump-version.sh rewrites every version field in every .json to one
    value — versioning is marketplace-wide and ad-hoc, not per-plugin tags. So any
    version-pinned dependency needs upstream tagging work first; an unpinned
    bare-name dep or a ref/sha-pinned git-subdir works today.

Options

Option A — Cross-marketplace dependency (declarative)

kbagent plugin.json declares dataapp-developer from keboola-claude-kit;
kbagent marketplace.json adds allowCrossMarketplaceDependenciesOn.

  • ➕ ai-kit stays the single source of truth; zero code duplication; clean ownership.
  • ➕ Pulls dataapp-developer's bundled mcpServers (keboola SSE + playwright) with it.
  • ➖ Does not auto-add the ai-kit marketplace → unresolved unless the user adds it manually. Defeats the "one install" goal.
  • ➖ Version pinning needs ai-kit to start tagging per-plugin.

Option B — Re-export via git-subdir + same-marketplace dependency (recommended)

kbagent marketplace.json adds a dataapp-developer entry sourced via
git-subdir from keboola/ai-kit, pinned to a ref/sha. kbagent plugin.json
then depends on it by bare name (same marketplace → no allowlist, no second
marketplace add).

  • ➕ Truly one marketplace, one install; dependency resolves today (no upstream tags needed).
  • ➕ No code copied — sparse clone from ai-kit at install; upstream stays source of truth.
  • ➕ Works with the cross-marketplace limitation instead of fighting it.
  • ➖ kbagent marketplace re-publishes a plugin it doesn't own → ownership ambiguity; we manually bump the pinned ref to adopt upstream changes (explicit, but manual).
  • ➖ Pulls ai-kit's mcpServers (keboola SSE endpoint is hardcoded to us-east4.gcp — needs a stack-agnostic story; see Open questions).

Option C — Vendor (copy the skills into the kbagent plugin)

Copy dataapp-dev + dataapp-deployment into plugins/kbagent/skills/.

  • ➕ Fully self-contained, single install, works even outside the marketplace flow.
  • Drift — two divergent copies; ai-kit ships an update, kbagent silently lags. Violates DRY and the repo's "silent-drift surfaces" discipline (CLAUDE.md §17).
  • ➖ Unclear ownership of the duplicated knowledge.

Option D — Reference-only (status quo+)

kbagent's data-app-workflow.md detects the absence of dataapp-developer and
tells Claude to /plugin install dataapp-developer@keboola-claude-kit.

  • ➕ Zero maintenance, zero drift.
  • ➖ Weakest integration; manual step; the skill may not be loaded at the moment Claude needs it.

Recommendation

Pilot with Option B for dataapp-developer, because it delivers the
"one install, full loop" UX today without depending on ai-kit adopting
per-plugin tags, and keeps ai-kit as the source of truth. Revisit Option A
(cleaner ownership) once ai-kit tags per-plugin releases ({plugin}--v{version})
and we're comfortable asking users to add a second marketplace.

If Option B's "re-export a plugin we don't own" tradeoff is unacceptable to the
ai-kit owners, fall back to Option A + a doctor/onboarding nudge that runs
the marketplace add for the user.

Proposed first step (data-app pilot)

  1. Agree the integration shape with the ai-kit owners (Option A vs B).
  2. Wire the chosen mechanism for dataapp-developer only.
  3. Cross-link the skills: kbagent's data-app-workflow.md references
    dataapp-dev (write the code) and dataapp-deployment (repo structure);
    confirm validate-repo checks match dataapp-deployment's documented
    keboola-config/ layout so the two never contradict.
  4. Add the integration to the mandatory plugin-sync surfaces (CLAUDE.md §17:
    SKILL.md triggers, keboola-expert.md, commands-reference, gotchas).
  5. Document the prerequisite Claude Code version (≥ 2.1.143 for transitive
    enable) in install docs.

Open questions

  • MCP server collision/endpoint: dataapp-developer hardcodes a
    us-east4.gcp Keboola SSE MCP endpoint. kbagent is multi-stack and token-based.
    How do we reconcile a bundled MCP server with kbagent's per-project credentials?
  • Ownership: are the ai-kit owners OK with kbagent re-exporting / depending on
    dataapp-developer? Who bumps the pinned ref on upstream changes?
  • Tagging: will ai-kit adopt per-plugin git tags ({plugin}--v{version})?
    That unblocks clean version-pinned Option A.
  • Scope: data apps first — but sl-toolkit overlaps kbagent's existing
    semantic-layer commands, and ai-kit's keboola-cli (legacy kbc) overlaps
    kbagent's sync. Bundle, consolidate, or leave separate?
  • Distribution mismatch: kbagent is also a pip/uv-installed CLI; the plugin
    dependency mechanism only governs the Claude Code plugin half. Any docs/UX
    implications for CLI-only users?

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions