Skip to content
Distribution

How to fix a rejected Claude connector or ChatGPT plugin

Troubleshoot rejected MCP connectors and plugins for Claude and ChatGPT. Fix connection, policy, tool, and annotation issues, then resubmit.

Cosette CresslerKaustubh Shukla

October 23, 202614 min read

Both directories revise their review criteria often. Check the linked docs before you resubmit.

This guide covers eight common rejection categories for Claude connectors and ChatGPT plugins. Seven apply to both directories; the test-case section is specific to ChatGPT. Match your review feedback to a section in the table below, apply the fix, and follow the resubmission steps for your directory.

Picture the invoicing agent from How to build an agent for your product and serve it everywhere. You shipped it as an MCP server, submitted it to both directories, and a week later the verdict arrived: rejected. The email, or the dashboard entry, names the check that failed. It doesn't tell you what to change. This page does. Find the section that matches the wording in your feedback and work through it; each section stands on its own and says which directory it covers. If you haven't submitted yet, the Claude connector guide and the ChatGPT plugin guide cover how to pass the first time.

How rejection and resubmission work

Both directories deliver feedback by check name, and both accept a resubmission of the same listing once you fix the problem.

Claude (Anthropic) scans every submission automatically and lists it as a community connector by default. Listings Anthropic expects to be widely used go to verified review, where a reviewer runs every tool by hand. Feedback lands in the submissions dashboard. Fix the problem on your server and resubmit the same listing. Anthropic publishes no review timeline; escalations go to mcp-review@anthropic.com.

ChatGPT (OpenAI) sends review feedback by email and shows status in the plugin portal. For a rejected package, address the feedback and upload a corrected ZIP to the existing plugin. After publication, hosted MCP tool changes are handled through scans; listing metadata, assets, and skills still require a new ZIP. To appeal a rejection, reply to the email. See the submission guide.

Planning for another review. Neither directory provides a fixed resubmission turnaround or a guaranteed priority path. Address all known issues together and leave time for another review; your first submission's wait is not a reliable estimate.

Find your rejection reason

The feedback saysGo to
"Couldn't reach the MCP server," "Authorization failed," "Cannot connect," test account doesn't workReviewers couldn't connect or authenticate
Privacy policy, terms, documentation, or support URL missing or incompleteA policy page is missing or incomplete
Description doesn't match behavior, prompt injection, promotional language, steers the modelA tool description is unclear or flagged
Catch-all tool, read and write in one tool, requests conversation history, overly broad dataA tool's scope is too broad
Missing title, missing or mismatched readOnlyHint / destructiveHint / openWorldHintAnnotations are missing or wrong
Timeouts, generic errors, oversized responses, too many registered clientsThe server is too slow, too noisy, or rate-limited
Test cases failed (ChatGPT only)Test cases fail
Category not acceptedThe connector does something the directory doesn't allow

Reviewers couldn't connect or authenticate

Applies to: Claude and ChatGPT.

What it means. The reviewer added your server the way a user would and never reached a working tool. This is the most common rejection on both directories, and the MCP server itself is rarely the cause. DNS, a firewall, OAuth discovery, and the demo account account for most of it.

Say the invoicing agent's rejection reads "Couldn't reach the MCP server." It runs fine in Claude Code and the MCP Inspector, which is the clue: those connect from your machine, and the reviewer connects from the directory's cloud.

The fix. Work through these from a machine outside your own network and stop at the first one that fails. Anthropic's troubleshooting page covers the same checks in more depth.

  1. Confirm the hostname resolves to a public address. Run dig +short your-server.example.com from outside your network. Every returned address must be globally routable. Private ranges, carrier-grade NAT, and split-horizon DNS can prevent access. Claude's hosted connectors require a public IPv4 A record: an IPv6-only hostname with only AAAA records cannot be reached. See Anthropic's troubleshooting guide.
  2. Confirm the server URL doesn't redirect. Run curl -sI https://your-server.example.com/mcp. A 3xx to a different host (apex to www, region routing) drops the Authorization header and surfaces as an auth failure. Register the URL the server listens on.
  3. Confirm nothing in front of the server blocks the directory's traffic. Look for 403 or 429 in your CDN or WAF logs during the connect attempt. Allowlist Anthropic's published IP range (160.79.104.0/21) and exempt your MCP and OAuth paths from bot rules. Discovery requests to your authorization server come from the same range, so a WAF in front of your identity provider breaks the flow too.
  4. Confirm the 401 advertises your metadata. An unauthenticated request must return 401 with WWW-Authenticate: Bearer resource_metadata="https://.../.well-known/oauth-protected-resource". Claude ignores that header on a 200. The resource field in the document must match your server URL exactly as users type it, path included.
  5. Confirm discovery documents resolve. From a public network, curl -i your protected resource metadata and one of /.well-known/oauth-authorization-server or /.well-known/openid-configuration. Hosted identity providers usually serve only the second. The document must list S256 in code_challenge_methods_supported; both directories refuse authorization servers that omit it.
  6. Confirm the client can register. Your authorization server metadata needs one of: "client_id_metadata_document_supported": true plus "none" in token_endpoint_auth_methods_supported (CIMD), a registration_endpoint (DCR), or a pre-registered client. Both directories prefer CIMD. With none of the three, Anthropic can hold a client ID and secret for you (email mcp-review@anthropic.com), and OpenAI lets you paste one into the portal.
  7. Confirm the redirect URI is on your allowlist. Claude: https://claude.ai/api/mcp/auth_callback, plus http://localhost/callback and http://127.0.0.1/callback with any port for Claude Code. ChatGPT: https://chatgpt.com/connector_platform_oauth_redirect when your server supports issuer identification, otherwise the per-connection https://chatgpt.com/connector/oauth/{callback_id} shown on your plugin's management page (see OpenAI's authentication guide).
  8. Confirm the token endpoint is fast and accepts form-urlencoded. Claude waits 10 seconds for discovery, registration, and token responses. A 415 means your framework only parses JSON; register a form body parser. DCR's /register takes JSON, so don't assume one parser covers both. Refresh failures must return invalid_grant, not a custom code.
  9. Confirm the demo account signs in with no second factor. Use the exact credentials you submitted, from outside your network, with MFA off. Both directories reject accounts that need SMS, email confirmation, or VPN access, and both want realistic data in the account.

On AgentOS with AuthKit, AuthKitProvider connects the MCP resource server to your AuthKit tenant; it does not configure the tenant for you. In the AuthKit setup, enable DCR, register the public MCP resource indicator, and issue the AgentOS resource scopes the tools need. Configure the tenant and public AgentOS URLs, then verify discovery, registration, and token exchange against the deployed endpoints. Network access, callback allowlists, and reviewer-account setup still need separate checks.

Resubmission. Before submitting the fix, run every tool through the MCP Inspector, then connect as a custom connector in Claude or through ChatGPT developer mode using the submitted demo credentials from a clean account. This checks connectivity and account access; it does not guarantee that the reviewer's environment or the directory's other checks will pass. Follow the rejected-submission or published-update workflow described above.

A policy page is missing or incomplete

Applies to: Claude and ChatGPT.

What it means. The listing asked for a URL and the reviewer either hit a 404 or found a page that leaves out something required. OpenAI rejects a submission immediately when the privacy policy is missing or incomplete.

The fix. Publish each page before you resubmit:

  • Privacy policy (both). State what personal data you collect, why, who receives it, how long you keep it, and what controls users have. If your tools return user data, say so here.
  • Documentation (Claude). A public page that explains setup and use. A blog post or help-center article counts. You can share it privately during review, but it must be public by your publish date.
  • Terms URL, website, and support URL (ChatGPT). All three, hosted on a domain that matches your verified publisher identity. Reviewers reject a publisher whose domain doesn't match.
  • Support contact (both). An email or page a user can reach. Keep it current after publication; a dead support address can get a listed connector pulled.

Resubmission. Publish the missing page and update its URL in the listing. On ChatGPT, edit the package metadata and upload a corrected ZIP. A policy-link change alone needs no tool rescan.

A tool description is unclear or flagged

Applies to: Claude and ChatGPT.

