From 56ef441a374f730fad0582df416a9968dfc4d759 Mon Sep 17 00:00:00 2001 From: Allen <0xfatdog@gmail.com> Date: Mon, 10 Aug 2026 14:43:17 +0800 Subject: [PATCH 1/4] feat: add Cursor plugin support --- .claude/CLAUDE.md | 20 ++++++++++++--- .cursor-plugin/plugin.json | 31 +++++++++++++++++++++++ .github/workflows/claude-pr-review.yml | 3 ++- .github/workflows/verify-version-sync.yml | 7 ++++- AGENTS.md | 19 +++++++++++--- README.md | 8 +++++- docs/README_zh.md | 8 +++++- release-please-config.json | 5 ++++ 8 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 .cursor-plugin/plugin.json diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 0127a92..f35d21b 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -17,6 +17,8 @@ The same repo also works as a Claude Code plugin (via `.claude-plugin/plugin.jso It additionally works as a **Codex plugin** (via `.codex-plugin/plugin.json` + `.codex-plugin/mcp.json`, distributed through `.agents/plugins/marketplace.json` — the repo is its own marketplace, added with `codex plugin marketplace add chainbase-labs/agentkey`). Codex plugins have no `userConfig`/header-interpolation mechanism, so auth uses MCP OAuth instead: the server's `/v1/mcp` endpoint advertises `WWW-Authenticate: Bearer resource_metadata=…` (RFC 9728) and supports dynamic client registration, so `.codex-plugin/mcp.json` needs only `type` + `url` — discovery does the rest. In that mode the OAuth sign-in substitutes for step 2. +It also works as a **Cursor plugin** (`.cursor-plugin/plugin.json`). The Cursor-native manifest bundles `skills/` and an inline remote-HTTP MCP entry. Cursor authenticates through the server's MCP OAuth discovery, substituting for step 2. + It also works as a **Kimi Code plugin** (`.kimi-plugin/plugin.json`). Kimi requires `mcpServers` to be an inline object in the manifest. The remote AgentKey endpoint uses Kimi's native MCP OAuth flow; after install Kimi shows the standard `/reload` hint, then the user signs in with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that OAuth is required. ## Directory Structure @@ -27,6 +29,8 @@ agentkey/ ├── .codex-plugin/ │ ├── plugin.json # Codex plugin manifest (skills + mcpServers + interface metadata) │ └── mcp.json # Codex MCP entry — http + oauth_resource (NOT the root .mcp.json) +├── .cursor-plugin/ +│ └── plugin.json # Cursor manifest with skills + inline HTTP MCP entry (OAuth) ├── .kimi-plugin/ │ └── plugin.json # Kimi Code manifest with inline HTTP MCP entry (OAuth) ├── .agents/plugins/marketplace.json # Codex marketplace listing this repo as a local-source plugin @@ -58,11 +62,11 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes ``` -Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifest versions, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. +Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all four plugin manifest versions, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. ## Version & Release Rules -- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, and `.kimi-plugin/plugin.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. +- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.cursor-plugin/plugin.json`, and `.kimi-plugin/plugin.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. - `version.txt` lives inside `skills/agentkey/` (not at repo root) so it travels with the skill when the Skills CLI copies the subdirectory. `release-please-config.json` points at this path via `version-file`. - Tag format: `v` prefix (e.g. `v0.4.5`) - Plugin updates trigger on **GitHub Release** publication, not on plain commits @@ -71,7 +75,7 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl ## Change Checklists **Changes to any `plugin.json`:** -- release-please automatically bumps all three manifest versions + `CHANGELOG.md` from merged conventional-commit PRs; maintainers review + merge the generated Release PR rather than editing these files directly +- release-please automatically bumps all four manifest versions + `CHANGELOG.md` from merged conventional-commit PRs; maintainers review + merge the generated Release PR rather than editing these files directly **Changes to `.mcp.json`:** - The MCP server is `type: http` (remote endpoint, no subprocess), so inject the API key by interpolating the userConfig value as `${user_config.AGENTKEY_API_KEY}` in the `Authorization` header — the key name MUST match the `plugin.json` `userConfig` key. Do NOT use `${CLAUDE_PLUGIN_OPTION_}`: those env vars are only exported to stdio/subprocess servers and hook/monitor commands, and are not interpolated into an http server's headers. @@ -82,12 +86,19 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Do NOT set `oauth_resource`: rmcp already sends `resource` on its own, and Codex appends `oauth_resource` as a *second* `resource` query param without deduplication (`codex-rs/rmcp-client/src/perform_oauth_login.rs`). Clerk enforces RFC 6749 (no repeated params) and rejects the request with `invalid_request: The request includes the parameter 'resource' more than once`. The official Notion/Figma plugins get away with it only because their authorization servers tolerate duplicates. - Keep the endpoint URL in sync with the root `.mcp.json` — both must point at the same `/v1/mcp` endpoint. +**Changes to `.cursor-plugin/plugin.json`:** +- The manifest MUST stay at `.cursor-plugin/plugin.json`; component paths resolve from the plugin root. +- Use only fields documented by the Cursor plugin reference. Do not copy Codex/Kimi-only metadata such as `interface` into this manifest. +- Keep `skills` pointed at `./skills/` and `mcpServers` as the minimal inline `{"agentkey":{"url":"https://api.agentkey.app/v1/mcp"}}` entry. Do not add static credentials or `${user_config.*}` interpolation; Cursor handles MCP OAuth itself. +- Keep the endpoint URL in sync with the root `.mcp.json`, `.codex-plugin/mcp.json`, and `.kimi-plugin/plugin.json`. +- This repository is a single Cursor plugin, so `.cursor-plugin/marketplace.json` is not required. Submit the public repository URL through Cursor's marketplace publisher. + **Changes to `.kimi-plugin/plugin.json`:** - `mcpServers` MUST be an inline object. Kimi does not accept a path such as `"./mcp.json"` for this field. - Keep the HTTP entry minimal: `{"agentkey":{"url":"https://api.agentkey.app/v1/mcp"}}`. Kimi infers the transport from `url`. - Do not add `userConfig`, a static Authorization header, or `${user_config.*}` interpolation. Kimi discovers and persists MCP OAuth credentials itself. - Kimi displays `Run /new or /reload to apply plugin changes.` after install. Once reloaded, the user completes native MCP OAuth with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that authentication is required. -- Keep the endpoint URL in sync with the root `.mcp.json` and `.codex-plugin/mcp.json`. +- Keep the endpoint URL in sync with the root `.mcp.json`, `.codex-plugin/mcp.json`, and `.cursor-plugin/plugin.json`. **Changes to install/uninstall docs:** - Update both `README.md` and `docs/README_zh.md` together — they mirror each other @@ -99,5 +110,6 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Setup mode in SKILL.md runs `! npx -y @agentkey/cli --auth-login` to authenticate via browser — same command as step 2 of the public install - `@agentkey/cli --auth-login` auto-writes MCP configs for 16 agents (canonical list lives in `AGENT_REGISTRY` in `../AgentKey-Server/cli/src/lib/mcp-clients.ts`): Claude Code, Claude Desktop, Cursor, Codex, Gemini CLI, OpenCode, Qwen Code, iFlow CLI, Kimi CLI, Kiro CLI, Windsurf, Warp, Amp, Crush, droid, openclaw. The `--only ` flag (used by install.sh's `MCP_TARGETS` and install.ps1's `$McpTargets`) filters this list — its id values MUST match `npx skills add -a` ids, with `claude-desktop` as the one documented MCP-only exception. Goose / kode / kilo still need a manual JSON paste (see SKILL.md's "Fallback" section); when adding more agents server-side, keep `MCP_AUTO_AGENTS` in both install scripts and the cleanup list in both uninstall scripts in sync. - `.mcp.json` registers the remote-HTTP MCP endpoint (`https://api.agentkey.app/v1/mcp`) in Claude Code plugin mode; the API key flows from plugin userConfig into the `Authorization: Bearer ${user_config.AGENTKEY_API_KEY}` header (no stdio binary is launched) +- `.cursor-plugin/plugin.json` registers the same endpoint inline in Cursor plugin mode, authenticated through Cursor's native MCP OAuth flow - `.kimi-plugin/plugin.json` registers the same endpoint inline in Kimi Code plugin mode. After reloading, the user starts Kimi's native MCP OAuth flow with `/mcp-config login plugin-agentkey:agentkey`. - `README.md` / `docs/README_zh.md` are the public-facing docs; keep them in sync with any structural changes diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json new file mode 100644 index 0000000..39b7e6e --- /dev/null +++ b/.cursor-plugin/plugin.json @@ -0,0 +1,31 @@ +{ + "name": "agentkey", + "version": "1.13.1", + "description": "AgentKey — one-stop live data marketplace for your agent: web search, web scraping, social media, finance, crypto, e-commerce, business data, weather/maps, and travel through a single MCP server. No API keys to manage, auto failover across providers, free to start.", + "author": { + "name": "Chainbase Labs" + }, + "homepage": "https://agentkey.app", + "license": "MIT", + "keywords": [ + "agentkey", + "web-search", + "scraping", + "social-media", + "finance", + "crypto", + "blockchain", + "e-commerce", + "business-data", + "weather", + "maps", + "travel", + "real-time-data" + ], + "skills": "./skills/", + "mcpServers": { + "agentkey": { + "url": "https://api.agentkey.app/v1/mcp" + } + } +} diff --git a/.github/workflows/claude-pr-review.yml b/.github/workflows/claude-pr-review.yml index 1b2590e..ef46a2c 100644 --- a/.github/workflows/claude-pr-review.yml +++ b/.github/workflows/claude-pr-review.yml @@ -192,7 +192,8 @@ jobs: from release-please itself, which won't trigger this review since author.type == Bot) - `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, - and `.kimi-plugin/plugin.json` version fields — managed + `.cursor-plugin/plugin.json`, and `.kimi-plugin/plugin.json` + version fields — managed ### 4c. Repo invariants - `skills/agentkey/scripts/check-update.sh` REPO line diff --git a/.github/workflows/verify-version-sync.yml b/.github/workflows/verify-version-sync.yml index fcfbef2..2302968 100644 --- a/.github/workflows/verify-version-sync.yml +++ b/.github/workflows/verify-version-sync.yml @@ -13,6 +13,7 @@ on: - 'skills/agentkey/SKILL.md' - '.claude-plugin/plugin.json' - '.codex-plugin/plugin.json' + - '.cursor-plugin/plugin.json' - '.kimi-plugin/plugin.json' - 'release-please-config.json' pull_request: @@ -22,6 +23,7 @@ on: - 'skills/agentkey/SKILL.md' - '.claude-plugin/plugin.json' - '.codex-plugin/plugin.json' + - '.cursor-plugin/plugin.json' - '.kimi-plugin/plugin.json' - 'release-please-config.json' @@ -38,19 +40,22 @@ jobs: | head -1 | sed -E 's/^LOCAL_VERSION="([^"]+)".*/\1/') claude_plugin=$(python3 -c 'import json; print(json.load(open(".claude-plugin/plugin.json"))["version"])') codex_plugin=$(python3 -c 'import json; print(json.load(open(".codex-plugin/plugin.json"))["version"])') + cursor_plugin=$(python3 -c 'import json; print(json.load(open(".cursor-plugin/plugin.json"))["version"])') kimi_plugin=$(python3 -c 'import json; print(json.load(open(".kimi-plugin/plugin.json"))["version"])') skill=$(awk '/^---/{c++; next} c==1 && /^version:/{print $2; exit}' skills/agentkey/SKILL.md) echo "version.txt: $canonical" echo "check-update.sh: $script" echo "Claude plugin: $claude_plugin" echo "Codex plugin: $codex_plugin" + echo "Cursor plugin: $cursor_plugin" echo "Kimi plugin: $kimi_plugin" echo "SKILL.md: $skill" if [ "$canonical" != "$script" ] \ || [ "$canonical" != "$claude_plugin" ] \ || [ "$canonical" != "$codex_plugin" ] \ + || [ "$canonical" != "$cursor_plugin" ] \ || [ "$canonical" != "$kimi_plugin" ] \ || [ "$canonical" != "$skill" ]; then - echo "::error::Version drift detected. release-please syncs all six values from version.txt — re-run release-please or restore the values manually." + echo "::error::Version drift detected. release-please syncs all seven values from version.txt — re-run release-please or restore the values manually." exit 1 fi diff --git a/AGENTS.md b/AGENTS.md index 7c0f924..bdc6c54 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,7 @@ The same repo also works as: - a **Claude Code plugin** (`.claude-plugin/plugin.json` + root `.mcp.json`) — the plugin's `userConfig` injects the API key via `${user_config.AGENTKEY_API_KEY}`, substituting for step 2. - a **Codex plugin** (`.codex-plugin/plugin.json` + `.codex-plugin/mcp.json`, distributed through `.agents/plugins/marketplace.json`; the repo is its own marketplace: `codex plugin marketplace add chainbase-labs/agentkey`). Codex plugins have no `userConfig`/header-interpolation mechanism, so auth uses MCP OAuth via the server's RFC 9728 metadata discovery (`type` + `url` only in mcp.json), substituting for step 2. +- a **Cursor plugin** (`.cursor-plugin/plugin.json`). The Cursor-native manifest bundles `skills/` and an inline remote-HTTP MCP entry. Cursor authenticates through the server's MCP OAuth discovery, substituting for step 2. - a **Kimi Code plugin** (`.kimi-plugin/plugin.json`). Kimi requires `mcpServers` to be an inline object in the manifest. The remote AgentKey endpoint uses Kimi's native MCP OAuth flow; after install Kimi shows the standard `/reload` hint, then the user signs in with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that OAuth is required. ## Directory Structure @@ -27,6 +28,8 @@ agentkey/ ├── .codex-plugin/ │ ├── plugin.json # Codex plugin manifest (skills + mcpServers + interface metadata) │ └── mcp.json # Codex MCP entry — http + oauth_resource (NOT the root .mcp.json) +├── .cursor-plugin/ +│ └── plugin.json # Cursor manifest with skills + inline HTTP MCP entry (OAuth) ├── .kimi-plugin/ │ └── plugin.json # Kimi Code manifest with inline HTTP MCP entry (OAuth) ├── .agents/plugins/marketplace.json # Codex marketplace listing this repo as a local-source plugin @@ -58,11 +61,11 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes ``` -Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifest versions, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. +Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all four plugin manifest versions, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. ## Version & Release Rules -- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, and `.kimi-plugin/plugin.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. +- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.cursor-plugin/plugin.json`, and `.kimi-plugin/plugin.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. - `version.txt` lives inside `skills/agentkey/` (not at repo root) so it travels with the skill when the Skills CLI copies the subdirectory. `release-please-config.json` points at this path via `version-file`. - Tag format: `v` prefix (e.g. `v0.4.5`) - Plugin updates trigger on **GitHub Release** publication, not on plain commits @@ -71,7 +74,7 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl ## Change Checklists **Changes to any `plugin.json`:** -- release-please automatically bumps all three manifest versions + `CHANGELOG.md` from merged conventional-commit PRs; maintainers review + merge the generated Release PR rather than editing these files directly +- release-please automatically bumps all four manifest versions + `CHANGELOG.md` from merged conventional-commit PRs; maintainers review + merge the generated Release PR rather than editing these files directly **Changes to the root `.mcp.json` (Claude Code plugin path):** - The MCP server is `type: http` (remote endpoint, no subprocess), so inject the API key by interpolating the userConfig value as `${user_config.AGENTKEY_API_KEY}` in the `Authorization` header — the key name MUST match the `.claude-plugin/plugin.json` `userConfig` key. Do NOT use `${CLAUDE_PLUGIN_OPTION_}`: those env vars are only exported to stdio/subprocess servers and hook/monitor commands, and are not interpolated into an http server's headers. @@ -82,12 +85,19 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Do NOT set `oauth_resource`: rmcp already sends `resource` on its own, and Codex appends `oauth_resource` as a *second* `resource` query param without deduplication (`codex-rs/rmcp-client/src/perform_oauth_login.rs`). Clerk enforces RFC 6749 (no repeated params) and rejects the request with `invalid_request: The request includes the parameter 'resource' more than once`. The official Notion/Figma plugins get away with it only because their authorization servers tolerate duplicates. - Keep the endpoint URL in sync with the root `.mcp.json` — both must point at the same `/v1/mcp` endpoint. +**Changes to `.cursor-plugin/plugin.json` (Cursor plugin path):** +- The manifest MUST stay at `.cursor-plugin/plugin.json`; component paths resolve from the plugin root. +- Use only fields documented by the Cursor plugin reference. Do not copy Codex/Kimi-only metadata such as `interface` into this manifest. +- Keep `skills` pointed at `./skills/` and `mcpServers` as the minimal inline `{"agentkey":{"url":"https://api.agentkey.app/v1/mcp"}}` entry. Do not add static credentials or `${user_config.*}` interpolation; Cursor handles MCP OAuth itself. +- Keep the endpoint URL in sync with the root `.mcp.json`, `.codex-plugin/mcp.json`, and `.kimi-plugin/plugin.json`. +- This repository is a single Cursor plugin, so `.cursor-plugin/marketplace.json` is not required. Submit the public repository URL through Cursor's marketplace publisher. + **Changes to `.kimi-plugin/plugin.json` (Kimi Code plugin path):** - `mcpServers` MUST be an inline object. Kimi does not accept a path such as `"./mcp.json"` for this field. - Keep the HTTP entry minimal: `{"agentkey":{"url":"https://api.agentkey.app/v1/mcp"}}`. Kimi infers the transport from `url`. - Do not add `userConfig`, a static Authorization header, or `${user_config.*}` interpolation. Kimi discovers and persists MCP OAuth credentials itself. - Kimi displays `Run /new or /reload to apply plugin changes.` after install. Once reloaded, the user completes native MCP OAuth with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that authentication is required. -- Keep the endpoint URL in sync with the root `.mcp.json` and `.codex-plugin/mcp.json`. +- Keep the endpoint URL in sync with the root `.mcp.json`, `.codex-plugin/mcp.json`, and `.cursor-plugin/plugin.json`. **Changes to install/uninstall docs:** - Update both `README.md` and `docs/README_zh.md` together — they mirror each other @@ -100,5 +110,6 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - `@agentkey/cli --auth-login` auto-writes MCP configs for 16 agents (canonical list lives in `AGENT_REGISTRY` in `../AgentKey-Server/cli/src/lib/mcp-clients.ts`): Claude Code, Claude Desktop, Cursor, Codex, Gemini CLI, OpenCode, Qwen Code, iFlow CLI, Kimi CLI, Kiro CLI, Windsurf, Warp, Amp, Crush, droid, openclaw. The `--only ` flag (used by install.sh's `MCP_TARGETS` and install.ps1's `$McpTargets`) filters this list — its id values MUST match `npx skills add -a` ids, with `claude-desktop` as the one documented MCP-only exception. Goose / kode / kilo still need a manual JSON paste (see SKILL.md's "Fallback" section); when adding more agents server-side, keep `MCP_AUTO_AGENTS` in both install scripts and the cleanup list in both uninstall scripts in sync. - Root `.mcp.json` registers the remote-HTTP MCP endpoint (`https://api.agentkey.app/v1/mcp`) in Claude Code plugin mode; the API key flows from plugin userConfig into the `Authorization: Bearer ${user_config.AGENTKEY_API_KEY}` header (no stdio binary is launched) - `.codex-plugin/mcp.json` registers the same endpoint in Codex plugin mode, authenticated via MCP OAuth (RFC 9728 discovery; no `oauth_resource` — see checklist above) +- `.cursor-plugin/plugin.json` registers the same endpoint inline in Cursor plugin mode, authenticated through Cursor's native MCP OAuth flow - `.kimi-plugin/plugin.json` registers the same endpoint inline in Kimi Code plugin mode. After reloading, the user starts Kimi's native MCP OAuth flow with `/mcp-config login plugin-agentkey:agentkey`. - `README.md` / `docs/README_zh.md` are the public-facing docs; keep them in sync with any structural changes diff --git a/README.md b/README.md index a756518..f5aa74c 100644 --- a/README.md +++ b/README.md @@ -380,6 +380,10 @@ Kimi copies local plugins into its managed plugin directory. Re-run `/plugins in If you previously worked around an older AgentKey plugin by adding a user-global `agentkey` entry through `/mcp-config`, remove that old entry once with `/mcp-config remove agentkey` before reloading. The plugin now owns its namespaced MCP entry; keeping both would create duplicate tools and authentication attempts. +**Cursor plugin mode** — install AgentKey from the Cursor Marketplace after the listing is published. The Cursor-native manifest at `.cursor-plugin/plugin.json` bundles the same Skill and an inline remote-HTTP MCP entry, so there is **no API key to paste and no second `@agentkey/cli` step**. When Cursor prompts for MCP authentication, approve the AgentKey browser sign-in. + +For maintainers, push the plugin to a public Git repository and submit the repository URL at [cursor.com/marketplace/publish](https://cursor.com/marketplace/publish). Before submitting, test the plugin in the current Cursor release and confirm that both the `agentkey` Skill and MCP server load successfully after OAuth. The manifest follows the [Cursor plugin reference](https://cursor.com/docs/reference/plugins); keep its component paths relative to the plugin root. + **Repo layout:** ``` @@ -388,6 +392,8 @@ agentkey/ ├── .codex-plugin/ │ ├── plugin.json # Codex plugin manifest │ └── mcp.json # Codex MCP entry (OAuth, no user_config) +├── .cursor-plugin/ +│ └── plugin.json # Cursor manifest with Skill + inline MCP OAuth ├── .kimi-plugin/ │ └── plugin.json # Kimi manifest with inline MCP OAuth entry ├── .agents/plugins/marketplace.json # Codex marketplace (this repo is its own marketplace) @@ -403,7 +409,7 @@ agentkey/ └── uninstall.ps1 # Windows PowerShell uninstaller ``` -**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifests, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset. +**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, all four plugin manifests, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset. diff --git a/docs/README_zh.md b/docs/README_zh.md index 9d5c4fc..09a90c3 100644 --- a/docs/README_zh.md +++ b/docs/README_zh.md @@ -380,6 +380,10 @@ Kimi 会把本地插件复制到自己的托管目录。修改原 checkout 后 如果你曾为旧版 AgentKey plugin 手工通过 `/mcp-config` 添加过用户全局的 `agentkey` 条目,请在 reload 前执行一次 `/mcp-config remove agentkey` 删除旧条目。现在 plugin 会维护自己的命名空间 MCP;同时保留两份会造成工具和鉴权流程重复。 +**Cursor 插件模式** —— 插件上架后,从 Cursor Marketplace 安装 AgentKey。`.cursor-plugin/plugin.json` 这个 Cursor 原生清单会同时捆绑同一个 Skill 和内联的远程 HTTP MCP 配置,因此**不用粘贴 API Key,也不需要再单独运行 `@agentkey/cli`**。Cursor 提示 MCP 需要认证时,在浏览器完成 AgentKey 登录即可。 + +维护者需要先把插件推送到公开 Git 仓库,再到 [cursor.com/marketplace/publish](https://cursor.com/marketplace/publish) 提交仓库地址。提交前请使用当前版本 Cursor 实际安装测试,确认 OAuth 完成后 `agentkey` Skill 和 MCP server 都能正常加载。清单遵循 [Cursor 插件参考](https://cursor.com/cn/docs/reference/plugins),其中所有组件路径都必须相对于插件根目录。 + **仓库结构:** ``` @@ -388,6 +392,8 @@ agentkey/ ├── .codex-plugin/ │ ├── plugin.json # Codex 插件清单 │ └── mcp.json # Codex MCP 配置(OAuth,无 user_config) +├── .cursor-plugin/ +│ └── plugin.json # Cursor 清单,捆绑 Skill 与内联 MCP OAuth ├── .kimi-plugin/ │ └── plugin.json # Kimi 清单,内联 MCP OAuth 配置 ├── .agents/plugins/marketplace.json # Codex marketplace(本仓库即自己的 marketplace) @@ -403,7 +409,7 @@ agentkey/ └── uninstall.ps1 # Windows PowerShell 卸载脚本 ``` -**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、三个插件清单和 `CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。 +**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、四个插件清单和 `CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。 diff --git a/release-please-config.json b/release-please-config.json index 9699591..e440d6d 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -20,6 +20,11 @@ "path": ".codex-plugin/plugin.json", "jsonpath": "$.version" }, + { + "type": "json", + "path": ".cursor-plugin/plugin.json", + "jsonpath": "$.version" + }, { "type": "json", "path": ".kimi-plugin/plugin.json", From 9c8de4c798fc1558e897fd877f4c07d7b01e9441 Mon Sep 17 00:00:00 2001 From: Allen <0xfatdog@gmail.com> Date: Mon, 10 Aug 2026 14:49:26 +0800 Subject: [PATCH 2/4] update cursor marketplace --- .cursor-plugin/marketplace.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .cursor-plugin/marketplace.json diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json new file mode 100644 index 0000000..2d85d04 --- /dev/null +++ b/.cursor-plugin/marketplace.json @@ -0,0 +1,18 @@ +{ + "name": "agentkey", + "description": "One-stop live data marketplace for your agent: web search, web scraping, social media, finance, crypto, e-commerce, business data, weather/maps, and travel", + "owner": { + "name": "Chainbase Labs", + "url": "https://agentkey.app" + }, + "plugins": [ + { + "name": "agentkey", + "description": "AgentKey — one-stop live data marketplace for your agent: web search, web scraping, social media, finance, crypto, e-commerce, business data, weather/maps, and travel through a single MCP server. No API keys to manage, auto failover across providers, free to start.", + "source": "./", + "category": "data", + "homepage": "https://github.com/chainbase-labs/agentkey", + "tags": ["agentkey", "web-search", "scraping", "social-media", "finance", "crypto", "blockchain", "e-commerce", "business-data", "weather", "maps", "travel", "real-time-data"] + } + ] +} From 64a28bda4164fe885cfb467a844cb0fb89bcc931 Mon Sep 17 00:00:00 2001 From: Allen <0xfatdog@gmail.com> Date: Mon, 10 Aug 2026 15:28:53 +0800 Subject: [PATCH 3/4] feat: add Gemini CLI extension onboarding --- .claude/CLAUDE.md | 15 ++++++- .github/workflows/scripts-test.yml | 2 + .github/workflows/verify-version-sync.yml | 7 ++- AGENTS.md | 14 +++++- README.md | 15 ++++++- docs/README_zh.md | 15 ++++++- gemini-extension.json | 10 +++++ release-please-config.json | 5 +++ tests/gemini-extension.bats | 55 +++++++++++++++++++++++ 9 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 gemini-extension.json create mode 100644 tests/gemini-extension.bats diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 0127a92..a8393ce 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -19,6 +19,8 @@ It additionally works as a **Codex plugin** (via `.codex-plugin/plugin.json` + ` It also works as a **Kimi Code plugin** (`.kimi-plugin/plugin.json`). Kimi requires `mcpServers` to be an inline object in the manifest. The remote AgentKey endpoint uses Kimi's native MCP OAuth flow; after install Kimi shows the standard `/reload` hint, then the user signs in with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that OAuth is required. +It also works as a **Gemini CLI extension** (root `gemini-extension.json` + `skills/`). Gemini requires the manifest at the extension root, discovers bundled agent skills automatically, and connects to AgentKey with `httpUrl` plus native MCP OAuth discovery. `/mcp auth agentkey` substitutes for step 2. + ## Directory Structure ``` @@ -31,6 +33,7 @@ agentkey/ │ └── plugin.json # Kimi Code manifest with inline HTTP MCP entry (OAuth) ├── .agents/plugins/marketplace.json # Codex marketplace listing this repo as a local-source plugin ├── .mcp.json # Auto-registers AgentKey MCP when installed as a Claude Code plugin +├── gemini-extension.json # Gemini CLI extension — Streamable HTTP + OAuth discovery ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules (end-user facing) │ ├── scripts/ # check-update helper @@ -58,11 +61,11 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes ``` -Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifest versions, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. +Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifest versions, `gemini-extension.json`, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. ## Version & Release Rules -- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, and `.kimi-plugin/plugin.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. +- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.kimi-plugin/plugin.json`, and `gemini-extension.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. - `version.txt` lives inside `skills/agentkey/` (not at repo root) so it travels with the skill when the Skills CLI copies the subdirectory. `release-please-config.json` points at this path via `version-file`. - Tag format: `v` prefix (e.g. `v0.4.5`) - Plugin updates trigger on **GitHub Release** publication, not on plain commits @@ -89,6 +92,13 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Kimi displays `Run /new or /reload to apply plugin changes.` after install. Once reloaded, the user completes native MCP OAuth with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that authentication is required. - Keep the endpoint URL in sync with the root `.mcp.json` and `.codex-plugin/mcp.json`. +**Changes to `gemini-extension.json`:** +- The manifest MUST remain at the repository root because Gemini installs the repository as the extension root and expects the extension name to match its install directory. +- Keep `mcpServers.agentkey` inline and use `httpUrl` for the Streamable HTTP endpoint. Do not use the SSE-only `url` field for `/v1/mcp`. +- Do not add static credentials, `settings`, custom headers, or `trust`. Gemini discovers the AgentKey OAuth metadata after the server's 401, and users authenticate with `/mcp auth agentkey`. +- Do not duplicate `skills/agentkey/` or add an always-loaded `GEMINI.md`; Gemini discovers the existing skill automatically. +- Keep the endpoint URL in sync with `.mcp.json`, `.codex-plugin/mcp.json`, and `.kimi-plugin/plugin.json`. + **Changes to install/uninstall docs:** - Update both `README.md` and `docs/README_zh.md` together — they mirror each other - The canonical install is always the two-command sequence (`npx skills add …` + `npx -y @agentkey/cli --auth-login`). Don't imply either command does both. @@ -100,4 +110,5 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - `@agentkey/cli --auth-login` auto-writes MCP configs for 16 agents (canonical list lives in `AGENT_REGISTRY` in `../AgentKey-Server/cli/src/lib/mcp-clients.ts`): Claude Code, Claude Desktop, Cursor, Codex, Gemini CLI, OpenCode, Qwen Code, iFlow CLI, Kimi CLI, Kiro CLI, Windsurf, Warp, Amp, Crush, droid, openclaw. The `--only ` flag (used by install.sh's `MCP_TARGETS` and install.ps1's `$McpTargets`) filters this list — its id values MUST match `npx skills add -a` ids, with `claude-desktop` as the one documented MCP-only exception. Goose / kode / kilo still need a manual JSON paste (see SKILL.md's "Fallback" section); when adding more agents server-side, keep `MCP_AUTO_AGENTS` in both install scripts and the cleanup list in both uninstall scripts in sync. - `.mcp.json` registers the remote-HTTP MCP endpoint (`https://api.agentkey.app/v1/mcp`) in Claude Code plugin mode; the API key flows from plugin userConfig into the `Authorization: Bearer ${user_config.AGENTKEY_API_KEY}` header (no stdio binary is launched) - `.kimi-plugin/plugin.json` registers the same endpoint inline in Kimi Code plugin mode. After reloading, the user starts Kimi's native MCP OAuth flow with `/mcp-config login plugin-agentkey:agentkey`. +- `gemini-extension.json` registers the same endpoint through `httpUrl` in Gemini CLI extension mode. Gemini discovers the existing `skills/agentkey/` tree and authenticates through `/mcp auth agentkey`. - `README.md` / `docs/README_zh.md` are the public-facing docs; keep them in sync with any structural changes diff --git a/.github/workflows/scripts-test.yml b/.github/workflows/scripts-test.yml index 1018093..12fb843 100644 --- a/.github/workflows/scripts-test.yml +++ b/.github/workflows/scripts-test.yml @@ -3,11 +3,13 @@ on: push: paths: - 'skills/agentkey/scripts/**' + - 'gemini-extension.json' - 'tests/**' - '.github/workflows/scripts-test.yml' pull_request: paths: - 'skills/agentkey/scripts/**' + - 'gemini-extension.json' - 'tests/**' jobs: diff --git a/.github/workflows/verify-version-sync.yml b/.github/workflows/verify-version-sync.yml index fcfbef2..1b5a179 100644 --- a/.github/workflows/verify-version-sync.yml +++ b/.github/workflows/verify-version-sync.yml @@ -14,6 +14,7 @@ on: - '.claude-plugin/plugin.json' - '.codex-plugin/plugin.json' - '.kimi-plugin/plugin.json' + - 'gemini-extension.json' - 'release-please-config.json' pull_request: paths: @@ -23,6 +24,7 @@ on: - '.claude-plugin/plugin.json' - '.codex-plugin/plugin.json' - '.kimi-plugin/plugin.json' + - 'gemini-extension.json' - 'release-please-config.json' jobs: @@ -39,18 +41,21 @@ jobs: claude_plugin=$(python3 -c 'import json; print(json.load(open(".claude-plugin/plugin.json"))["version"])') codex_plugin=$(python3 -c 'import json; print(json.load(open(".codex-plugin/plugin.json"))["version"])') kimi_plugin=$(python3 -c 'import json; print(json.load(open(".kimi-plugin/plugin.json"))["version"])') + gemini_extension=$(python3 -c 'import json; print(json.load(open("gemini-extension.json"))["version"])') skill=$(awk '/^---/{c++; next} c==1 && /^version:/{print $2; exit}' skills/agentkey/SKILL.md) echo "version.txt: $canonical" echo "check-update.sh: $script" echo "Claude plugin: $claude_plugin" echo "Codex plugin: $codex_plugin" echo "Kimi plugin: $kimi_plugin" + echo "Gemini extension: $gemini_extension" echo "SKILL.md: $skill" if [ "$canonical" != "$script" ] \ || [ "$canonical" != "$claude_plugin" ] \ || [ "$canonical" != "$codex_plugin" ] \ || [ "$canonical" != "$kimi_plugin" ] \ + || [ "$canonical" != "$gemini_extension" ] \ || [ "$canonical" != "$skill" ]; then - echo "::error::Version drift detected. release-please syncs all six values from version.txt — re-run release-please or restore the values manually." + echo "::error::Version drift detected. release-please syncs all seven values from version.txt — re-run release-please or restore the values manually." exit 1 fi diff --git a/AGENTS.md b/AGENTS.md index 7c0f924..186bffb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,6 +18,7 @@ The same repo also works as: - a **Claude Code plugin** (`.claude-plugin/plugin.json` + root `.mcp.json`) — the plugin's `userConfig` injects the API key via `${user_config.AGENTKEY_API_KEY}`, substituting for step 2. - a **Codex plugin** (`.codex-plugin/plugin.json` + `.codex-plugin/mcp.json`, distributed through `.agents/plugins/marketplace.json`; the repo is its own marketplace: `codex plugin marketplace add chainbase-labs/agentkey`). Codex plugins have no `userConfig`/header-interpolation mechanism, so auth uses MCP OAuth via the server's RFC 9728 metadata discovery (`type` + `url` only in mcp.json), substituting for step 2. - a **Kimi Code plugin** (`.kimi-plugin/plugin.json`). Kimi requires `mcpServers` to be an inline object in the manifest. The remote AgentKey endpoint uses Kimi's native MCP OAuth flow; after install Kimi shows the standard `/reload` hint, then the user signs in with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that OAuth is required. +- a **Gemini CLI extension** (root `gemini-extension.json` + `skills/`). Gemini requires the manifest at the extension root, discovers bundled agent skills automatically, and connects to AgentKey with `httpUrl` plus native MCP OAuth discovery. `/mcp auth agentkey` substitutes for step 2. ## Directory Structure @@ -31,6 +32,7 @@ agentkey/ │ └── plugin.json # Kimi Code manifest with inline HTTP MCP entry (OAuth) ├── .agents/plugins/marketplace.json # Codex marketplace listing this repo as a local-source plugin ├── .mcp.json # Auto-registers AgentKey MCP when installed as a Claude Code plugin +├── gemini-extension.json # Gemini CLI extension — Streamable HTTP + OAuth discovery ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules (end-user facing) │ ├── scripts/ # check-update helper @@ -58,11 +60,11 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes ``` -Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifest versions, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. +Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifest versions, `gemini-extension.json`, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. ## Version & Release Rules -- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, and `.kimi-plugin/plugin.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. +- `skills/agentkey/version.txt`, the versions in `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.kimi-plugin/plugin.json`, and `gemini-extension.json`, plus `CHANGELOG.md`, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them. - `version.txt` lives inside `skills/agentkey/` (not at repo root) so it travels with the skill when the Skills CLI copies the subdirectory. `release-please-config.json` points at this path via `version-file`. - Tag format: `v` prefix (e.g. `v0.4.5`) - Plugin updates trigger on **GitHub Release** publication, not on plain commits @@ -89,6 +91,13 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Kimi displays `Run /new or /reload to apply plugin changes.` after install. Once reloaded, the user completes native MCP OAuth with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that authentication is required. - Keep the endpoint URL in sync with the root `.mcp.json` and `.codex-plugin/mcp.json`. +**Changes to `gemini-extension.json` (Gemini CLI extension path):** +- The manifest MUST remain at the repository root because Gemini installs the repository as the extension root and expects the extension name to match its install directory. +- Keep `mcpServers.agentkey` inline and use `httpUrl` for the Streamable HTTP endpoint. Do not use the SSE-only `url` field for `/v1/mcp`. +- Do not add static credentials, `settings`, custom headers, or `trust`. Gemini discovers the AgentKey OAuth metadata after the server's 401, and users authenticate with `/mcp auth agentkey`. +- Do not duplicate `skills/agentkey/` or add an always-loaded `GEMINI.md`; Gemini discovers the existing skill automatically. +- Keep the endpoint URL in sync with `.mcp.json`, `.codex-plugin/mcp.json`, and `.kimi-plugin/plugin.json`. + **Changes to install/uninstall docs:** - Update both `README.md` and `docs/README_zh.md` together — they mirror each other - The canonical install is always the two-command sequence (`npx skills add …` + `npx -y @agentkey/cli --auth-login`). Don't imply either command does both. @@ -101,4 +110,5 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Root `.mcp.json` registers the remote-HTTP MCP endpoint (`https://api.agentkey.app/v1/mcp`) in Claude Code plugin mode; the API key flows from plugin userConfig into the `Authorization: Bearer ${user_config.AGENTKEY_API_KEY}` header (no stdio binary is launched) - `.codex-plugin/mcp.json` registers the same endpoint in Codex plugin mode, authenticated via MCP OAuth (RFC 9728 discovery; no `oauth_resource` — see checklist above) - `.kimi-plugin/plugin.json` registers the same endpoint inline in Kimi Code plugin mode. After reloading, the user starts Kimi's native MCP OAuth flow with `/mcp-config login plugin-agentkey:agentkey`. +- `gemini-extension.json` registers the same endpoint through `httpUrl` in Gemini CLI extension mode. Gemini discovers the existing `skills/agentkey/` tree and authenticates through `/mcp auth agentkey`. - `README.md` / `docs/README_zh.md` are the public-facing docs; keep them in sync with any structural changes diff --git a/README.md b/README.md index a756518..ddccc15 100644 --- a/README.md +++ b/README.md @@ -380,6 +380,18 @@ Kimi copies local plugins into its managed plugin directory. Re-run `/plugins in If you previously worked around an older AgentKey plugin by adding a user-global `agentkey` entry through `/mcp-config`, remove that old entry once with `/mcp-config remove agentkey` before reloading. The plugin now owns its namespaced MCP entry; keeping both would create duplicate tools and authentication attempts. +**Gemini CLI extension mode** — install the repository as an extension. The root `gemini-extension.json` bundles the existing AgentKey skill and the remote Streamable HTTP MCP server, so there is **no API key to paste and no second `@agentkey/cli` step**: + +```bash +# Public install +gemini extensions install https://github.com/chainbase-labs/agentkey + +# Or link a local checkout for development +gemini extensions link /absolute/path/to/agentkey +``` + +Restart Gemini CLI after installing or linking. If the MCP server requires authentication, run `/mcp auth agentkey` and approve the browser authorization; Gemini then stores and refreshes the OAuth tokens. Use `/mcp reload` after changing the server configuration. + **Repo layout:** ``` @@ -392,6 +404,7 @@ agentkey/ │ └── plugin.json # Kimi manifest with inline MCP OAuth entry ├── .agents/plugins/marketplace.json # Codex marketplace (this repo is its own marketplace) ├── .mcp.json # Used when installed as a Claude Code plugin +├── gemini-extension.json # Gemini CLI extension manifest (MCP OAuth + skills) ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules │ ├── scripts/ # check-update helper @@ -403,7 +416,7 @@ agentkey/ └── uninstall.ps1 # Windows PowerShell uninstaller ``` -**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifests, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset. +**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, all three plugin manifests, `gemini-extension.json`, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset. diff --git a/docs/README_zh.md b/docs/README_zh.md index 9d5c4fc..57ed12a 100644 --- a/docs/README_zh.md +++ b/docs/README_zh.md @@ -380,6 +380,18 @@ Kimi 会把本地插件复制到自己的托管目录。修改原 checkout 后 如果你曾为旧版 AgentKey plugin 手工通过 `/mcp-config` 添加过用户全局的 `agentkey` 条目,请在 reload 前执行一次 `/mcp-config remove agentkey` 删除旧条目。现在 plugin 会维护自己的命名空间 MCP;同时保留两份会造成工具和鉴权流程重复。 +**Gemini CLI 扩展模式** —— 把本仓库直接安装为 extension。根目录的 `gemini-extension.json` 会捆绑现有 AgentKey skill 和远程 Streamable HTTP MCP server,**不用粘贴 API Key,也不需要再单独跑 `@agentkey/cli`**: + +```bash +# 公开安装 +gemini extensions install https://github.com/chainbase-labs/agentkey + +# 或链接本地 checkout,用于开发 +gemini extensions link /absolute/path/to/agentkey +``` + +安装或链接后重启 Gemini CLI。如果 MCP server 提示需要认证,执行 `/mcp auth agentkey` 并在浏览器完成授权;之后 Gemini 会保存并自动刷新 OAuth token。修改 server 配置后可执行 `/mcp reload`。 + **仓库结构:** ``` @@ -392,6 +404,7 @@ agentkey/ │ └── plugin.json # Kimi 清单,内联 MCP OAuth 配置 ├── .agents/plugins/marketplace.json # Codex marketplace(本仓库即自己的 marketplace) ├── .mcp.json # 作为 Claude Code 插件安装时使用 +├── gemini-extension.json # Gemini CLI 扩展清单(MCP OAuth + skills) ├── skills/agentkey/ │ ├── SKILL.md # 决策树 & 路由规则 │ ├── scripts/ # check-update 辅助脚本 @@ -403,7 +416,7 @@ agentkey/ └── uninstall.ps1 # Windows PowerShell 卸载脚本 ``` -**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、三个插件清单和 `CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。 +**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、三个插件清单、`gemini-extension.json` 和 `CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。 diff --git a/gemini-extension.json b/gemini-extension.json new file mode 100644 index 0000000..451088e --- /dev/null +++ b/gemini-extension.json @@ -0,0 +1,10 @@ +{ + "name": "agentkey", + "version": "1.13.1", + "description": "AgentKey gives Gemini CLI one-stop access to live web, social, finance, crypto, e-commerce, business, weather, maps, and travel data.", + "mcpServers": { + "agentkey": { + "httpUrl": "https://api.agentkey.app/v1/mcp" + } + } +} diff --git a/release-please-config.json b/release-please-config.json index 9699591..1e9e7e4 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -25,6 +25,11 @@ "path": ".kimi-plugin/plugin.json", "jsonpath": "$.version" }, + { + "type": "json", + "path": "gemini-extension.json", + "jsonpath": "$.version" + }, { "type": "generic", "path": "skills/agentkey/scripts/check-update.sh" diff --git a/tests/gemini-extension.bats b/tests/gemini-extension.bats new file mode 100644 index 0000000..01104e9 --- /dev/null +++ b/tests/gemini-extension.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +setup() { + REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/.." && pwd)" + MANIFEST="$REPO_ROOT/gemini-extension.json" +} + +@test "Gemini extension declares the AgentKey Streamable HTTP server inline" { + python3 - "$MANIFEST" <<'PY' +import json +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + manifest = json.load(handle) + +assert manifest["name"] == "agentkey" +assert manifest["description"] +assert manifest["mcpServers"] == { + "agentkey": { + "httpUrl": "https://api.agentkey.app/v1/mcp", + } +} +PY +} + +@test "Gemini extension relies on native OAuth discovery" { + python3 - "$MANIFEST" <<'PY' +import json +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + manifest = json.load(handle) + +assert "settings" not in manifest +server = manifest["mcpServers"]["agentkey"] +assert "headers" not in server +assert "oauth" not in server +assert "authProviderType" not in server +assert "trust" not in server +PY +} + +@test "Gemini extension bundles the existing AgentKey skill" { + [ -f "$REPO_ROOT/skills/agentkey/SKILL.md" ] + + python3 - "$REPO_ROOT/skills/agentkey/SKILL.md" <<'PY' +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + skill = handle.read() + +frontmatter = skill.split("---", 2)[1] +assert "\nname: agentkey\n" in f"\n{frontmatter}\n" +PY +} From 7a588a63aa1dc6f759137a6c535d5f10e41d3c08 Mon Sep 17 00:00:00 2001 From: Allen <0xfatdog@gmail.com> Date: Mon, 10 Aug 2026 18:17:36 +0800 Subject: [PATCH 4/4] feat: add Antigravity plugin support --- .claude/CLAUDE.md | 14 ++++- .github/workflows/scripts-test.yml | 4 ++ AGENTS.md | 13 +++- README.md | 25 +++++++- docs/README_zh.md | 25 +++++++- mcp_config.json | 7 +++ plugin.json | 5 ++ tests/antigravity-plugin.bats | 98 ++++++++++++++++++++++++++++++ 8 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 mcp_config.json create mode 100644 plugin.json create mode 100644 tests/antigravity-plugin.bats diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index a7ef59c..ac81921 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -23,6 +23,8 @@ It also works as a **Kimi Code plugin** (`.kimi-plugin/plugin.json`). Kimi requi It also works as a **Gemini CLI extension** (root `gemini-extension.json` + `skills/`). Gemini requires the manifest at the extension root, discovers bundled agent skills automatically, and connects to AgentKey with `httpUrl` plus native MCP OAuth discovery. `/mcp auth agentkey` substitutes for step 2. +It also works as an **Antigravity 2.0 and Antigravity CLI plugin** (root `plugin.json` + `mcp_config.json` + `skills/`). Both runtimes use the same package, require `serverUrl` for remote MCP, and authenticate through automatic OAuth discovery. + ## Directory Structure ``` @@ -38,6 +40,8 @@ agentkey/ ├── .agents/plugins/marketplace.json # Codex marketplace listing this repo as a local-source plugin ├── .mcp.json # Auto-registers AgentKey MCP when installed as a Claude Code plugin ├── gemini-extension.json # Gemini CLI extension — Streamable HTTP + OAuth discovery +├── plugin.json # Antigravity desktop/CLI plugin marker +├── mcp_config.json # Antigravity remote MCP entry — serverUrl + OAuth discovery ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules (end-user facing) │ ├── scripts/ # check-update helper @@ -65,7 +69,7 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes ``` -Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all four plugin manifest versions, `gemini-extension.json`, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. +Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all four versioned plugin manifest versions, `gemini-extension.json`, and `CHANGELOG.md`. The Antigravity manifest has no version field. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. ## Version & Release Rules @@ -110,6 +114,13 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Do not duplicate `skills/agentkey/` or add an always-loaded `GEMINI.md`; Gemini discovers the existing skill automatically. - Keep the endpoint URL in sync with `.mcp.json`, `.codex-plugin/mcp.json`, `.cursor-plugin/plugin.json`, and `.kimi-plugin/plugin.json`. +**Changes to root `plugin.json` / `mcp_config.json`:** +- Keep both files at the repository root so Antigravity 2.0 and Antigravity CLI share one plugin package and reuse `skills/agentkey/` without duplication. +- Keep `plugin.json` limited to the documented `$schema`, `name`, and `description` fields. The Antigravity schema has no `version` field, so release-please must not add one. +- Keep `mcpServers.agentkey` inline in `mcp_config.json` and use `serverUrl`; legacy `url` and `httpUrl` fields are unsupported. +- Do not add static credentials, headers, or manual OAuth client secrets. AgentKey supports dynamic client registration, so Antigravity performs automatic OAuth discovery. +- Keep the endpoint URL in sync with `.mcp.json`, `.codex-plugin/mcp.json`, `.cursor-plugin/plugin.json`, `.kimi-plugin/plugin.json`, and `gemini-extension.json`. + **Changes to install/uninstall docs:** - Update both `README.md` and `docs/README_zh.md` together — they mirror each other - The canonical install is always the two-command sequence (`npx skills add …` + `npx -y @agentkey/cli --auth-login`). Don't imply either command does both. @@ -123,4 +134,5 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - `.cursor-plugin/plugin.json` registers the same endpoint inline in Cursor plugin mode, authenticated through Cursor's native MCP OAuth flow - `.kimi-plugin/plugin.json` registers the same endpoint inline in Kimi Code plugin mode. After reloading, the user starts Kimi's native MCP OAuth flow with `/mcp-config login plugin-agentkey:agentkey`. - `gemini-extension.json` registers the same endpoint through `httpUrl` in Gemini CLI extension mode. Gemini discovers the existing `skills/agentkey/` tree and authenticates through `/mcp auth agentkey`. +- Root `plugin.json` and `mcp_config.json` package the existing skill and the same endpoint for both Antigravity 2.0 and Antigravity CLI; remote MCP uses `serverUrl` and automatic OAuth discovery. - `README.md` / `docs/README_zh.md` are the public-facing docs; keep them in sync with any structural changes diff --git a/.github/workflows/scripts-test.yml b/.github/workflows/scripts-test.yml index 12fb843..8c8db60 100644 --- a/.github/workflows/scripts-test.yml +++ b/.github/workflows/scripts-test.yml @@ -4,12 +4,16 @@ on: paths: - 'skills/agentkey/scripts/**' - 'gemini-extension.json' + - 'plugin.json' + - 'mcp_config.json' - 'tests/**' - '.github/workflows/scripts-test.yml' pull_request: paths: - 'skills/agentkey/scripts/**' - 'gemini-extension.json' + - 'plugin.json' + - 'mcp_config.json' - 'tests/**' jobs: diff --git a/AGENTS.md b/AGENTS.md index 233688f..e5f2959 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,6 +20,7 @@ The same repo also works as: - a **Cursor plugin** (`.cursor-plugin/plugin.json`). The Cursor-native manifest bundles `skills/` and an inline remote-HTTP MCP entry. Cursor authenticates through the server's MCP OAuth discovery, substituting for step 2. - a **Kimi Code plugin** (`.kimi-plugin/plugin.json`). Kimi requires `mcpServers` to be an inline object in the manifest. The remote AgentKey endpoint uses Kimi's native MCP OAuth flow; after install Kimi shows the standard `/reload` hint, then the user signs in with `/mcp-config login plugin-agentkey:agentkey` when Kimi reports that OAuth is required. - a **Gemini CLI extension** (root `gemini-extension.json` + `skills/`). Gemini requires the manifest at the extension root, discovers bundled agent skills automatically, and connects to AgentKey with `httpUrl` plus native MCP OAuth discovery. `/mcp auth agentkey` substitutes for step 2. +- an **Antigravity 2.0 and Antigravity CLI plugin** (root `plugin.json` + `mcp_config.json` + `skills/`). Both runtimes use the same package, require `serverUrl` for remote MCP, and authenticate through automatic OAuth discovery. ## Directory Structure @@ -36,6 +37,8 @@ agentkey/ ├── .agents/plugins/marketplace.json # Codex marketplace listing this repo as a local-source plugin ├── .mcp.json # Auto-registers AgentKey MCP when installed as a Claude Code plugin ├── gemini-extension.json # Gemini CLI extension — Streamable HTTP + OAuth discovery +├── plugin.json # Antigravity desktop/CLI plugin marker +├── mcp_config.json # Antigravity remote MCP entry — serverUrl + OAuth discovery ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules (end-user facing) │ ├── scripts/ # check-update helper @@ -63,7 +66,7 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes ``` -Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all four plugin manifest versions, `gemini-extension.json`, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. +Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, all four versioned plugin manifest versions, `gemini-extension.json`, and `CHANGELOG.md`. The Antigravity manifest has no version field. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users. ## Version & Release Rules @@ -108,6 +111,13 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - Do not duplicate `skills/agentkey/` or add an always-loaded `GEMINI.md`; Gemini discovers the existing skill automatically. - Keep the endpoint URL in sync with `.mcp.json`, `.codex-plugin/mcp.json`, `.cursor-plugin/plugin.json`, and `.kimi-plugin/plugin.json`. +**Changes to root `plugin.json` / `mcp_config.json` (Antigravity plugin path):** +- Keep both files at the repository root so Antigravity 2.0 and Antigravity CLI share one plugin package and reuse `skills/agentkey/` without duplication. +- Keep `plugin.json` limited to the documented `$schema`, `name`, and `description` fields. The Antigravity schema has no `version` field, so release-please must not add one. +- Keep `mcpServers.agentkey` inline in `mcp_config.json` and use `serverUrl`; legacy `url` and `httpUrl` fields are unsupported. +- Do not add static credentials, headers, or manual OAuth client secrets. AgentKey supports dynamic client registration, so Antigravity performs automatic OAuth discovery. +- Keep the endpoint URL in sync with `.mcp.json`, `.codex-plugin/mcp.json`, `.cursor-plugin/plugin.json`, `.kimi-plugin/plugin.json`, and `gemini-extension.json`. + **Changes to install/uninstall docs:** - Update both `README.md` and `docs/README_zh.md` together — they mirror each other - The canonical install is always the two-command sequence (`npx skills add …` + `npx -y @agentkey/cli --auth-login`). Don't imply either command does both. @@ -122,4 +132,5 @@ Releases are driven by [release-please](https://github.com/googleapis/release-pl - `.cursor-plugin/plugin.json` registers the same endpoint inline in Cursor plugin mode, authenticated through Cursor's native MCP OAuth flow - `.kimi-plugin/plugin.json` registers the same endpoint inline in Kimi Code plugin mode. After reloading, the user starts Kimi's native MCP OAuth flow with `/mcp-config login plugin-agentkey:agentkey`. - `gemini-extension.json` registers the same endpoint through `httpUrl` in Gemini CLI extension mode. Gemini discovers the existing `skills/agentkey/` tree and authenticates through `/mcp auth agentkey`. +- Root `plugin.json` and `mcp_config.json` package the existing skill and the same endpoint for both Antigravity 2.0 and Antigravity CLI; remote MCP uses `serverUrl` and automatic OAuth discovery. - `README.md` / `docs/README_zh.md` are the public-facing docs; keep them in sync with any structural changes diff --git a/README.md b/README.md index 33f0551..416159a 100644 --- a/README.md +++ b/README.md @@ -396,6 +396,27 @@ gemini extensions link /absolute/path/to/agentkey Restart Gemini CLI after installing or linking. If the MCP server requires authentication, run `/mcp auth agentkey` and approve the browser authorization; Gemini then stores and refreshes the OAuth tokens. Use `/mcp reload` after changing the server configuration. +**Antigravity 2.0 / Antigravity CLI plugin mode** — both runtimes use the root `plugin.json`, `mcp_config.json`, and existing `skills/` directory. The MCP entry uses Antigravity's `serverUrl` schema and automatic OAuth discovery, so there is **no API key to paste and no second `@agentkey/cli` step**. + +For Antigravity 2.0, place the repository at workspace scope or global scope, then restart Antigravity: + +```bash +# Workspace scope +git clone https://github.com/chainbase-labs/agentkey.git /path/to/workspace/.agents/plugins/agentkey + +# Or global scope +git clone https://github.com/chainbase-labs/agentkey.git ~/.gemini/config/plugins/agentkey +``` + +For Antigravity CLI, install a local checkout and verify it is registered: + +```bash +agy plugin install /absolute/path/to/agentkey +agy plugin list +``` + +Antigravity 2.0 exposes OAuth through **Settings → Customizations → Authenticate**. In Antigravity CLI, open `/mcp` to inspect or reload the server and follow the authentication prompt when it first connects. + **Repo layout:** ``` @@ -411,6 +432,8 @@ agentkey/ ├── .agents/plugins/marketplace.json # Codex marketplace (this repo is its own marketplace) ├── .mcp.json # Used when installed as a Claude Code plugin ├── gemini-extension.json # Gemini CLI extension manifest (MCP OAuth + skills) +├── plugin.json # Antigravity desktop/CLI plugin manifest +├── mcp_config.json # Antigravity remote MCP entry (serverUrl + OAuth) ├── skills/agentkey/ │ ├── SKILL.md # Decision tree + routing rules │ ├── scripts/ # check-update helper @@ -422,7 +445,7 @@ agentkey/ └── uninstall.ps1 # Windows PowerShell uninstaller ``` -**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, all four plugin manifests, `gemini-extension.json`, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset. +**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, all four versioned plugin manifests, `gemini-extension.json`, and `CHANGELOG.md`. The Antigravity schema has no `version` field, so its root `plugin.json` is not part of version syncing. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset. diff --git a/docs/README_zh.md b/docs/README_zh.md index 644d5dc..45d91d0 100644 --- a/docs/README_zh.md +++ b/docs/README_zh.md @@ -396,6 +396,27 @@ gemini extensions link /absolute/path/to/agentkey 安装或链接后重启 Gemini CLI。如果 MCP server 提示需要认证,执行 `/mcp auth agentkey` 并在浏览器完成授权;之后 Gemini 会保存并自动刷新 OAuth token。修改 server 配置后可执行 `/mcp reload`。 +**Antigravity 2.0 / Antigravity CLI 插件模式** —— 两个运行时共用根目录的 `plugin.json`、`mcp_config.json` 和现有 `skills/`。MCP 配置使用 Antigravity 规定的 `serverUrl` 并依赖自动 OAuth discovery,**不用粘贴 API Key,也不需要再单独运行 `@agentkey/cli`**。 + +Antigravity 2.0 可按 workspace 或全局范围放置插件,完成后重启 Antigravity: + +```bash +# Workspace 范围 +git clone https://github.com/chainbase-labs/agentkey.git /path/to/workspace/.agents/plugins/agentkey + +# 或全局范围 +git clone https://github.com/chainbase-labs/agentkey.git ~/.gemini/config/plugins/agentkey +``` + +Antigravity CLI 使用本地 checkout 安装并确认注册结果: + +```bash +agy plugin install /absolute/path/to/agentkey +agy plugin list +``` + +Antigravity 2.0 在 **Settings → Customizations → Authenticate** 中完成 OAuth。Antigravity CLI 首次连接时按认证提示操作;需要检查状态或重新加载 server 时打开 `/mcp`。 + **仓库结构:** ``` @@ -411,6 +432,8 @@ agentkey/ ├── .agents/plugins/marketplace.json # Codex marketplace(本仓库即自己的 marketplace) ├── .mcp.json # 作为 Claude Code 插件安装时使用 ├── gemini-extension.json # Gemini CLI 扩展清单(MCP OAuth + skills) +├── plugin.json # Antigravity 桌面端/CLI 插件清单 +├── mcp_config.json # Antigravity 远程 MCP 配置(serverUrl + OAuth) ├── skills/agentkey/ │ ├── SKILL.md # 决策树 & 路由规则 │ ├── scripts/ # check-update 辅助脚本 @@ -422,7 +445,7 @@ agentkey/ └── uninstall.ps1 # Windows PowerShell 卸载脚本 ``` -**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、四个插件清单、`gemini-extension.json` 和 `CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。 +**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、四个带版本号的插件清单、`gemini-extension.json` 和 `CHANGELOG.md`。Antigravity schema 没有 `version` 字段,因此根目录 `plugin.json` 不参与版本同步。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。 diff --git a/mcp_config.json b/mcp_config.json new file mode 100644 index 0000000..ed3a731 --- /dev/null +++ b/mcp_config.json @@ -0,0 +1,7 @@ +{ + "mcpServers": { + "agentkey": { + "serverUrl": "https://api.agentkey.app/v1/mcp" + } + } +} diff --git a/plugin.json b/plugin.json new file mode 100644 index 0000000..bbc779e --- /dev/null +++ b/plugin.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://antigravity.google/schemas/v1/plugin.json", + "name": "agentkey", + "description": "AgentKey gives Antigravity one-stop access to live web, social, finance, crypto, e-commerce, business, weather, maps, and travel data." +} diff --git a/tests/antigravity-plugin.bats b/tests/antigravity-plugin.bats new file mode 100644 index 0000000..32e23ca --- /dev/null +++ b/tests/antigravity-plugin.bats @@ -0,0 +1,98 @@ +#!/usr/bin/env bats + +setup() { + REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/.." && pwd)" + MANIFEST="$REPO_ROOT/plugin.json" + MCP_CONFIG="$REPO_ROOT/mcp_config.json" +} + +@test "Antigravity plugin manifest follows the documented schema" { + python3 - "$MANIFEST" <<'PY' +import json +import re +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + manifest = json.load(handle) + +assert manifest["$schema"] == "https://antigravity.google/schemas/v1/plugin.json" +assert re.fullmatch(r"[a-zA-Z0-9-_]+", manifest["name"]) +assert manifest["name"] == "agentkey" +assert manifest["description"] +assert set(manifest) == {"$schema", "name", "description"} +assert "version" not in manifest +PY +} + +@test "Antigravity plugin declares remote MCP with serverUrl" { + python3 - "$MCP_CONFIG" <<'PY' +import json +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + config = json.load(handle) + +assert config == { + "mcpServers": { + "agentkey": { + "serverUrl": "https://api.agentkey.app/v1/mcp", + } + } +} +server = config["mcpServers"]["agentkey"] +assert "url" not in server +assert "httpUrl" not in server +PY +} + +@test "Antigravity plugin relies on automatic OAuth discovery" { + python3 - "$MCP_CONFIG" <<'PY' +import json +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + server = json.load(handle)["mcpServers"]["agentkey"] + +assert "headers" not in server +assert "oauth" not in server +assert "authProviderType" not in server +PY +} + +@test "Antigravity desktop and CLI share the existing AgentKey skill" { + [ -f "$REPO_ROOT/skills/agentkey/SKILL.md" ] + + python3 - "$REPO_ROOT/skills/agentkey/SKILL.md" <<'PY' +import sys + +with open(sys.argv[1], encoding="utf-8") as handle: + skill = handle.read() + +frontmatter = skill.split("---", 2)[1] +assert "\nname: agentkey\n" in f"\n{frontmatter}\n" +PY +} + +@test "Antigravity endpoint stays synchronized with every plugin client" { + python3 - "$REPO_ROOT" <<'PY' +import json +import os +import sys + +root = sys.argv[1] +configs = { + "claude": (".mcp.json", "url"), + "codex": (".codex-plugin/mcp.json", "url"), + "cursor": (".cursor-plugin/plugin.json", "url"), + "kimi": (".kimi-plugin/plugin.json", "url"), + "gemini": ("gemini-extension.json", "httpUrl"), + "antigravity": ("mcp_config.json", "serverUrl"), +} +endpoints = {} +for client, (relative_path, field) in configs.items(): + with open(os.path.join(root, relative_path), encoding="utf-8") as handle: + endpoints[client] = json.load(handle)["mcpServers"]["agentkey"][field] + +assert set(endpoints.values()) == {"https://api.agentkey.app/v1/mcp"}, endpoints +PY +}