## Summary - install the AgentKey Skill through the Skills CLI universal target for DSH-only installs - avoid passing either dsh or the unsupported global PromptScript target while preserving explicit mixed-agent targets - update Bash, PowerShell, English/Chinese setup guidance, retry instructions, and release-asset source docs - add Bash mixed-target coverage and a Windows PowerShell invocation regression ## Root cause skills@1.5.23 -g -y adds PromptScript to its universal target set even though PromptScript has no global install directory. The canonical AgentKey Skill still installs, but the command prints Failed to install 1. Explicitly targeting universal writes the same ~/.agents/skills/agentkey copy without selecting PromptScript. ## Validation - bats tests/ — 42/42 - bash -n scripts/install.sh - bash -n scripts/uninstall.sh - bash -n scripts/build-release-assets.sh - scripts/build-release-assets.sh with an isolated output directory - workflow YAML parse - git diff --check - Windows behavior regression added to the windows-latest Scripts tests job ## Deployment follow-up Merging/releasing this PR does not automatically update agentkey.app/install.sh. After release, publish the current Bash/PowerShell install and uninstall scripts to the website origin and purge the CDN; the live endpoints were serving stale pre-DSH content during verification. Co-authored-by: Allen <0xfatdog@gmail.com>
17 KiB
AGENTS.md
This file provides guidance to coding agents (Codex, and any AGENTS.md-aware tool) when working with code in this repository. It mirrors .claude/CLAUDE.md — keep the two in sync.
What This Repo Is
AgentKey Skill ships the agent-side half of AgentKey: a single skill that teaches agents how to call the AgentKey MCP tools correctly.
AgentKey has two pieces and a full end-user install is two commands:
npx skills add chainbase-labs/agentkey— installs this skill. It does NOT register the MCP server.npx -y @agentkey/cli --auth-login— runs the AgentKey CLI (@agentkey/clifrom../AgentKey-Server/cli). It mints an API key via device-code login and writes a remote-HTTP MCP block (pointing athttps://api.agentkey.app/v1/mcp) into agent configs (Claude Code, Codex, Cursor, and 13 more). The hosted MCP server itself lives at/v1/mcpon AgentKey-Server.
The skill is useless without the MCP server; the MCP server works without the skill but the agent won't know to prefer it over built-in web search. Keep this mental model when editing docs — do not let either command drift into claiming it does both.
The same repo also works as:
- a Claude Code plugin (
.claude-plugin/plugin.json+ root.mcp.json) — the remote HTTP entry has no static authentication header, so Claude Code follows the server's 401/RFC 9728 metadata into its native MCP OAuth flow, 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 nouserConfig/header-interpolation mechanism, so auth uses MCP OAuth via the server's RFC 9728 metadata discovery (type+urlonly in mcp.json), substituting for step 2. - a Cursor plugin (
.cursor-plugin/plugin.json). The Cursor-native manifest bundlesskills/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 requiresmcpServersto be an inline object in the manifest. The remote AgentKey endpoint uses Kimi's native MCP OAuth flow; after install Kimi shows the standard/reloadhint, then the user signs in with/mcp-config login plugin-agentkey:agentkeywhen 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 withhttpUrlplus native MCP OAuth discovery.oauth.enabledrequests the browser flow automatically;/mcp auth agentkeyis the manual fallback. Either 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, requireserverUrlfor remote MCP, and authenticate through automatic OAuth discovery. - a CLI-managed DeepSeek Harness integration. The installers detect
${DSH_HOME:-~/.dsh}/dsh, install the skill globally through the Skills CLI'suniversaltarget (neverskills add -a dsh), and let@agentkey/cli --auth-login --only dshmaintain one marked@deepseek-ai/dsh-mcp-cliententry in$DSH_HOME/cordis.patch.yml. DSH composes that home layer over current and future profiles; running processes watch it through HMR. DSH rc.7 has no MCP OAuthauthProvider, so this path requires the CLI-written Bearer key. Tool policy may still hide tools.
Directory Structure
agentkey/
├── .claude-plugin/plugin.json # Claude Code plugin manifest
├── .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
├── .mcp.json # Claude MCP entry — HTTP + OAuth discovery, no static headers
├── 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
│ └── version.txt # Managed by release-please only — must live inside the skill so it survives `npx skills add`
└── scripts/
├── build-release-assets.sh # Builds Skill + Gemini GitHub Release assets
└── uninstall.sh # End-user cleanup helper
Key Commands
# Test a local edit against every detected agent
npx skills add .
# Daily commit (does NOT trigger user updates)
git add -A && git commit -m "..." && git push origin main
# Publish a new release
# Releases are cut automatically by release-please on merge to main.
# To manually trigger: merge a conventional-commit PR; release-please will open
# a Release PR; merge that to tag and create the GitHub Release.
# Undo a bad release
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: 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
skills/agentkey/version.txt, the versions in.claude-plugin/plugin.json,.codex-plugin/plugin.json,.cursor-plugin/plugin.json,.kimi-plugin/plugin.json, andgemini-extension.json, plusCHANGELOG.md, are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them.version.txtlives insideskills/agentkey/(not at repo root) so it travels with the skill when the Skills CLI copies the subdirectory.release-please-config.jsonpoints at this path viaversion-file.- Tag format:
vprefix (e.g.v0.4.5) - Plugin updates trigger on GitHub Release publication, not on plain commits
npx skills updatepulls from the default branch, so main must always be shippable
Change Checklists
Changes to any plugin.json:
- release-please automatically bumps all four manifest versions +
CHANGELOG.mdfrom 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):
- Keep the remote server as the minimal
type: http+urlentry. Do not addheaders,headersHelper,userConfig, a static token, or an API-key placeholder. - Claude Code treats any configured
Authorizationheader as explicit header authentication and does not fall back to OAuth when that header receives a 401. With no header, the server's 401 and RFC 9728 protected-resource metadata expose the native Authenticate action andclaude mcp login plugin:agentkey:agentkeyflow. - This applies only to the Claude Code plugin path; the Skills-CLI path still writes API-key MCP config through
npx @agentkey/cli --auth-login.
Changes to .codex-plugin/mcp.json (Codex plugin path):
- Codex plugin MCP config does NOT support
${user_config.*}interpolation — a literal${…}would be sent as the Authorization header. Auth is MCP OAuth via RFC 9728 discovery: the server's 401 advertisesresource_metadata, and the rmcp client automatically appendsresource=<server url>to the authorization request. - Do NOT set
oauth_resource: rmcp already sendsresourceon its own, and Codex appendsoauth_resourceas a secondresourcequery param without deduplication (codex-rs/rmcp-client/src/perform_oauth_login.rs). Clerk enforces RFC 6749 (no repeated params) and rejects the request withinvalid_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 each plugin endpoint aligned with the Server routing contract. Kimi uses the attributed
/kimi/v1/mcpalias; the other plugin manifests currently use/v1/mcp. Do not require every client path to be byte-identical.
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
interfaceinto this manifest. - Keep
skillspointed at./skills/andmcpServersas 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 Cursor endpoint at
/v1/mcpuntil the Server routing contract assigns it a client-specific path. - This repository is a single Cursor plugin, so
.cursor-plugin/marketplace.jsonis not required. Submit the public repository URL through Cursor's marketplace publisher.
Changes to .kimi-plugin/plugin.json (Kimi Code plugin path):
mcpServersMUST 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/kimi/v1/mcp"}}. Kimi infers the transport fromurl; the path preserves Kimi attribution while reaching the same MCP surface. - 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:agentkeywhen Kimi reports that authentication is required. - Keep the Kimi endpoint aligned with the Server's
/kimi/v1/mcpattributed alias.
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.agentkeyinline and usehttpUrlfor the Streamable HTTP endpoint. Do not use the SSE-onlyurlfield for/v1/mcp. - Keep
oauthlimited to{"enabled":true}so Gemini starts its native browser flow after the server's 401 while still discovering all endpoints dynamically. Do not add static credentials, OAuth endpoints/client credentials,settings, custom headers, ortrust./mcp auth agentkeyremains the manual fallback. - Do not duplicate
skills/agentkey/or add an always-loadedGEMINI.md; Gemini discovers the existing skill automatically. - Keep the Gemini endpoint at
/v1/mcpuntil the Server routing contract assigns it a client-specific path.
Changes to GitHub Release assets:
- Keep
agentkey.skillfor Skill consumers, but never publish it as the only generic Release asset. Gemini CLI treats a lone generic asset as an extension archive and only extracts.tar.gzor.zipfiles. - Run
scripts/build-release-assets.shto produceagentkey.skillplusdarwin.agentkey.tar.gz,linux.agentkey.tar.gz, andwin32.agentkey.zip. - Every platform-named Gemini archive MUST contain
gemini-extension.jsonandskills/agentkey/SKILL.mdat its archive root. Keep the platform prefixes so Gemini selects these archives beforeagentkey.skill.
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.jsonlimited to the documented$schema,name, anddescriptionfields. The Antigravity schema has noversionfield, so release-please must not add one. - Keep
mcpServers.agentkeyinline inmcp_config.jsonand useserverUrl; legacyurlandhttpUrlfields 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 Antigravity endpoint at
/v1/mcpuntil the Server routing contract assigns it a client-specific path.
Changes to install/uninstall docs:
- Update both
README.mdanddocs/README_zh.mdtogether — 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. - Do not re-add OpenClaw / per-agent installers without a new design — historical context is in git history (removed in chore/remove-archive-directory)
- Describe DSH as a CLI-managed MCP integration, not a native installable DSH plugin. Do not reintroduce the removed README-only
.dsh-plugin/agentkey/placeholder without a real package and install contract. - Never commit a real DSH Authorization key. Tests and examples use obviously fake values; production keys live only in the user's local
cordis.patch.yml.
Architecture Constraints
- Setup mode in SKILL.md runs
! npx -y @agentkey/cli --auth-loginto authenticate via browser — same command as step 2 of the public install @agentkey/cli --auth-loginauto-writes MCP configs for 18 agents (canonical list lives inAGENT_REGISTRYin../AgentKey-Server/cli/src/lib/mcp-clients.ts), including Hermes and DeepSeek Harness. The--only <ids>flag filters this list. Most ids matchnpx skills add -a;claude-desktophas no skill path,hermesis a local CLI exception, anddshdeliberately uses the globalskills add -g -a universalpath. Goose / kode / kilo still need manual MCP setup. Keep the Bash/PowerShell installer target subsets and uninstall cleanup behavior synchronized with their intended registry entries.- DSH automatic config is
${DSH_HOME:-~/.dsh}/cordis.patch.yml, with exactly one# agentkey:start/# agentkey:endblock in the home patch. The Loader entry id andserverNameare bothagentkey. Existing per-profile managed blocks are migration inputs only; recognize markers at column 1 and never inside indented YAML block scalars. Structurally detected unmarked legacy Loader rows must stop migration for manual removal, never trigger guessed text deletion. Symlinked profile patches are read-only migration inputs: allow clean ones, but stop before all writes when either legacy form is present. A profile is not required before installation. Archive a legacy.agent-presets/agentkeydirectory instead of deleting it.Mountedis not connection proof; readiness requires the three core MCP tools to be visible and callable in the intended tool policy. - Root
.mcp.jsonregisters the remote-HTTP MCP endpoint (https://api.agentkey.app/v1/mcp) in Claude Code plugin mode with no static header oruserConfig; Claude Code performs native MCP OAuth discovery after the server's 401 response. .codex-plugin/mcp.jsonregisters the same endpoint in Codex plugin mode, authenticated via MCP OAuth (RFC 9728 discovery; nooauth_resource— see checklist above).cursor-plugin/plugin.jsonregisters the same endpoint inline in Cursor plugin mode, authenticated through Cursor's native MCP OAuth flow.kimi-plugin/plugin.jsonregisters the attributedhttps://api.agentkey.app/kimi/v1/mcpendpoint 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.jsonregisters the same endpoint throughhttpUrlin Gemini CLI extension mode. Gemini discovers the existingskills/agentkey/tree;oauth.enabledstarts native OAuth automatically and/mcp auth agentkeyretries it manually.- Root
plugin.jsonandmcp_config.jsonpackage the existing skill and the same endpoint for both Antigravity 2.0 and Antigravity CLI; remote MCP usesserverUrland automatic OAuth discovery. README.md/docs/README_zh.mdare the public-facing docs; keep them in sync with any structural changes