Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ jobs:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Sync PRs from jfrog-skills lead with [patch]/[minor]/[major] so the
# plugin release workflow ships on merge. Parse that prefix, then the
# conventional type (chore, feat, …).
headerPattern: '^(?:\[(?:patch|minor|major)\]\s+)?(\w*)(?:\(([\w$.\-*/ ]*)\))?: (.*)$'
headerPatternCorrespondence: type, scope, subject
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The JFrog plugin provides the following capabilities, grouped by component:
| --- | --- | --- |
| **MCP** | JFrog Platform MCP server | Registers the remote JFrog Platform MCP (`https://${JFROG_PLATFORM_URL}/mcp`, OAuth) into OpenCode's `config.mcp.jfrog`. Authenticate once with `opencode mcp auth jfrog`. Opt out with `JFROG_MCP_DISABLE=true`. |
| **Skill** | JFrog Platform | Interact with Artifactory repositories, builds, permissions, users, access tokens, projects, release bundles, and platform administration via the JFrog CLI and REST/GraphQL APIs. Also covers security audits, CVE lookups, and Advanced Security exposure queries. |
| **Skill** | Package safety & download | Check whether npm, Maven, PyPI, Go, and other packages are safe, curated, or allowed, then download them through Artifactory remote caches or curation-aware package managers. |
| **Skill** | Package curation | Check whether npm, Maven, PyPI, Go, and other packages are safe, curated, or allowed, then download them through Artifactory remote caches or curation-aware package managers. |
| **Skill** | Agent Guard | OpenCode manages MCPs through the JFrog Agent Guard. Discover, install, configure, update, and remove MCP servers from the JFrog AI Catalog approved for your project, and authenticate to remote HTTP MCPs via OAuth, API key, or bearer token. |

