BetaFindAgent is in free public beta — every agent is free to connect and paid agents aren't available yet.
Handing an agent an API key is handing it to every host the agent can reach. Audience-bound credential slots invert that: the runtime attaches a secret only when the destination host matches a declared list.
A guardrail written into a system prompt is a request. A guardrail enforced at the gateway is a rule. Here's the full guardrail surface and a ready-made block for each class of tool.
Interactive approval works where the client can be asked — and degrades to a confirm step where it can't. The design that survives both is a read-only propose call, then a separate execute call, with the conversation in between.
Every listing goes through two stages before it's live: a static scan, then human review. Both fail closed. Anything that can't be verified as safe is rejected rather than allowed through with a note, which means the useful mental model when authoring is write for the gate, not for the happy path.
Here is the complete rejection taxonomy, what triggers each, and how to check it yourself first.
flowchart TD
S["Submission"] --> Scan["Static scan — automated"]
Scan --> R1["❌ Action host outside<br/>its credential's allowlist"]
Scan --> R2["❌ Credential slot with<br/>no allowed_hosts"]
Scan --> R3["❌ Schema validation failure"]
Scan --> R4["❌ Code bundle fails scan<br/>or sandbox acceptance"]
Scan -->|"clean"| HR["Human review"]
HR --> R5["❌ Prohibited content<br/>under marketplace policy"]
HR --> R6["❌ Listing claims the<br/>manifest doesn't support"]
HR -->|"clean"| Live["Listed"]
style Scan fill:#1f2937,color:#fff
style HR fill:#1f2937,color:#fffThe single most common automated rejection.
The scan resolves every auth_ref to its credential slot and checks that the slot's allowed_hosts
covers the host in that action's URL. Per action — not per agent.
// action
{ "url": "https://api.eu.acme.com/v2/orders", "auth_ref": "acme_key" }
// slot
{ "ref": "acme_key", "allowed_hosts": ["api.acme.com"] }api.eu.acme.com is a sibling of api.acme.com, not a subdomain of it. Rejected.
Worth noting that the scan is doing you a favour here: had it passed, the credential would never have attached at runtime and every call would have returned 401 with no obvious cause.
Check yourself: list every action URL's host, list every slot's allowed_hosts, and confirm each
action's host appears in the list of the slot it references. Ten lines of eyeballing.
allowed_hostsA credential with no declared audience can be attached to any outbound request. There is no safe default to fall back on, so the slot is rejected outright.
// rejected
{ "ref": "vendor_key", "label": "Vendor API key", "type": "secret" }Check yourself: every object in credential_slots has an allowed_hosts array, and every array
is as narrow as the agent allows — exact hosts, not parent domains.
The unglamorous bucket, and the easiest to eliminate. What actually shows up:
| Failure | Detail |
|---|---|
| Missing required fields | name, system_prompt, example_prompts |
| Length violations | name outside 3–80; system_prompt outside 50–20,000 |
| Malformed tools | Missing description, malformed input_schema, more than 40 tools |
| Undefined placeholders | A {param} in a URL with no matching property in input_schema |
secret_leak_scan written |
Mandatory and always on — writing it, usually as false, fails |
| Inconsistent shape | code-bundle with mcp.stdio; local doer with chatgpt in targets |
| Dangling or orphaned refs | An auth_ref resolving to nothing, or a slot no action uses |
Invalid llms values |
Only claude, chatgpt, gemini, cursor, vscode, custom — others are dropped silently |
One kind won't fail here but also won't do what you expect: autonomous-agent is a reserved roadmap
value with no distinct runtime behaviour, so a submission that sets it is silently coerced to
mcp-tool rather than rejected. It isn't offered as a choice anywhere, and you shouldn't author
it — treat your doer as mcp-tool.
Check yourself: the pre-delivery checklist in the manifest cookbook covers every row of this table.
Code bundles carry a second surface: the code itself is scanned, and the sandbox has to be able to accept the bundle.
What tends to surface here:
Check yourself: scan your own repo for secrets, grep for every hostname the code contains, and confirm each one is in the README's network section. See repo to code agent.
Human review, and not negotiable. Read the marketplace policy before building rather than after — this is the only rejection category where the fix might be "don't build this."
This is the category creators are least prepared for, because everything validates and the agent genuinely works. Review is also checking whether the description matches the artifact.
What gets sent back:
readOnlyHint: true on a tool that writes is the
classic, and it has teeth: clients use that annotation to decide what to run without asking.targets listing clients the agent can't work in. Especially chatgpt on a local doer, which
is not a supported configuration.example_prompts that don't exercise the agent. One generic line, or prompts referencing
tools that don't exist. The requirement is 1–5 prompts showing genuine use, and reviewers do read
them.system_prompt that claims capabilities the tools don't have. Instructing the model to
"check the customer's payment history" when no such tool exists produces confident fabrication.Check yourself: read the listing copy and the manifest side by side, and for each claim ask which tool delivers it. Any claim without a tool behind it is a rejection.
Work top to bottom. Each line maps to a rejection above.
Credentials
allowed_hostsauth_ref resolves to a slot covering that action's host — checked per actionurl, headers, body_template, env, description or any listing fieldSchema
name 3–80; system_prompt 50–20,000; ≤40 tools; 1–5 example_prompts{param} defined in input_schemahttpssecret_leak_scan not written at allkind: mcp-tool (never autonomous-agent, which is coerced away)kind / delivery / exec / targets mutually consistentllms values from the allowed sixBehaviour
annotations match what each tool does — nothing that writes is read-onlyapproval: "human" on irreversible or spending toolsidempotent: false on anything with side effectsrate_limit on every external callListing
targets limited to clients actually supportedexample_prompts show real usageCode bundles
.env.example complete and commentedThe rejection tells you which check failed. Fix that specific thing and resubmit — it's cheap, and one round trip is entirely normal for a first listing with credentials in it.
What's expensive is resubmitting repeatedly without reading the reason, usually because the failure looks arbitrary. It generally isn't: the host-coverage check in particular is catching a bug that would otherwise have surfaced as an unexplained 401 in front of a paying buyer.
One thing to settle before you submit at all: the slug you choose at the Basics step is permanent. Everything else is editable across versions. Pick it deliberately.
What is the most common reason an agent listing is rejected?
An action whose destination host isn't covered by the allowed_hosts of the credential slot its
auth_ref points to. The check runs per action, so a slot that covers one tool's host but not
another's fails.
Does a human review every agent? Yes. The static scan runs first and rejects automatically, then a human reviews what passes. Both stages fail closed, so anything that can't be verified as safe is rejected rather than approved with a caveat.
Can I disable a check for my own agent?
No. secret_leak_scan is mandatory and always runs, allowed_hosts is required on every credential
slot, and guardrails may only ever be tightened, never loosened.
Why was my agent rejected when the manifest validates?
Human review also checks that the listing's claims match the manifest — tool descriptions broader
than their actions, annotations that don't match behaviour, targets including unsupported clients,
or a tagline promising an outcome the tools can't produce.
How long does a resubmission take? Fix the specific check named in the rejection and resubmit. One round trip is normal for a first listing that involves credentials; the check that failed is usually catching a bug that would have surfaced later as a runtime error.
Can I change my agent's slug after submitting? No. The slug chosen at the Basics step is permanent. Other listing fields can be edited across versions.
Related: The MCP Agent Manifest Cookbook · Audience-bound credentials · From GitHub repo to hosted code agent