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
36 changes: 25 additions & 11 deletions .github/scripts/sync-modules-integrity.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
{
"schemaVersion": 1,
"pin": "jfrog-agent-hooks/v0.9.0",
"pin": "jfrog-agent-hooks/v0.11.0",
"files": {
"assets/agents-default-conf.json": "04aae9b1dcfc75271c3ed786adceea1635b0a1ae0be64fadd7b1111229f11f01",
"assets/agents-conf-fingerprints.json": "11bd418cdf38c8494e04239ae5237a1242bb1532468428c5a561f674f21e2657",
"assets/agents-default-conf.json": "774e1bfd5bb1e2f38de06c9ce53b92e12ddd36b82c159e4a3113f4c038bfc3bb",
"claude-session-start.mjs": "2ca1edc6b939cdff6c5faa6ac4b69636e6e92bc7b079316e1fdee7c53c6e837b",
"copilot-session-start.mjs": "8811e0829c90ff0987bed158f5ef571195ee5eb54dfc8021b4396fe76ad8a499",
"core/agents-config.mjs": "3ade16fd6e08b8ac6cb8570edfbed1e9677b26d9c31513720680dd17513480af",
"core/agent-guard-check.mjs": "fd7fe9df640418b0df3296a67c33dfabed97f65e210f6e7abea5bce96fa68834",
"core/agents-config.mjs": "d6a3181f77efa7b03d691ac8384ec4716f058f867054c33ef77cca3a8f992dab",
"core/entry.mjs": "0b0b218448151d7a06743c37e684d0933ab76225be5761f648627f4db02c1f17",
"core/io.mjs": "63ea75df635a4e15cf36f2158fe78ae42e3ca886abe267ee5ed2577042eb153d",
"core/jf-identity.mjs": "9d0301d4a60b9c9297cde24e0bab0c2660c56f831617f2b69db17c844276b19b",
"core/jf-identity.mjs": "4ee1c17b6e737f29aa0a2d2f0c94edad6b4566ecaf8f5b5bed0e45486e4f720a",
"core/jf-user-agent.mjs": "4ad02d04a4e9c4593cfff936b1b0899f834ca0cfb6e731ddafc9abf4c83b2de9",
"core/logger.mjs": "1ebdffcdf4af14b19e3ee8e82cfeb377fb9961a09d4e9d6ecdc922d07b0848c2",
"core/rewrite-mcp-json.mjs": "a88733edd33bd146ed960c157e085f0b89a20882719c1d6daee5a56400322d86",
"core/run-capability.mjs": "9fac890b7fd4866f9d3322469b2a7301e28cebfa3faebd77857f9f79d2d1c532",
"core/scaffold-fingerprint.mjs": "df7a710ba215e74808fbda5322e353171a613e74a3ac90fbca466d70c91dca67",
"cursor-session-start.mjs": "37dd25ffee18e9f357e3cbb8453552766fd89295e85aa09bf93bc208df74aa20",
"package-resolution/onboarding/package-resolution-nudge.md": "18f8c7b6c1a41e453f20c17392ff07338b6f15a1796f544d09af8d699218db26",
"package-resolution/onboarding/package-resolution-onboarding-procedure.md": "90abb6232228eea0fd874b0c8f69c5d3d298390ad77c5ff283b12c6ee9f04e60",
"package-resolution/scripts/apr-heartbeat.mjs": "3b87b52c06afc5fe311df9c8ecfd29c97198f4b6e1881920ba28231358dc466b",
"package-resolution/scripts/configure.mjs": "18cd8bf29d45aa399dca8bd5fbd799317e97880dfd61f94e4a90d17223b88c83",
"package-resolution/scripts/eager-setup-receipt.mjs": "69213084bc1976ec63b346ca26e8a63eb713b0da7ad6ab4fc018934e70fef091",
"package-resolution/scripts/eager-setup.mjs": "d78fc422d15a271e9ae68b754a28fa72ea25a9e86b505b1a0e5e053add864c0d",
"package-resolution/scripts/feature-flag.mjs": "18b258e4d1999de31bad54a1f7f3c3f9cf65c598bbb83f328b45f68a739821f3",
"package-resolution/scripts/index.mjs": "f3ea8f71ecd156515a4a5eb14e33de5c61287f4f2e0e7ca90f9b7d010c4d6567",
"package-resolution/scripts/eager-setup.mjs": "a2b4ec841f65424f9cfbd59b53ecbd2abf99237298a27edf2558cf7ea3bc8d42",
"package-resolution/scripts/feature-flag.mjs": "644f527172700b8578369438dd319d0d80f575a602dcf40f7c9c8128531b7d54",
"package-resolution/scripts/index.mjs": "482a9fb19389179841b5f41cfa5f6314369cd7f01a17260fa2467af88cb3e43c",
"package-resolution/scripts/onboarding-decline-cache.mjs": "92dbc291d5c862e315255046f613bde9d2a488de35137a542a0f70ccf51f202c",
"package-resolution/scripts/onboarding.mjs": "864fd72aa8f3b3c48b3e315c7cefffd398c3a1b8116d2bfecc82a0f274395e24",
"package-resolution/scripts/package-manager-family.mjs": "50d066910638e37c2375f696094fde1252181398be56c4218ca14342a76a34e5",
"package-resolution/scripts/print-policy.mjs": "02593c6e401006d226b908221d007ba9e1951a61c4cb060789877c1fe919faa2",
"package-resolution/scripts/render-instruction.mjs": "9e4205b5715e2c79515de19d473a6487d61971368103f2851388530ed0a180c4",
"package-resolution/scripts/render-instruction.mjs": "a2c1a5d19fec1bff0a08d33eafdd33c6ff27581d314a4d3699980c914891e4d1",
"package-resolution/scripts/repo-types.mjs": "b432bcdd6e77f80ca2c9dddfbf4d9e1299019758fd58b04b29fc21b18a86f788",
"package-resolution/scripts/resolver.mjs": "3485575a65fd5579420d69a51f723047d44f3cfa246511565c6e89ca32b02b4d",
"package-resolution/scripts/resolver.mjs": "6b2b92c0f8d6d56390386255899bee5cec943d298a06b859f5340b30ed79cc8c",
"package-resolution/scripts/setup-conflict.mjs": "fdc589561813a9c5e708f50a20a87bacdad3f490158c973b12b217cb984e2845",
"package-resolution/scripts/sync-onboarding-rule.mjs": "cec5559b12bb840cbb059d0b90ab8f36a31a27e7ffdf501262e1e56b3d7d6809",
"package-resolution/scripts/verify-repo.mjs": "ad0a1cc04c1dddd92e29fefb27ae90e69afb368b8d208d22ab4fda6a27dfe34a",
"package-resolution/scripts/workspace-config.mjs": "f8f8eaaf0fb8a0c3691938e99afebbc87d8779e508db0ef821fa23f0a55b786a",
"package-resolution/templates/package-resolution-unconfigured.md": "e7645b89d1c4d618fb45692de084d627ca24b5e2e975416176115d3c233e9c00",
"package-resolution/templates/package-resolution.md": "c305751d24fe352b6334a208f7831eb9db58704f1baa693c6921264f6a4456d1"
"package-resolution/templates/package-resolution-unconfigured.md": "d276aa796b3c38f0566bc0b5c3a1553bbbf322d5eaa0d60841e21a3e280a91e0",
"package-resolution/templates/package-resolution.md": "f432ea47e99db08b6223873eb4560f814369f92673acdff2b0de6fa7e10a1d58"
}
}
2 changes: 1 addition & 1 deletion .github/scripts/sync-modules-vendor.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"repo": "JFROG/jfrog-agent-hooks",
"pin": "jfrog-agent-hooks/v0.9.0",
"pin": "jfrog-agent-hooks/v0.11.0",
"paths": ["modules"],
"dest_prefix": "plugin"
}
4 changes: 4 additions & 0 deletions .github/workflows/validate-package-resolution-hook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
paths:
- "plugin/hooks/hooks.json"
- "plugin/modules/**"
- "plugin/scripts/**"
- "plugin/.claude-plugin/plugin.json"
- "marketplace.json"
- "scripts/validate-package-resolution-hook.mjs"
Expand All @@ -35,5 +36,8 @@ jobs:
- name: Validate hook assembly
run: node scripts/validate-package-resolution-hook.mjs

- name: Test VS Code MCP alignment
run: node --test plugin/scripts/*.test.mjs

- name: Verify vendored module integrity
run: node .github/scripts/check-vendored-modules.mjs
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The JFrog plugin provides the following capabilities, grouped by component:
| Component | Feature | Description |
| --------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **MCP** | JFrog MCP server | Remote JFrog MCP server auto-attached to every session via `.mcp.json` at `${JFROG_URL}/mcp` (OAuth, no API keys). |
| **Hook** | MCP server alignment | Secures installed plugins' `mcp.json` and `.mcp.json` server commands with JFrog Agent Guard at Copilot SessionStart. |
| **Skill** | Agent Guard | Copilot manages MCPs through the JFrog Agent Guard. Through it you can 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. |
| **Hook** | Agent Package Resolution (Preview) | Inject Artifactory routing instructions at the start of each Copilot session. |

Expand Down Expand Up @@ -122,6 +123,42 @@ See the [user guide](docs/package-resolution-user-guide.md) for setup and the
[administrator guide](docs/package-resolution-admin-guide.md) for rollout and
governance configuration.

### MCP server alignment

At Copilot `SessionStart`, the plugin discovers MCP configuration files owned by
installed agent plugins and passes them to Agent Guard's shared
`--rewrite-mcp-json` pipeline. Agent Guard rewrites eligible server commands so
they run through the configured JFrog project policy. The hook is fail-open and
has a 60-second limit; disabled, unchanged, or failed rewrites do not block a
chat.

Discovery checks both `mcp.json` and `.mcp.json`, in that order, under
`~/.copilot/installed-plugins/{marketplace}/{plugin}`,
`~/.copilot/installed-plugins/_direct/{id}`, and
`~/.vscode/agent-plugins/…`, plus this plugin's own configs next to the
adaptor.

Only plugin MCP configurations are considered. The hook never rewrites the user
`Code/User/mcp.json` or a workspace `.vscode/mcp.json`.

Environment controls:

- `JF_AGENT_REWRITE_MCP_JSON_DISABLE=1` disables rewriting.
- `JF_AGENT_REWRITE_MCP_JSON_FORCE=1` ignores the current-state marker and
forces a refresh.
- `JF_ALIGN_MCP_JSON_ROOTS` replaces the default Copilot installed-plugins
and `~/.vscode/agent-plugins` roots (and skips this plugin's own configs).
Separate roots with colon or comma on macOS/Linux, and semicolon or
comma on Windows. Overrides may point outside the default, but discovery
still rejects `.vscode` and `Code/User` configs and symlinks escaping an
override root.

If the alignment pipeline changes any discovered configuration bytes, even if
the pipeline later times out or reports a failure, Copilot displays:
`JFrog Agent Guard secured your plugins' MCP servers. Run Developer: Reload Window to reconnect.`
Use the Command Palette command **Developer: Reload Window** before using the
rewritten MCP servers.

### Discover, inspect, and install MCPs

| Ask the agent… | What happens |
Expand Down
7 changes: 7 additions & 0 deletions VENDOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ verifies the committed tree matches the pin (see
[`sync-modules-integrity.json`](.github/scripts/sync-modules-integrity.json)
for the per-file checksums used in that check).

The current bundle is pinned to `jfrog-agent-hooks/v0.11.0`, which includes
the shared `--rewrite-mcp-json` pipeline from upstream PR 108. Only upstream
`modules/` are vendored; upstream tests remain in the source repository.
[`plugin/package.json`](plugin/package.json) is a version stub so
`modules/core/jf-user-agent.mjs` can read `../../package.json` (the same
relative path as in the upstream repo root).

## Not vendored

[`@jfrog/agent-guard`](https://jfrog.com) is fetched at runtime via `npx` from
Expand Down
2 changes: 1 addition & 1 deletion marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{
"name": "jfrog",
"description": "JFrog Platform integration with MCP, security skills, and supply-chain best practices",
"version": "1.0.17",
"version": "1.0.18",
"license": "Apache-2.0",
"source": "plugin",
"categories": [
Expand Down
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "jfrog",
"description": "JFrog Platform integration with MCP, security skills, and supply-chain best practices",
"version": "1.0.17",
"version": "1.0.18",
"license": "Apache-2.0",
"author": {
"name": "JFrog",
Expand Down
6 changes: 6 additions & 0 deletions plugin/hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
"command": "node \"${CLAUDE_PLUGIN_ROOT}/modules/copilot-session-start.mjs\" package-resolution",
"timeout": 15,
"statusMessage": "Routing package installs through JFrog Artifactory…"
},
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/vscode-align-mcp-json.mjs\" session-start",
"timeout": 60,
"statusMessage": "Securing plugin MCP servers with JFrog Agent Guard…"
}
]
}
Expand Down
30 changes: 30 additions & 0 deletions plugin/modules/assets/agents-conf-fingerprints.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"schemaVersion": 1,
"fingerprints": [
{
"id": "v0-placeholders-no-onboardingPrompt",
"sha256": "452b737ede2af5da3ea660cb0a2226d422b5624fa1684bc883279422c0728421",
"note": "Legacy template with example repo keys, before onboardingPrompt"
},
{
"id": "v1-placeholders-onboardingPrompt-auto",
"sha256": "b19251b4671db244a8050885bcbaf5f217f0e4eecfec34c0338264b08fa7c871",
"note": "Legacy template with example repo keys + onboardingPrompt: auto"
},
{
"id": "v2-empty-defaultGlobalRepos",
"sha256": "5a104c83c4cb67f2cb01d71ad0044a438f9125bab868ef76e24bd7be7828b82b",
"note": "Empty defaultGlobalRepos after #84 (no onboardingPrompt)"
},
{
"id": "v3-empty-onboardingPrompt-auto",
"sha256": "8b68d55af89e2dadf4ff0c3ae0784b70051c24d1fb75e3ea6df8ba3044c5cefa",
"note": "Legacy template: enabled false + empty defaultGlobalRepos + onboardingPrompt: auto"
},
{
"id": "v4-enabled-onboardingPrompt-auto",
"sha256": "f0481d915f1f7f2a1e7d88ab23ce7b9430d3e44e41aaabb4d4d13e2b40963ae2",
"note": "Current shipped template: enabled true + empty defaultGlobalRepos + onboardingPrompt: auto"
}
]
}
3 changes: 2 additions & 1 deletion plugin/modules/assets/agents-default-conf.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"logLevel": "info",
"packageResolution": {
"enabled": false,
"enabled": true,
"verifyRepos": true,
"cacheTtlDays": 7,
"onboardingPrompt": "auto",
"defaultGlobalRepos": {},
"autoSetup": []
}
Expand Down
Loading
Loading