Developer tools
These tools are for people who publish Apps. You can check your App, prove that you control it, share access with your team, run private tests, ask for indexing, and get notices when something breaks.
Only the inspection call is public. All other calls need a user token or the session cookie, and the apps.publish permission. See Authentication.
Inspect an App
Anyone can inspect an App. You do not need to sign in. Inspection reads only public documents. It saves nothing and does not connect to the App.
curl -X POST https://api.example.com/v1/developer/inspect \ -H "Content-Type: application/json" \ -d '{ "input": "apps.example.com" }'input can be a domain or an HTTPS link, up to 8192 characters. The report has:
| Field | Description |
|---|---|
apps |
Each App found. eligibility is Eligible, Excluded or Unconfirmed for the public Index. stored shows the last saved index check, if any. |
issues |
Problems to fix. Each has a code, a stage, a severity (blocking or suggestion), a message, and a repair hint. |
stages |
Each check step: Input, Discovery, CardRead, CardSchema, Compatibility, PublisherAssociation and Eligibility. Each is Passed, Failed, Unconfirmed or NotChecked. |
An Eligible result does not mean the App is in the Index yet. See App Index.
Prove that you control an App
Most tools need proof that you control the App. You can prove control in two ways:
| Scope | What it covers | Where you put the token |
|---|---|---|
PublisherHostname |
Every App whose Card is on this host name and listed in a Catalog on the same host name. | A DNS TXT record |
AppCard |
One App, by its exact Card URL. | The Server Card |
Start a claim
curl -X POST https://api.example.com/v1/developer/claims \ -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "_tag": "PublisherHostname", "hostname": "apps.example.com" }'For one App, send { "_tag": "AppCard", "cardUrl": "https://apps.example.com/mcp/server-card" }. The host name must be one exact public name, with no port, path or wildcard.
The answer has an id and a token like openbot-verification=.... The claim lasts 24 hours.
Publish the token
For a host name, add a DNS TXT record at _openbot-verification.<hostname>. Use the full token as the value:
_openbot-verification.apps.example.com. TXT "openbot-verification=abc123..."For one Card, add the token to the Card:
{ "_meta": { "openbot/developer-verification": { "version": 1, "tokens": ["openbot-verification=abc123..."] } }}OpenBot reads the Card at its exact URL, with no redirects. Your robots.txt must allow the OpenBot user agent.
Verify
curl -X POST https://api.example.com/v1/developer/claims/<claim id>/verify \ -H "Authorization: Bearer $OPENBOT_TOKEN"On success you get a proof. You become the administrator for that scope. On failure you get 409 DeveloperConflict. Its reason can be ProofMismatch, ClaimExpired, VerificationUnavailable, RobotsDenied, RobotsUnconfirmed or CardUnconfirmed.
Keep the token in place. A proof is valid for 7 days, and OpenBot checks it again every day:
- If the token is gone, the proof becomes
Suspendedat once. - If the check cannot run, the proof becomes
Unconfirmed. It still works until it ends. OpenBot tries again after about one minute. - A
Suspendedproof gives no access.
To check now, call POST /v1/developer/proofs/:id/verify. To give up a proof, call POST /v1/developer/proofs/:id/relinquish. To cancel a claim, call POST /v1/developer/claims/:id/revoke.
GET /v1/developer returns your Apps, your proofs, and your access grants.
Members and roles
The administrator can invite other accounts.
| Role | What they can do |
|---|---|
administrator |
The account that made the proof. Everything, and manage members. |
maintainer |
Save reports, run tests, and ask for indexing. |
viewer |
Read Apps, reports and indexing requests. No changes. |
- Invite:
POST /v1/developer/proofs/:id/invitationswith{ "role": "maintainer" }or"viewer". The invitation lasts 7 days. - Send the invitation
idto the person. They read it withGET /v1/developer/invitations/:idand accept it withPOST /v1/developer/invitations/:id/accept. - Manage:
GET /v1/developer/proofs/:id/members,PUT /v1/developer/members/:idwith a newrole, andDELETE /v1/developer/members/:id. Members can also remove themselves.
To cancel an invitation, call POST /v1/developer/invitations/:id/revoke. When a proof ends, its members lose access too.
Reports
A report is a saved inspection. Use reports to see how your App changes over time.
| Task | Request |
|---|---|
| Save a new report | POST /v1/developer/reports with { "cardUrl" } |
| List reports for App | GET /v1/developer/reports?cardUrl=... (newest first, 50 per page, page with before) |
| Read one report | GET /v1/developer/reports/:id |
| Compare two reports | GET /v1/developer/reports/:id/compare?other=<id> |
| Delete a report you saved | DELETE /v1/developer/reports/:id |
| List reports you saved | GET /v1/developer/personal-reports |
A comparison lists the issues that are introduced, resolved and persisting.
Private connection tests
A test connects to your App from OpenBot, like a user would. It is private. It does not save a user connection, and it does not add the App to the Index. A test ends after one hour.
- Create a test with your own UUID:
POST /v1/developer/testswith{ "id", "cardUrl", "remoteIndex" }. - If the endpoint needs settings, send them:
PUT /v1/developer/tests/:id/configurationwith an object of keys and values. The keys are the same as for connections. - Run it:
POST /v1/developer/tests/:id/run. Read the result withGET /v1/developer/tests/:id.
Each run has stages: configuration, negotiation, tools, resources, resourceTemplates and prompts. Each stage is Passed, Failed, NotAdvertised or NotChecked. The test status ends as Succeeded or Failed.
Sign in during a test
When the App needs an account, the test status becomes AwaitingAuthorization.
- Start the sign-in:
POST /v1/developer/tests/:id/authorizationwith{ "scopes": [] }. Addissuerif the App has more than one provider. - Open
authorization.authorizationUrlin your browser and sign in. - The provider sends you to
/auth/developer/apps/callback. OpenBot then sends you to/?developerTest=<testId>. - Finish:
POST /v1/developer/tests/:id/authorization/complete. Then run the test again.
When you are done, call POST /v1/developer/tests/:id/cleanup. OpenBot revokes the test sign-in where the provider allows it, and deletes the stored tokens. You can also cancel a running test, or DELETE it.
Ask for indexing
You do not have to wait for a user to connect your App. Ask OpenBot to check it:
curl -X POST https://api.example.com/v1/developer/indexing \ -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "cardUrl": "https://apps.example.com/mcp/server-card" }'OpenBot inspects the App first. If it is not eligible, you get 409 with the reason. If the deployment blocks the App, you get 403 DeveloperRestricted.
The request status goes from Accepted to Waiting, Verifying and Completed. When it is done, check has the result. List requests with GET /v1/developer/indexing, or read one with GET /v1/developer/indexing/:id.
Notifications
OpenBot checks the Apps you manage about every hour. It sends you a notice when something changes.
| Kind | When |
|---|---|
IssueAppeared |
A new blocking issue appears. |
IssueResolved |
A blocking issue goes away. |
AccessChanged |
A proof changes state, or you lose member access. |
Read notices with GET /v1/developer/notifications. Use before to read older pages. Mark one as read with POST /v1/developer/notifications/:id/read.
Issue notices are on for every App. To turn them off for one App, send PUT /v1/developer/subscriptions with { "cardUrl": "...", "enabled": false }. List your settings with GET /v1/developer/subscriptions.
See the full shapes in the API reference.