The skills ship **with the plugin** (vendored and pinned) — they are **not** downloaded
Expand All @@ -29,7 +29,7 @@ Before installing, make sure you have:
- **JFrog host** — A [JFrog Platform](https://jfrog.com) instance you can authenticate against, exposed to the plugin as `JFROG_PLATFORM_URL` (e.g. `mycompany.jfrog.io`). The JFrog Platform MCP server authenticates via OAuth (browser sign-in).
- **OpenCode** — Installed (verified against OpenCode **1.17.7** and newer, which honors `config.skills.paths` in object form).
- **Node.js** (≥ 18) — with `npx` on your `PATH` (used by the Agent Guard).
- **Skill runtime requirements** — `jf` CLI, `jq`, and `curl` on `PATH`, plus a configured JFrog CLI server. For the minimum versions, see the upstream skills [`Requirements`](https://github.com/jfrog/jfrog-skills/blob/v0.22.0/README.md#requirements). Configure the CLI with `jf login` / `jf config add` — see [Authentication](#authentication).
- **Skill runtime requirements** — `jf` CLI, `jq`, and `curl` on `PATH`, plus a configured JFrog CLI server. For the minimum versions, see the upstream skills [`Requirements`](https://github.com/jfrog/jfrog-skills/blob/v0.31.1/README.md#requirements). Configure the CLI with `jf login` / `jf config add` — see [Authentication](#authentication).
- **JFrog AI Catalog** (optional) — If you want to use the Agent Guard feature, your JFrog subscription needs to include the AI Catalog entitlement. Contact your JFrog account team if you're unsure whether it's enabled.
- **JFrog CLI ≥ 2.105.0** (optional) — If you want the Agent Guard to auto-resolve the credentials/server ID from the JFrog CLI configuration.
- **JFrog project** (optional) — If you want to use the Agent Guard feature.
Expand Down Expand Up @@ -162,7 +162,7 @@ grouped by capability.
| "Create a scoped access token for CI." | Creates an access token with the requested scope. |
| "Promote this release bundle to production." | Uses Lifecycle / Distribution APIs to promote the bundle. |

### Package safety & download skill
### Package curation skill

| Ask the agent… | What happens |
| --- | --- |
Expand Down
7 changes: 4 additions & 3 deletions VENDOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ The result is a flat, committed tree:
```
skills/
jfrog/SKILL.md (+ references/ scripts/ assets/)
jfrog-package-safety-and-download/SKILL.md
jfrog-setup-package-managers/SKILL.md
jfrog-ai-catalog-skills/SKILL.md
jfrog-ai-catalog/SKILL.md
jfrog-init/SKILL.md
jfrog-mcp-management/SKILL.md
jfrog-package-curation/SKILL.md
jfrog-reference-architecture/SKILL.md
jfrog-setup-package-managers/SKILL.md
```

> **Note:** the exact set of skill directories is whatever the pinned `jfrog/jfrog-skills` release
Expand Down
2 changes: 1 addition & 1 deletion mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ forbid() {

require "dist/index.js"
require "skills/jfrog/SKILL.md"
require "skills/jfrog-package-safety-and-download/SKILL.md"
require "skills/jfrog-package-curation/SKILL.md"

forbid "(^|/)[^/]*-TEST-PLAN\\.md$"
forbid "(^|/)[^/]*-TEST-RESULTS\\.md$"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
---
name: jfrog-ai-catalog-skills
name: jfrog-ai-catalog
description: >-
Discover, install, manage, and publish agent skills hosted in the JFrog AI
Catalog (Artifactory skills repositories) using the JFrog CLI (`jf skills`)
and the JFrog Agent Guard. Lists and searches available skills (catalog-wide
or scoped to a project), shows a skill's versions and which repos host it,
installs the latest or a pinned version, verifies the install, lists
installed skills, updates and removes them, and publishes (uploads) a local
skill bundle and releases new versions.
Use when the user asks what skills are available or installed, to
search/browse the catalog, to install/update/uninstall a skill, to see a
skill's versions, or to publish/upload/release a skill to JFrog /
Artifactory / the AI Catalog.
Discover, search, install, update, remove, and publish agent skills and
plugins hosted in the JFrog AI Catalog (Artifactory) via the JFrog CLI
(`jf skills`, `jf agent plugins`) and JFrog Agent Guard. Use whenever the
user asks what skills or plugins are available or installed, wants to
browse/search the catalog, see versions, install/update/uninstall/delete a
skill or plugin, or publish/upload/release one to JFrog / Artifactory / the
AI Catalog.
metadata:
role: workflow
---

# JFrog AI Catalog Skills
# JFrog AI Catalog

Discover, install, and manage agent skills from the JFrog AI Catalog
(Artifactory skills repositories), and publish your own skills back to it, all
through the JFrog CLI (`jf skills`) and the JFrog Agent Guard.
Discover, install, and manage agent skills and agent plugins from the JFrog AI
Catalog (Artifactory skills/plugins repositories), and publish your own back to
it, all through the JFrog CLI (`jf skills`, `jf agent plugins`) and the JFrog
Agent Guard.

## Choose a reference file

Expand All @@ -32,6 +29,10 @@ Pick the row matching the user's intent and read that reference file.
| Install or update a skill (latest or a pinned version), or a download is blocked | [references/installing-skills.md](references/installing-skills.md) |
| "What's installed?" / remove an installed skill | [references/managing-installed-skills.md](references/managing-installed-skills.md) |
| Publish / upload / release a skill to the catalog | [references/publishing-skills.md](references/publishing-skills.md) |
| "What plugins are available?" / browse the plugin catalog / list plugin versions / search plugins | [references/discovering-plugins.md](references/discovering-plugins.md) |
| Install or update a plugin (latest or a pinned version) | [references/installing-plugins.md](references/installing-plugins.md) |
| "What plugins are installed?" / remove an installed plugin | [references/managing-installed-plugins.md](references/managing-installed-plugins.md) |
| Publish / upload / release a plugin to the catalog | [references/publishing-plugins.md](references/publishing-plugins.md) |

## Prerequisites

Expand All @@ -43,6 +44,12 @@ Pick the row matching the user's intent and read that reference file.
- The [server selection rules](../jfrog/SKILL.md#server-selection-rules-mandatory)
— resolve the default `<SID>` once and reuse it, pass `--server-id <SID>`
after the subcommand on every `jf` call, and use one server per request.
**Resolve it now, before any `jf` call:**
```bash
jf config show 2>/dev/null \
| awk '/^Server ID:/{id=$NF} /^Default:[[:space:]]*true/{print id; exit}'
# stdout: the default server-id; if empty, stop and ask which server to use
```
- The stop-on-error rule — on any `jf` failure, stop and never switch servers.

One addition specific to this skill: never `cat` or parse
Expand All @@ -57,16 +64,30 @@ Pick the row matching the user's intent and read that reference file.
as your `jf` calls. Agent Guard also reads `JFROG_URL` / `JF_URL` directly when
set, so make sure the `<SID>` you resolved points at that same host.
- **Resolve the project (`<PROJECT>`) only when needed.**
It is required for `--list-skills`, `--list-skill-versions`, and
`--provision-skills-repository`. Take it from `JF_PROJECT` or the user.
It is required for `--list-skills`, `--list-skill-versions`,
`--provision-skills-repository`, `--list-agent-plugins`,
`--list-agent-plugin-versions`, and `--provision-agent-plugins-repository`.
Resolve it with this priority:
1. Parse `~/.jfrog/setup.json` (if present) and read `.servers["<SID>"].currentActiveProject`.
2. Fall back to `$JF_PROJECT`.
3. If still empty, ask the user for the project key - do **not** guess.

```bash
PROJECT=$(jq -r --arg sid "<SID>" '.servers[$sid].currentActiveProject // empty' \
~/.jfrog/setup.json 2>/dev/null)
[ -z "$PROJECT" ] && PROJECT="${JF_PROJECT:-}"
```
There is no non-admin way to look up or validate project keys (the
`/access/api/v1/projects` list endpoint needs admin), so you cannot
silently correct a display name to a key. If the value looks like a
display name (spaces, mixed case) rather than a short slug, ask the
user to confirm the project **key** specifically. Never assume
`default`, never invent one. Install, update, remove, and publishing to
an explicit `--repo` are keyed by skill **name** and/or **repo**, not a
project.
an explicit `--repo` are keyed by skill/plugin **name** and/or **repo**,
not a project.
- **Bundle manifests differ by type.** Skill bundles require `SKILL.md`
in the bundle root; plugin bundles require `plugin.json`. Validate the
correct file before installing or publishing.

## Workflow overview

Expand All @@ -76,10 +97,14 @@ flowchart TD
B -->|No| C[Ask user to install jf CLI, then continue]
B -->|Yes| D{Intent}
C --> D
D -->|List all / versions| E[npx @jfrog/agent-guard --list-skills]
D -->|Install / update| F[Resolve slug + version, then jf skills install/update]
D -->|List installed / remove| G[jf skills list / rm -rf install dir]
D -->|Publish| H[Resolve/provision repo, validate bundle, jf skills publish]
D -->|List all skills / versions| E[npx @jfrog/agent-guard --list-skills]
D -->|Install / update skill| F[Resolve slug + version, then jf skills install/update]
D -->|List installed skills / remove| G[jf skills list / rm -rf install dir]
D -->|Publish skill| H[Resolve/provision repo, validate bundle, jf skills publish]
D -->|List all plugins / versions| I[npx @jfrog/agent-guard --list-agent-plugins]
D -->|Install / update plugin| J[Resolve slug + version, then jf agent plugins install/update]
D -->|List installed plugins / remove| K[jf agent plugins list / rm -rf install dir]
D -->|Publish plugin| L[Resolve/provision repo, validate bundle, jf agent plugins publish]
```

## Gotchas
Expand All @@ -100,3 +125,6 @@ the reference files above.
- **Use the response templates verbatim**: where a reference file gives a "reply
using this exact template" block, fill the placeholders and send exactly that,
with the same wording every time and no extra preamble or commentary.
- **Plugins have no Xray support**: skip all Xray-related handling (no 403
gating on download, no inline scan on publish, no `--skip-scan` flag) when
performing any `jf agent plugins` operation.
83 changes: 83 additions & 0 deletions skills/jfrog-ai-catalog/references/discovering-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Discovering plugins

List-all and versions go through the **Agent Guard**.

## List plugins (page through the catalog)

```bash
npx --yes --registry <REGISTRY_URL> @jfrog/agent-guard \
--list-agent-plugins --project "<PROJECT>" [--name <PATTERN>] [--server "<SID>"] [--page-size <N>] [--cursor <C>] [--format json]
```

| Flag | Required | Purpose |
|------|----------|---------|
| `--project <PROJECT>` | **Yes** | AI Catalog project to list. |
| `--name <PATTERN>` | No | Find plugins by name: server-side, case-insensitive substring, scoped to the project. |
| `--server <SID>` | No | jf CLI config entry to authenticate with (defaults to the resolved single server). |
| `--page-size <N>` | No | Results per page. Pass `50` to stay bounded. The Agent Guard defaults to 500 if omitted. |
| `--cursor <C>` | No | Continuation cursor from a previous page's JSON, to fetch the next page. |
| `--format json` | No | Raw page JSON instead of the default compact TSV (name + last-updated). |

Request a bounded page with `--page-size 50 --format json`, present those plugins,
then read `exhausted` and `cursor` from the response. If `exhausted` is `false`
there are more. Tell the user and offer to fetch the next page with
`--cursor <cursor>`. Do not silently page through the whole catalog.

**Presenting results (use this exact format).** Render the plugins as this table,
sorted by name, and nothing else (no commands, URLs, flags, or cursors):

| Plugin | Last updated |
|--------|-------------|
| `<name>` | `<lastUpdated>` |

For a `--name` search with no matches, reply with one line instead:

> No plugins match "`<query>`".

To offer a follow-up (a plugin's versions or repos), ask in plain language
("want the versions for one of these?") and run the command yourself.

## List a repo's plugins

To see what is published in one specific plugins repository (for example, to check
a repo before or after publishing to it), list it directly with the CLI. This is
repo-scoped (Artifactory registry contents), unlike `--list-agent-plugins`, which is
project-scoped:

```bash
jf agent plugins list --repo "<repo>" --server-id "<SID>" --format json
```

Never run a bare `jf agent plugins list` (it errors): always pass `--repo <key>` here, or
`--harness <h>` for installed plugins (see `managing-installed-plugins.md`).

**Presenting results (use this exact format).** Render the plugins as this table,
sorted by name, and nothing else (no commands, URLs, or flags):

Plugins in `<repo>`:

| Plugin | Version | Description |
|--------|---------|-------------|
| `<name>` | `<version>` | `<description>` |

Include the **Description** column only when the listing provides one (drop it if
every plugin's description is empty). If the repo holds no plugins, reply with one
line instead:

> No plugins published in `<repo>`.

## A plugin's versions and hosting repos

```bash
npx --yes --registry <REGISTRY_URL> @jfrog/agent-guard \
--list-agent-plugin-versions --project "<PROJECT>" --agent-plugin "<slug>" [--server "<SID>"] [--page-size <N>] [--cursor <C>] [--format json]
# JSON: versions[].version, versions[].locations[].repoKey (page through with cursor like above)
```

**Presenting versions (use this exact format).** Newest version first:

Versions of `<slug>`:

| Version | Hosted in |
|---------|-----------|
| `<version>` | `<repoKey>`[, `<repoKey>`…] |
Loading
Loading