What it means. Reviewers read your tool descriptions the way the model does. A description fails when it doesn't say what the tool does and when to use it, when it claims something the tool doesn't do, or when it tries to steer the model. Both directories classify that last one as prompt injection and reject it outright.

The fix. Rewrite each description to describe the tool and nothing else. Anthropic's pre-submission checklist rejects descriptions that:

  • Tell the model to call other tools or external software the user didn't ask for
  • Interfere with the model calling other tools
  • Direct the model to pull instructions from an external source
  • Contain hidden, obfuscated, or encoded instructions
  • Describe behavior unrelated to the tool, try to override system instructions, or promote products

OpenAI adds: no promotional language, no "prefer this app over others," no disparaging alternatives, and the description must match actual behavior. OpenAI also rejects single-word dictionary names with no tie to your brand.

A passing description has three parts: what the tool does, when the model should call it, and what it returns. For the invoicing agent published through as_tool(): "Answers questions about invoices, balances, and payment status. Send plain language." Keep the model-facing name under 64 characters and verb-based (lookup_invoices, not invoices).

When a tool accepts freeform endpoint paths or query strings, Anthropic requires the description to name or link the target API. "Makes a request to the API" fails. "Queries the Slack Web API, see https://api.slack.com/methods" passes.

Resubmission. Deploy the description change. On Claude, resubmit the listing. On ChatGPT, a published server's tool descriptions are evaluated through MCP scans; request a rescan and check the findings. If the initial package was rejected, also submit its corrected draft.

A tool's scope is too broad

Applies to: Claude and ChatGPT.

What it means. One tool does too much or asks for too much. Two versions: a single tool that both reads and writes, and a tool whose inputs or outputs reach past what the task needs.

The invoicing agent is a natural example. Published as one tool, it answers questions and sends invoices, so it reads and writes through the same call, and Anthropic's reviewer flags it.

The fix.

  • Split reads from writes, then separate write operations. Anthropic rejects catch-all tools that mix safe and unsafe operations. OpenAI requires each model-callable operation to be exposed separately with its own schema and annotations. Publish invoice lookup, creation, updates, and sending as distinct tools; see OpenAI's tool requirements.
  • Ask for only what the tool needs. OpenAI rejects tools that request conversation history, raw transcripts, precise location, or contextual data they don't use. Anthropic rejects tools that collect conversation data beyond their function or that query Claude's memory, chat history, or user files.
  • Return only what the user needs. Strip trace IDs, session IDs, timestamps, and internal identifiers from responses unless the tool can't work without them. OpenAI names "undisclosed user data returned" as a rejection reason. Anthropic's version: don't return a database dump when the user asked for a summary.
  • Call your own APIs. Both directories reject connectors that act as unofficial pass-throughs to a third party's API or scrape sites without permission. The MCP server's domain should match the service it fronts.

Expose invoice lookup, creation, updates, and sending as separate operations. With AgentOS, MCPConfig.tools can publish existing Python functions through Function, giving each operation its own input schema and annotations.

The configuration below assumes lookup_invoices, create_invoice, update_invoice, and send_invoice are already implemented with narrowly typed parameters and account authorization. Lookup makes no changes; creation adds an unsent draft; updating changes an existing draft; sending uses only the recipient stored on that invoice.

from agno.os import MCPConfig
from agno.tools.function import Function
 
read_hints = {
    "readOnlyHint": True,
    "destructiveHint": False,
    "openWorldHint": False,
}
create_hints = {
    "readOnlyHint": False,
    "destructiveHint": False,
    "openWorldHint": False,
}
write_hints = {
    "readOnlyHint": False,
    "destructiveHint": True,
    "openWorldHint": False,
}
 
