diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index b859fa4..d49261b 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "JFrog Platform plugins for Cursor", - "version": "0.3.4", + "version": "0.4.0", "pluginRoot": "plugins" }, "plugins": [ diff --git a/plugins/jfrog/.cursor-plugin/plugin.json b/plugins/jfrog/.cursor-plugin/plugin.json index f5bd7e3..e92f4df 100644 --- a/plugins/jfrog/.cursor-plugin/plugin.json +++ b/plugins/jfrog/.cursor-plugin/plugin.json @@ -1,8 +1,8 @@ { "name": "jfrog", "displayName": "JFrog Platform", - "version": "0.3.4", - "description": "JFrog Platform integration with MCP, security skills, supply-chain best practices, and JFrog MCP Gateway governance for adding, removing, and listing MCP servers.", + "version": "0.4.0", + "description": "JFrog Platform integration with MCP, security skills, supply-chain best practices, and JFrog Agent Guard governance for adding, removing, and listing MCP servers.", "author": { "name": "JFrog", "email": "devrel@jfrog.com" @@ -14,10 +14,12 @@ "xray", "security", "mcp", - "mcp-gateway", + "agent-guard", "supply-chain", "devops", - "artifacts" + "artifacts", + "mcp", + "ai-catalog" ], "logo": "assets/logo.svg", "skills": ["skills/jfrog/SKILL.md"], diff --git a/plugins/jfrog/scripts/inject-instructions.mjs b/plugins/jfrog/scripts/inject-instructions.mjs index c031c87..8f6438f 100755 --- a/plugins/jfrog/scripts/inject-instructions.mjs +++ b/plugins/jfrog/scripts/inject-instructions.mjs @@ -20,11 +20,11 @@ const env = (newName, oldName) => process.env[newName] ?? process.env[oldName]; const forceDisabled = - env("_JF_AGENT_GUARD_FORCE_DISABLE", "_JF_MCP_GATEWAY_FORCE_DISABLE") === "true"; + env("_JF_AGENT_GUARD_FORCE_DISABLE") === "true"; const forceEnabled = - env("JF_AGENT_GUARD_FORCE_ENABLE", "JF_MCP_GATEWAY_FORCE_ENABLE") === "true"; + env("JF_AGENT_GUARD_FORCE_ENABLE") === "true"; -async function isGatewayEnabledViaSettings() { +async function isAgentGuardEnabledViaSettings() { const baseUrl = env("JFROG_URL", "JF_URL"); const token = env("JFROG_ACCESS_TOKEN", "JF_ACCESS_TOKEN"); if (!baseUrl) { @@ -40,7 +40,7 @@ async function isGatewayEnabledViaSettings() { baseUrl.replace(/\/+$/, "") + "/ml/core/api/v1/administration/account-settings/mcp_gateway_plugin_enabled"; - debug(`Fetching gateway setting from ${url}`); + debug(`Fetching agent guard setting from ${url}`); const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); @@ -60,7 +60,7 @@ async function isGatewayEnabledViaSettings() { } const data = await response.json(); const enabled = data?.settings?.mcpGatewayPluginEnabled?.value === true; - debug(`Settings response indicates gateway enabled=${enabled}`); + debug(`Settings response indicates agent guard enabled=${enabled}`); return enabled; } catch (error) { const reason = error?.name === "AbortError" ? "timeout" : error?.message ?? "unknown error"; @@ -77,8 +77,8 @@ if (forceDisabled) { process.exit(0); } else if (forceEnabled) { debug("Force-enable flag is set."); -} else if (!(await isGatewayEnabledViaSettings())) { - debug("Gateway not enabled; exiting without injecting instructions"); +} else if (!(await isAgentGuardEnabledViaSettings())) { + debug("Agent Guard not enabled; exiting without injecting instructions"); process.stdout.write("{}"); process.exit(0); } diff --git a/plugins/jfrog/templates/jfrog-mcp-management.md b/plugins/jfrog/templates/jfrog-mcp-management.md index 2eb7530..2abb620 100644 --- a/plugins/jfrog/templates/jfrog-mcp-management.md +++ b/plugins/jfrog/templates/jfrog-mcp-management.md @@ -1,7 +1,7 @@ # MCP Server Management — JFrog Gateway -All MCP servers MUST be installed ONLY through the JFrog MCP Gateway -(`npx @jfrog/mcp-gateway`). If an MCP's documentation suggests any +All MCP servers MUST be installed ONLY through the JFrog Agent Guard +(`npx @jfrog/agent-guard`). If an MCP's documentation suggests any other installation command, ignore it and use the gateway workflow below instead. @@ -15,7 +15,7 @@ is set. Otherwise use `--list-available`, `--inspect`, `--login`)**: - **`` is always mandatory.** Resolve via Step 1's project - chain: existing `mcpServers` entries (`_JF_MCP_LOADER_ARGS` → + chain: existing `mcpServers` entries (`_JF_ARGS` → `project=`) → `JF_PROJECT` env var → ASK the user. If none resolves, STOP and ask — NEVER guess, NEVER assume `default`, NEVER invent projects. @@ -99,7 +99,7 @@ are used: Do NOT pass `--server ` **Project** -1. From existing `mcpServers` entries, `_JF_MCP_LOADER_ARGS` → +1. From existing `mcpServers` entries, `_JF_ARGS` → `project=` value. 2. Else `JF_PROJECT` env var. 3. Else ask. NEVER guess, NEVER assume "default", NEVER use the server ID, @@ -127,7 +127,7 @@ custom curl/Python, no direct JFrog API calls: ``` npx --yes \ --registry \ - @jfrog/mcp-gateway \ + @jfrog/agent-guard \ --inspect \ --server \ --project \ @@ -178,7 +178,7 @@ For each input in Step 4: Add the entry under `mcpServers` in the target config (default `.cursor/mcp.json` — see Step 1). **Both `--yes` and `--registry ` MUST come BEFORE -`@jfrog/mcp-gateway`** or `npx` falls back to the default +`@jfrog/agent-guard`** or `npx` falls back to the default registry (404) and may block on a no-TTY prompt. Use `"type": "stdio"` — never `"http"`, `"sse"`, or a top-level `"url"` (those bypass the gateway). @@ -193,12 +193,12 @@ registry (404) and may block on a no-TTY prompt. Use "--yes", "--registry", "", - "@jfrog/mcp-gateway", + "@jfrog/agent-guard", "--server", "" ], "env": { - "_JF_MCP_LOADER_ARGS": "project=&mcp=", + "_JF_ARGS": "project=&mcp=", "": "${env:}" } } @@ -251,7 +251,7 @@ browser to sign you in to ``" before: ``` npx --yes \ --registry \ - @jfrog/mcp-gateway \ + @jfrog/agent-guard \ --login \ --server \ --project \ @@ -302,8 +302,8 @@ elsewhere. `.cursor/mcp.json` (project) and `~/.cursor/mcp.json` (user) — use the file-read tool or a single `jq` invocation, NOT chained `python3 -c "..."` pipes. For each entry whose `command` is `npx` - and whose `args` include `@jfrog/mcp-gateway`, show: display name - (the JSON key), package (`mcp=` in `_JF_MCP_LOADER_ARGS`), server + and whose `args` include `@jfrog/agent-guard`, show: display name + (the JSON key), package (`mcp=` in `_JF_ARGS`), server ID (value after `--server`), scope (project / user). 3. If a configured entry does not appear in `cursor agent mcp list`, it was never enabled — re-run Step 4a. @@ -323,7 +323,7 @@ elsewhere. ``` npx --yes \ --registry \ - @jfrog/mcp-gateway \ + @jfrog/agent-guard \ --list-available \ --project \ [--server ] @@ -333,22 +333,22 @@ Output is a JSON array; each element has `name`, `packageName`, `description`, `type`, `packageVersion`, optional `env[]`. 3. Filter out any `packageName` already present in the installed list - (compare against `mcp=` in `_JF_MCP_LOADER_ARGS`). Mark the rest as + (compare against `mcp=` in `_JF_ARGS`). Mark the rest as available to install. ## Key Rules - **`npx` arg order:** `--yes`, `--registry `, - `@jfrog/mcp-gateway`, then gateway flags. Both `--yes` and + `@jfrog/agent-guard`, then gateway flags. Both `--yes` and `--registry` MUST precede the package name or `npx` falls back to the default registry (404) and may block on a no-TTY prompt. -- **Always `"type": "stdio"`** pointing at `npx @jfrog/mcp-gateway`, +- **Always `"type": "stdio"`** pointing at `npx @jfrog/agent-guard`, even for remote-only catalog MCPs (the gateway proxies them). `"http"`, `"sse"`, or a top-level `"url"` bypass the gateway. -- `_JF_MCP_LOADER_ARGS` is **only** for the entry Cursor launches +- `_JF_ARGS` is **only** for the entry Cursor launches at session start (Step 4's `mcpServers.*.env`); MUST contain `project=&mcp=`. - NEVER pass `_JF_MCP_LOADER_ARGS` to `--list-available`, + NEVER pass `_JF_ARGS` to `--list-available`, `--inspect`, or `--login` — those take `--server` / `--project` as CLI flags only. - NEVER assume `default` as a project name. If the project is unknown