dev-o-los/dodopayments
Dodo Payments tools for AI coding agents, including integration agent skills and the Dodo Payments API and docs MCP servers.
Changelog
0.5.0 - 2026-08-07
Adopts the Agent Plugins 1.0.0 specification and makes every provider-specific manifest a generated artifact of one canonical source. Two defects found during the migration were already shipping.
Fixed
- The documented Cursor install shipped zero working skills.
skills/was seventeen symlinks into theskills-srcgit submodule, and distribution is a plaingit clone, which does not fetch submodules. A bare clone of0.4.0yields 0 resolvableSKILL.mdfiles and 17 dangling symlinks. Skills are now vendored as real files: the same clone yields 17 and 0. If you installed Cursor from a clone before 0.5.0, re-clone. - The OpenCode package shipped skills nothing could discover. OpenCode scans six fixed locations, none inside an installed package, so users got MCP servers and no skills.
skills.pathsin your ownopencode.jsonis now documented and verified; see the package README. Settingconfig.skillsfrom the plugin'sconfighook is not a substitute — the skill index is built beforeconfighooks run. The plugin module also exports nothing but its default function: OpenCode's loader throwsPlugin export is not a functionon any non-function named export and silently skips the whole plugin, MCP servers included. enabledwas not a legal key in a specmcp.json. The Agent Plugins server union is closed (additionalProperties: false), so a stray key silently skips the entire server entry. Copying.mcp.jsonverbatim would have disabled both servers.enablednow exists only in the generated legacy.mcp.json, which Claude Code and Cursor still read.
Added
- Root
plugin.jsonandmcp.json, conforming to Agent Plugins 1.0.0. Verified on Codex 0.147.0: seventeen skills, two MCP servers, withPLUGIN_ROOT/PLUGIN_DATAinjected per spec. Cursor 3.14.27 also recognises the spec directly — its agent host carries both schema URLs and the spec'snameregex. VS Code 1.125.1 does not: theagent-plugins.orgstring appears nowhere in its bundle, and it loads this repo through the generated.claude-plugin/plugin.jsonand.mcp.jsoninstead. That works, and is why the compatibility manifests are still generated. - Kiro support via the
dev.kiroextension namespace inplugin.json, which is what the spec's reverse-domain namespaces are for. - Gemini CLI support via a generated
gemini-extension.json— MCP servers only. Gemini has no agent-skill primitive, so the seventeen skills are not available there and both the manifest description and the README say so rather than implying parity. scripts/conformance.mjs, a spec validator. The specification ships none and its failure semantics are silent, so this asserts the expected skill set explicitly (from.skills-source.json) rather than trusting that a passing install means a working one.Verifyworkflow running artifact-drift and conformance checks on every pull request, not only on release, plus live JSON Schema validation against the published schemas.sync-skillsworkflow re-syncingskills/from upstream weekly and opening a pull request, so staleness is visible instead of silent..skills-source.jsonrecording upstream provenance, the declared skill set, and any local transforms.
Changed
plugin.jsonis now the version source of truth, replacing.claude-plugin/plugin.json. Every provider manifest is generated from it.- Three scripts collapse into one.
scripts/build.mjs(with--check) replacessync-manifests.mjs,bundle-codex-plugin.mjs, andbuild-skills-for-npm.mjs. - The
skills-srcsubmodule is gone. Skills are vendored; upstream remains the content owner via the sync workflow. npm packno longer mutates the working tree. Theprepack/postpack+git checkout skills/dance is removed.- Codex
interfacemetadata moved intoextensions["com.openai"], which is what the spec's extension namespaces are for. skills/best-practicesrenamed toskills/dodo-best-practicesto match its frontmattername, since the spec keys skills by directory. The user-visible skill name is unchanged. Recorded as a declared transform in.skills-source.json, and fixed at the source in dodopayments/skills#7 so the transform can eventually be dropped.- MCP servers now use native
streamable-httpinmcp.jsoninstead of wrapping remote endpoints in thenpx mcp-remotestdio bridge. Both endpoints serve Streamable HTTP directly, anddodopayments-apiadvertises standard OAuth discovery, so clients broker auth themselves. This removes annpxsubprocess and its cold start per server, per session. On Codex the shim actually hid the auth model — servers reportedAuth: Unsupportedthroughmcp-remotebut reportNot logged innatively, withcodex mcp loginavailable. The generated.mcp.jsonthat Claude Code and Cursor read still uses themcp-remotebridge, derived from the same URLs so the two cannot drift. The OpenCode plugin also keeps the bridge — its config shape is OpenCode's own, so it is hand-written rather than generated — but now points at the same canonical endpoints, andscripts/conformance.mjsfails the build if that ever stops being true.
Notes
plugins/dodopayments/ and .codex-plugin/ are retained, deliberately.
Codex reads the root manifest natively and the generated bundle is now valid in both formats. Deleting it is verified to work — with source.path: "." and the bundle removed entirely, Codex 0.147.0 installs seventeen skills and two MCP servers. It is still the wrong move today:
- Root
plugin.jsonsupport (openai/codex#35105) first shipped stable in 0.146.0 on 2026-07-29, one release cycle before this changelog entry. - A self-referencing marketplace
source.pathwas never accepted before 0.142.0 (openai/codex#28771); both"."and"./"were rejected outright before it. - Codex auto-updates only managed installs. Standard
npm/brewinstalls require an explicit upgrade, and upstream documents no minimum-supported-version policy.
So the bundle is what keeps the plugin working for anyone who has not updated in the last couple of weeks. It stays until 0.146+ adoption is safe to assume, and even then the source.path change and the directory deletion must land in separate releases, because users who ran codex plugin marketplace add hold a cached manifest and need codex plugin marketplace upgrade.
0.4.0 - 2026-08-01
Added
- Nine new agent skills, bringing the bundle from eight to seventeen:
framework-adapters,product-catalog-management,customer-management,refunds-and-disputes,discounts-and-promotions,localized-pricing,mobile-checkout,testing-and-go-live,better-auth-integration. Symlinked inskills/and materialized intoplugins/dodopayments/skills/by the existing bundler.
Changed
skills-srcsubmodule bumped to pick up dodopayments/skills#6, which rewrote all eight existing skills against the current API and added the nine above.- README now lists all seventeen skills grouped by task, and the version badge (stale at
0.2.0) tracks the canonical manifest version again. - Codex marketplace listing (
.codex-plugin/plugin.jsonlongDescription) and the npm package README (opencode-plugin/README.md) no longer advertise "eight skills"; both now describe the seventeen shipped.
Fixed
Carried in from the skills submodule — these were shipping broken guidance to agents:
api.dodopayments.comhas no DNS record. The base URL inbest-practiceswas unreachable; corrected tolive.dodopayments.com/test.dodopayments.com.- Webhook signature verification could never succeed. Hand-rolled HMAC in four languages signed
timestamp.payload, omittingwebhook-id. Dodo follows the Standard Webhooks spec (webhook-id.webhook-timestamp.body). Replaced withclient.webhooks.unwrap()/ thestandardwebhookslibrary. - Wrong SDK surface:
customers.createPortalSession()does not exist, deprecatedpayments.create()was taught for new integrations,sk_test_/sk_live_key prefixes are Stripe's format (Dodo issuesdodo_test_/dodo_live_), and a nonexistent "publishable key" invited leaking a secret key client-side. - Unsafe payment logic:
dispute.acceptedwas treated as a win that restored customer access (it means the merchant conceded), and subscription cancellation revoked every license key a customer owned, including keys for unrelated products. - Access control that silently no-opped:
licenseKeys.update()was sent a nonexistentstatusfield instead ofdisabled, and subscription webhook handlers readdata.customer_idwhere the payload nests the customer — passingundefinedto every grant and revoke call. - Framework adapter examples:
@dodopayments/expressexportscheckoutHandler, notCheckout;@dodopayments/fastifyreturns{ getHandler, postHandler }rather than a callable;@dodopayments/nuxtauto-imports its handlers and exports only the Nuxt module from its root.environmentwas passed unnarrowed in every adapter, which does not type-check against the SDK's literal union. - Non-TypeScript examples: the Go webhook handler called a nonexistent
option.WithEnvironmentand used the wrongUnwrapsignature; the Python client was constructed with an unnarrowed env var that raisesValueErrorat startup; the Go quick-start calledos.Getenvwithout importingos. - CLI documentation:
dodo wh listenwas described as a tunnel that prints a public URL (it is an outbound relay that prints none), anddodo wh triggerpayloads were not documented as unsigned — contradicting the adjacent instruction to always verify signatures.
Enforcement
The submodule now carries CI that compiles every published example against the real SDKs, so the corrections above cannot silently regress: 217 TypeScript blocks (including the @dodopayments/* adapters), Go via go build against dodopayments-go, and Python via pyright. Structural rules cover hostnames, key prefixes, hand-rolled webhook HMAC, and manifest/README/frontmatter agreement.
0.3.3 - 2026-05-08
Added
-
Per-MCP enable/disable toggles for OpenCode. The npm plugin now reads two environment variables before registering each MCP:
DODO_DISABLE_API_MCP=1skips registeringdodopayments-api.DODO_DISABLE_KNOWLEDGE_MCP=1skips registeringdodo-knowledge.
Truthy values:
1,true,yes,on(case-insensitive). Both unset = both registered (prior default behavior preserved). Env vars chosen over anopencode.jsonconfig block because OpenCode's top-level config schema is strict and rejects unknown keys (anomalyco/opencode#9161). -
Explicit
"enabled": trueon every MCP entry in.mcp.json(Claude Code / Codex / Cursor bundle). Gives users a clear field to flip tofalsein their own override.mcp.jsonto disable an individual server. This is the supported path until per-MCP plugin toggles land upstream (anthropics/claude-code#27105, #46373, #50826). -
README sections documenting the new toggles for all four clients (Claude Code, Codex CLI, Cursor, OpenCode), plus an env-var table in
opencode-plugin/README.md.
0.3.2 - 2026-05-08
Fixed
- Codex CLI plugin still didn't appear in
/pluginsafter 0.3.1. (#4) The 0.3.1 marketplace pointed the plugin source atpath: "./". Codex'sresolve_local_plugin_source_pathrejects this — after stripping the./prefix, the remainder is empty and the plugin is silently dropped (warn-logged, then skipped). The plugin must live in a non-empty subdirectory. - Plugin manifest paths missing the required
./prefix. Codex'sresolve_manifest_pathsilently dropsskillsandmcpServerspaths that don't start with./. The repo's.codex-plugin/plugin.jsonhad"skills": "skills/"and"mcpServers": ".mcp.json", both ignored by Codex. skills/symlinks were dangling in Codex's clone.codex plugin marketplace adddoes a plaingit clone(no--recurse-submodules), so the existingskills/symlinks pointing into the emptyskills-src/submodule resolved to nothing. Even with the marketplace fixed, no skills would have loaded.
Added
plugins/dodopayments/— self-contained Codex plugin bundle with real (non-symlink, non-submodule) files. Contains.codex-plugin/plugin.jsonwith proper./paths,.mcp.json, and all eightSKILL.mdfiles copied fromskills-src/. This subdirectory is what.agents/plugins/marketplace.jsonnow points at, and it's what Codex actually loads.scripts/bundle-codex-plugin.mjs— generatesplugins/dodopayments/from canonical sources (.codex-plugin/plugin.json,.mcp.json,skills-src/dodo-payments/). Supports--checkfor CI drift detection. Wired intoscripts/sync-manifests.mjsso version bumps and bundle refreshes happen together.
Changed
.agents/plugins/marketplace.json: source path moved from./to./plugins/dodopayments..codex-plugin/plugin.json(root):skillsandmcpServerspaths now use the required./prefix.scripts/sync-manifests.mjs: now runsbundle-codex-plugin.mjsafter the version sync, so the bundle stays in lockstep with the canonical manifests.
Migration
If you ran codex plugin marketplace add dodopayments/dodo-agent-plugin before this release and the plugin did not appear in /plugins, refresh the marketplace cache:
codex plugin marketplace upgrade dodopayments
If the plugin still doesn't show up after upgrading, remove and re-add the marketplace:
codex plugin marketplace remove dodopayments
codex plugin marketplace add dodopayments/dodo-agent-plugin
Then open codex, run /plugins, switch to the Dodo Payments marketplace, and install the dodopayments plugin.
0.3.1 - 2026-05-08
Fixed
- Codex CLI install was broken on two levels. (#4)
- The README told users to run
codex plugin install dodopayments@dodopayments, which is not a real Codex subcommand. Codex CLI 0.129+ only exposescodex plugin marketplace {add,upgrade,remove}; actual plugin installation happens via the/pluginsslash command inside the Codex TUI. - After
codex plugin marketplace addsucceeded, the plugin still did not appear in/plugins. The repo only shipped a Claude-Code-style manifest at.claude-plugin/marketplace.json. Codex prefers.agents/plugins/marketplace.jsonwith its own schema (object-formsource, requiredpolicyandcategoryfields). The Claude-Code-shaped manifest was not a valid alternate layout for our split (.codex-plugin/plugin.jsonlives in a separate directory from.claude-plugin/).
- The README told users to run
Added
.agents/plugins/marketplace.json— canonical Codex marketplace manifest pointing thedodopaymentsplugin at the repo root, where.codex-plugin/plugin.jsonalready lives. Schema follows the official Codex spec withpolicy.installation: AVAILABLE,policy.authentication: ON_INSTALL, andcategory: Developer Tools.
Changed
- README Codex section rewritten to reflect the actual two-step install flow (
codex plugin marketplace addfrom the shell, then/pluginsfrom inside the TUI). Includes acodex plugin marketplace upgrade dodopaymentshint for users who registered the marketplace before this fix.
Migration
If you ran codex plugin marketplace add dodopayments/dodo-agent-plugin before this release and the plugin did not appear in /plugins, refresh the marketplace cache:
codex plugin marketplace upgrade dodopayments
Then open codex, run /plugins, switch to the Dodo Payments marketplace, and install the dodopayments plugin.
0.3.0 - 2026-04-23
Changed
-
OpenCode: MCP servers now register automatically.
@dodopayments/opencode-pluginno longer requires users to paste anmcp: { ... }block into theiropencode.json. The plugin now implements OpenCode'sconfigplugin hook and injectsdodopayments-apianddodo-knowledgeinto the runtime config on load. Install reduces to:{ "plugin": ["@dodopayments/opencode-plugin"] }This brings OpenCode to parity with the Claude Code, Codex, and Cursor installs, all of which already auto-register MCPs.
-
User-declared MCPs win. Registration uses nullish-assign (
??=), so if a user declares their own entry fordodopayments-apiordodo-knowledgeinopencode.json, their entry is preserved. This is the documented way to swap the default remote OAuth server for the local stdiododopayments-mcpwith a self-provided API key.
Removed
- Root
opencode.jsonhas been removed from the repository and from the npmfiles[]array. It previously shipped as a reference snippet; the plugin'sconfighook supersedes it. Install instructions live inREADME.md. translateMcpToOpencodetranslation inscripts/sync-manifests.mjs. The script no longer reads.mcp.jsonor writesopencode.json- it now only propagates the canonical version across the four plugin manifests and the npmpackage.json.
Migration
If you were using a prior version with the manual mcp: { ... } block in your opencode.json, you can remove that block. No other changes required. If you were using a customized mcp.dodopayments-api entry (e.g. pointing at the local stdio server), keep it - your entry takes precedence.
0.2.0 - 2026-04-23
Renamed
- Repository renamed from
dodo-claude-plugintododo-agent-pluginto reflect that this plugin now serves four AI coding agents (Claude Code, Codex, Cursor, OpenCode), not just Claude Code. - GitHub's automatic redirect keeps the old URL working, but the new URL is canonical.
- If you installed via
claude plugins marketplace add dodopayments/dodo-claude-plugin, re-add with the new URL when convenient:claude plugins marketplace add dodopayments/dodo-agent-plugin. Existing installations keep working via the redirect; no urgent action required.
Added
- Codex CLI support via new
.codex-plugin/plugin.jsonmanifest. Install withcodex plugin marketplace add dodopayments/dodo-agent-plugin. Codex also natively reads the existing.claude-plugin/marketplace.json, so this repo serves both editors from one marketplace file. - Cursor support via new
.cursor-plugin/plugin.jsonmanifest. Cursor auto-discovers the bundled skills from.claude/skills/(Claude Code compatibility) and reads.mcp.jsonas-is. - OpenCode support via new npm package
@dodopayments/opencode-plugin. Install by adding toopencode.json- see README for the config snippet. opencode.jsonreference config - users paste it into their own config.opencode-plugin/- OpenCode plugin entry point (index.jsregisters no runtime hooks; the package's value is the bundledskills/and documented MCP server snippets).scripts/sync-manifests.mjs- single command that keeps version numbers in sync across all four manifests and regenerates the OpenCode MCP block from the shared.mcp.json. Run with--checkin CI.scripts/build-skills-for-npm.mjs- materializes theskills/symlinks into real directories fornpm pack(viaprepack), then restores the symlinks afterward (viapostpack). Required because npm does not follow symlinks in the tarball..github/workflows/publish-opencode.yml- publishes@dodopayments/opencode-pluginto npm with provenance on every GitHub Release. Supports manualworkflow_dispatchwith dry-run mode for testing.For maintainerssection in the README covering npm scope ownership,NPM_TOKENsetup, and the release workflow.
Changed
- All four plugin manifests bumped to
0.2.0(.claude-plugin/plugin.json,.claude-plugin/marketplace.json,.cursor-plugin/plugin.json,.codex-plugin/plugin.json) plus the newpackage.json. repositoryURL updated tododopayments/dodo-agent-pluginin all manifests.- README rewritten: retitled to "Dodo Payments Agent Plugin", added install sections for Codex/Cursor/OpenCode, added a prominent rename callout pointing here.
Unchanged
- The plugin's internal name stays
dodopayments(so install commands still use@dodopayments). - The eight bundled skills are untouched (skills-src submodule is unchanged).
- The two MCP servers and their configurations are untouched.
- The Claude Code install flow works identically to 0.1.0, aside from the new repo name in the URL.
0.1.0 - 2026-04-21
Initial release.
- Eight Dodo Payments agent skills bundled via the
dodopayments/skillssubmodule:best-practices,checkout-integration,subscription-integration,webhook-integration,usage-based-billing,credit-based-billing,license-keys,billing-sdk. dodopayments-apiMCP server (remote SSE viamcp-remote) pre-registered for live API access.dodo-knowledgeMCP server (remote HTTP viamcp-remote) pre-registered for on-demand docs lookup.- Optional
userConfigfor users who switch the API MCP to local stdio (dodopayments-mcp).