mcp = MCPConfig(
    tools=[
        Function(
            name="lookup_invoices",
            title="Look up invoices",
            description="Retrieves invoices, balances, and payment status from the signed-in account.",
            entrypoint=lookup_invoices,
            annotations=read_hints,
        ),
        Function(
            name="create_invoice",
            title="Create an invoice draft",
            description="Creates an unsent invoice draft in the signed-in account.",
            entrypoint=create_invoice,
            annotations=create_hints,
        ),
        Function(
            name="update_invoice",
            title="Update an invoice draft",
            description="Updates an existing unsent invoice draft in the signed-in account.",
            entrypoint=update_invoice,
            annotations=write_hints,
        ),
        Function(
            name="send_invoice",
            title="Send an invoice",
            description="Sends an invoice to its stored recipient. This sends an external message.",
            entrypoint=send_invoice,
            annotations=write_hints,
        ),
    ],
    default_tools=False,
)

This example follows ChatGPT's annotation guidance for an additive draft creation. For a Claude directory submission, set create_hints["destructiveHint"] = True before building the MCP configuration: Claude's checklist requires that hint for tools that modify data. openWorldHint: False assumes every operation is restricted to the account's invoices and stored recipients; arbitrary recipient addresses require a different scope and hint.

Keep authorization and required confirmation in the operation's execution path. If you expose agents through as_tool() instead, each agent must have only the capabilities its operation needs; renaming a general invoice agent does not constrain what it can do. Return only task-relevant data.

Resubmission. Deploy the separate tools. Resubmit on Claude. For a published ChatGPT plugin, rescan the hosted MCP server; eligible tool changes do not require a new package version. For a rejected initial submission, correct and resubmit the package as well.

Annotations are missing or wrong

Applies to: Claude and ChatGPT.

What it means. Titles and annotations must describe the tool's actual behavior. Anthropic checks titles and the applicable hints; OpenAI requires explicit readOnlyHint, destructiveHint, and openWorldHint values. A write tool marked read-only, an incorrectly labelled irreversible action, or an omitted hint can fail review.

The fix. Set each hint from what the tool does, not from the permission prompt you'd prefer:

AnnotationSet true whenSet false when
readOnlyHintIt retrieves, computes, or previews without modifying the environmentIt changes state, persists artifacts, or starts stateful work
destructiveHint (ChatGPT)It can delete, overwrite, cancel, revoke access, or cause irreversible effectsIt is read-only or makes only additive writes without destructive or irreversible effects
destructiveHint (Claude)It modifies or deletes dataIt is read-only
openWorldHintIt interacts with public or open-ended entities, including arbitrary destinationsIt is confined to a bounded private account, workspace, or catalog, even if externally hosted

Being able to undo an action does not by itself make it non-destructive. Internet connectivity alone does not make it open-world. OpenAI no longer requires annotation justifications; see its annotation guidance. Claude uses these hints for auto-permissions: read-only tools can run without per-call confirmation, while destructive tools prompt. Its checklist requires the modifying-tool hint shown above. Hints do not replace authentication, authorization, or required user confirmation.

Since Agno 3.0.2, AgentOS publishes a title for every exposed component and asserts readOnlyHint: false, destructiveHint: true, openWorldHint: true by default, merging your overrides per key. Rejected for missing annotations on an AgentOS server? Upgrade first. Rejected for wrong ones? Override them in as_tool().

Resubmission. Deploy the corrected annotations. On Claude, resubmit the listing. For a published ChatGPT plugin, rescan the hosted tools; a rejected initial package also needs a corrected submission.

The server is too slow, too noisy, or rate-limited

Applies to: Claude and ChatGPT.

What it means. The reviewer connected, but tools timed out, returned generic errors, returned too much, or your authorization server buckled. Both directories test functional quality, and OpenAI's guidelines say plugins "should be stable, responsive, and complete."

The fix. Design around four limits:

  • OAuth endpoints: 10 seconds. Claude waits 10 seconds for discovery, registration, and token responses and 30 for refresh. Return headers and body without buffering behind upstream calls, and check that no proxy or WAF holds the response.
  • Tool calls: 240 seconds. On Claude web and Desktop, a tool call times out at 240 seconds and results cap at roughly 150,000 characters. An agent that runs a long workflow inside one call has to return earlier or return less. Split long tasks into steps the model calls in sequence.
  • Errors must say something. "Internal Server Error" and "Bad Request" with no detail fail review on both directories. Validate inputs and return an error that tells the user what to change.
  • Responses sized to the task. Don't return a full record set when the prompt asked for one item. For an agent, fix this in the instructions as much as in the code.

