Skip to content

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

@padak

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions