Repository navigation
Frame provider tools around creating accounts; unlisted providers by ID; show the sign-up cap - #66
Conversation
agentmail-api#1408 made GET /providers/{id} and POST
/providers/{id}/connect follow the provider's registration instead of
the catalog, so a registered provider the catalog does not list still
works when the caller has its ID. get_provider still said an unlisted
provider resolves "only when your organization holds an account at it",
which steers an agent away from a provider ID the user hands it.
- get_provider: any registered provider resolves; a missing updatedAt
means not a reviewed catalog entry; 404 means no such provider.
- connect_provider: works for any registered provider.
- list_providers / search_providers: catalog only, and point at the
by-ID path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n-up cap People reach these tools asking "create an account at Firecrawl" or "get my agent a web search API", not "connect a provider". Say so in the descriptions: connect_provider creates an account (or signs an existing one back in), search matches names only so a need goes through list_providers descriptions, and list_accounts is the check before connecting. ProviderSchema now keeps ownerSignupLimit (published by the API since agentmail-api#1315). connect_provider refuses a new sign-up past that cap; seeing it up front lets the agent pick an inbox that already holds an account instead of minting a URL that fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
shalim786
left a comment
There was a problem hiding this comment.
Checked against the deployed prod get-provider / connect-provider bundles (2026-09-28). The by-ID behaviour matches #1408, and the ownerSignupLimit semantics are right (per org; 0 pauses new sign-ups; an existing account always signs in). Two wording notes inline.
Merge/deploy order. The hosted connector runs agentmail-toolkit 0.9.0 (npm latest; 0.9.1 is unpublished). Live get_provider still says an unlisted provider 404s unless the org holds an account, and 0.9.0 strips ownerSignupLimit. Suggested order: toolkit#66 → publish 0.9.1 → bump the pin + regenerate mcp-manifest.json → deploy the connector → then skills#17, plugins#15, docs#279.
| logoUrl: z.string().optional(), | ||
| termsUrl: z.string().optional(), | ||
| privacyUrl: z.string().optional(), | ||
| ownerSignupLimit: z |
There was a problem hiding this comment.
Worth adding what the cap counts, so agents don't try to compute headroom from list_accounts. The deployed counter (organization_signup_count#<provider>#<org>) increments on every first-time sign-up and I found no decrement, so disabled accounts still count. list_accounts doesn't publish disabled rows, so counting its items undercounts. The directory value is also a snapshot as of updated_at, while /token reads it live. Maybe: "…Counts every inbox that has ever signed up, including disabled accounts; treat it as a hint and rely on connect's limit error."
There was a problem hiding this comment.
Added in 38a4c40, on both the ownerSignupLimit field and the get_provider description. It says the cap counts every inbox that has ever signed up, including disabled accounts list_accounts does not show, and that it can lag the live value, so treat it as a hint and rely on connect_provider's limit error.
| title: 'Connect Provider', | ||
| description: | ||
| "Start signing an inbox in to a provider: mints a browser sign-in session and returns a single-use magic URL to open in the client that will hold the sign-in (usually the agent's own browser session), plus the ID of the pending sign-in key. The URL expires, is never re-issued, and nothing is connected until the sign-in completes — do not call again for the same provider and inbox while a previous URL is still live (live sessions are limited per caller). Confirm completion with list_accounts for that providerId. Requires the provider_connect permission. inboxId is required unless the credential is scoped to one inbox.", | ||
| "Create an account at a provider as an inbox, or sign an inbox that already holds one back in: mints a browser sign-in session and returns a single-use magic URL to open in the client that will hold the sign-in (usually the agent's own browser session), plus the ID of the pending sign-in key. The URL expires, is never re-issued, and nothing is connected until the sign-in completes — do not call again for the same provider and inbox while a previous URL is still live (live sessions are limited per caller). Confirm completion with list_accounts for that providerId. Works for any registered provider, listed in the catalog or not. A provider can cap sign-ups per organization; when the cap is reached this fails with a limit error, and an inbox that already holds an account there (see list_accounts) can still sign in. Requires the provider_connect permission. inboxId is required unless the credential is scoped to one inbox.", |
There was a problem hiding this comment.
Nit: "Works for any registered provider" is slightly broad. Connect resolves via findProviderHandoffPrimary, which also requires a valid initiate_login_uri, so a provider get_provider resolves can still 404 here. The limit error could also be named: it's 403 limit_exceeded, and its fix text already says which inbox to use.
There was a problem hiding this comment.
Fixed in 38a4c40. It now says "Works by ID for a registered provider whether or not the catalog lists it, provided it has a sign-in entry point". It names the cap error as 403 limit_exceeded, whose fix says to sign in with an inbox that already holds an account. A 404 names Provider (unknown ID, or no sign-in entry point) or Inbox (not in the org or scope), and with acceptDisclosure can mean it isn't supported, so retry without.
Review against the deployed handlers: - ownerSignupLimit counts every inbox that ever signed up, including disabled accounts list_accounts hides, and can lag the live value. Describe it as a hint and point at connect's limit error. - connect_provider needs a sign-in entry point, so "any registered provider" was too broad. Name the cap error (403 limit_exceeded) and the 404 cases: Provider, Inbox, and acceptDisclosure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@shalim786 Thanks for checking against the deployed bundles. Both wording notes are addressed in 38a4c40 (replies inline). Your merge order is now in every PR description: this PR → publish 0.9.1 → mcp#62 with the pin bump and manifest regen → skills#17 → plugins#15 → docs#279. |
Summary
agentmail-to/agentmail-api#1408 (merged 2026-09-21) made
GET /providers/{id}andPOST /providers/{id}/connectfollow the provider's registration rather than the catalog. A registered provider that the catalog doesn't list now resolves (ID and name, noupdated_at) and can be connected, as long as the caller has its ID. List and search still show catalog entries only.The tool descriptions still described the old behavior.
get_providersaid an unlisted provider resolves "only when your organization holds an account at it — otherwise 404". That steers an agent away from a provider ID the user gives it. These descriptions are what the hosted connector shows to Claude, ChatGPT, and Cursor, so this is the change that makes the by-ID path visible there.get_provider: any registered provider resolves. A missingupdatedAtmeans the provider isn't a reviewed catalog entry, and a 404 means no provider is registered under that ID.connect_provider: works for any registered provider, listed or not.list_providers/search_providers: say they cover catalog entries only, and point at the by-ID path.ProviderSchemacomment to match.Framed around creating accounts. People reach these tools by asking "create an account at Firecrawl" or "my agent needs a web search API":
connect_providercreates an account, or signs an existing one back in, and names the sign-up-limit error and its fix.search_providersmatches names only, so a need goes throughlist_providersdescriptions.list_accountsis the check to run before connecting.ownerSignupLimitis now kept on provider results. The API has published it since agentmail-to/agentmail-api#1315, butProviderSchemastripped it.connect_providerrefuses a new sign-up past that cap, so seeing it up front lets the agent pick an inbox that already holds an account. A new test covers it passing through and SDK internals being stripped.Behavior is otherwise unchanged. It ships with the pending 0.9.1. After that is published, agentmail-mcp needs its
agentmail-toolkitpin moved from 0.9.0 andmcp-manifest.jsonregenerated.Related: agentmail-to/agentmail-skills#17, agentmail-to/agentmail-plugins#15
Test plan
npx tsup && npx vitest run: 465/465eslint src: cleanMerge order
agentmail-toolkit0.9.1 to npmmcp-manifest.json, then confirm the connector deployskills.py sync --backendagainst the regenerated manifestSkills, plugins, and docs wait for the connector so they don't describe
ownerSignupLimitand unlisted-by-ID behavior that the live 0.9.0 tool descriptions contradict.🤖 Generated with Claude Code