Rate limits and DCR pile-up. If your authorization server rate-limits registrations, DCR will hurt: Claude registers a new client on every fresh connection, and a popular listing produces very large numbers of registered clients. Switch to CIMD, which skips the registration call, or to Anthropic-held credentials. If you rate-limit tool calls per user, make sure a reviewer's test session stays under the limit; a 429 during review reads as a broken tool.

Resubmission. Deploy the performance fix. Resubmit a rejected listing on either directory. For an already published ChatGPT plugin, a server-only fix does not require a new package version.

Test cases fail

Applies to: ChatGPT only.

What it means. OpenAI requires exactly five positive and three negative test cases for initial MCP app review. For multiple MCP servers, supply the cases for each server in its MCP configuration; see the submission requirements. A case fails when the output doesn't match the expected result you wrote, when the UI errors on a supported surface, or when the negative case doesn't refuse the way you said it would.

The fix. Rerun every case yourself before you resubmit, on every surface the plugin will reach. For each positive case, confirm the prompt, the expected tool behavior, the result shape, and that the fixture data still exists in the demo account. For each negative case, confirm the plugin refuses or falls back safely and that your written reason still matches. If the agent's behavior has drifted since you wrote the cases (a model change, a prompt edit), update the cases instead of hoping the reviewer's run matches the old text.

Resubmission. Update the test cases in the plugin package and upload a corrected ZIP. If tools also changed, check the MCP scan findings before submitting the draft.

The connector does something the directory doesn't allow

Applies to: Claude and ChatGPT.

What it means. The category is excluded. Fixing the code won't get it listed.

Claude excludes connectors that transfer money, cryptocurrency, or other financial assets, and connectors that generate images, video, or audio with AI models. Design tools that produce diagrams, charts, or UI mockups are allowed.

ChatGPT excludes plugins that sell digital goods, subscriptions, or services; move money or crypto; serve ads; handle payment card data, health records, government IDs, or credentials; or fall into its list of prohibited goods (gambling, weapons, controlled substances, and others in the plugin guidelines). Physical goods are allowed only through external checkout on your own domain.

The fix. When the excluded behavior is one tool among many, remove that tool and resubmit. When it's the product, the directory isn't a distribution channel for it. Custom connectors in Claude and developer mode in ChatGPT still work for your own users; you can't be listed.

Resubmission timelines at a glance

ClaudeChatGPT
Published review timelineNoneNone; "varies"
Expedite requestsEmail mcp-review@anthropic.com for escalationsTurned down
Where feedback appearsSubmissions dashboardEmail and plugin portal
Appeal pathDashboard or emailReply to the rejection email
Rejected initial submissionFix the issue and resubmit the listingAddress feedback and submit a corrected package
Published listing: hosted tool changesDeploy and submit changes for reviewDeploy and rescan; eligible updates need no new package version
Published listing: package or listing changesEdit and submit the listingUpload an updated ZIP and complete review

Frequently asked questions

Claude shows reviewer feedback in the submissions dashboard in your organization settings. ChatGPT emails you the failed checks and shows status in the plugin portal. Both name the check that failed; neither names the fix.

On ChatGPT, reply to the rejection email. On Claude, respond through the dashboard or email mcp-review@anthropic.com. For a real defect, a fixed resubmission beats an appeal on both.

Neither directory publishes a guarantee about your queue position or resubmission turnaround. Do not assume that your previous wait will repeat. Fix all known issues together and leave time for another review.

The CLI and Inspector connect from your machine; the review connects from the directory’s cloud. Split-horizon DNS, a private IP, a WAF blocking the directory’s egress range, or a redirect to a different host cause most of these. Work through the connection section from a machine outside your network.

Fix every known issue and recheck the affected tools before resubmitting. A second unresolved defect can lead to another rejection. This is preparation advice; the directories do not guarantee a full or partial re-review.

No. One MCP server serves both; the directories differ in what they check, not in what they connect to. Fix the flagged issue on that server and resubmit to the directory that rejected it.