From 6b3cfd5cb6147f9d38017dd2eb1845df456a7a20 Mon Sep 17 00:00:00 2001 From: Avdev4J <37835668+avdev4j@users.noreply.github.com> Date: Thu, 3 Sep 2026 12:30:46 +0200 Subject: [PATCH 1/3] Update to current Orbit API and bundle Orbit's MCP server Mirrors the change made to orbit-claudecode-plugin. The endpoint moved from fabric-gateway.postmanlabs.com/api/search to api.buildwithorbit.ai/v1/search. Rather than re-hardcode the new URL, the plugin now bundles Orbit's MCP server via .mcp.json (referenced from the manifest as "mcpServers"), so the API contract lives server-side and Orbit can change parameters without breaking installed copies. The skill now drives the search and integrate tools and keeps what is actually this plugin's value: capability decomposition, reading "Not supported" lines as design gaps, iteration, and saving the blueprint to orbit-output/. Adds the integrate step, which turns chosen endpoints into a task brief covering auth, base URLs, and request steps. Also corrects parameters that the old skill had wrong or missing: limit and cursor, q's 512-char cap, nextCursor being absent rather than null on the last page, the 40-result pagination ceiling, resourceType/provider on results, integrate's 10-resource limit, and Orbit's own query-style guidance (one intent per call, no OR-queries). New references/orbit-api.md documents the REST endpoints as a fallback for sessions where the MCP tools are unavailable. Co-Authored-By: Claude --- .codex-plugin/plugin.json | 3 +- .mcp.json | 8 + README.md | 72 ++++++-- skills/discover/SKILL.md | 54 ++++-- skills/discover/references/orbit-api.md | 230 ++++++++++++++++++++++++ 5 files changed, 336 insertions(+), 31 deletions(-) create mode 100644 .mcp.json create mode 100644 skills/discover/references/orbit-api.md diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index ae3b757..a0a7462 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,8 +1,9 @@ { "name": "orbit", - "version": "1.0.0", + "version": "1.1.0", "description": "Discover APIs from the Postman API Network using Postman Orbit, an agent-friendly search API designed for AI-powered app design.", "skills": "./skills/", + "mcpServers": "./.mcp.json", "author": "Postman DevRel", "homepage": "https://github.com/Postman-Devrel/orbit-codex-plugin", "repository": "https://github.com/Postman-Devrel/orbit-codex-plugin", diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..0ab7401 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "orbit": { + "type": "streamable-http", + "url": "https://mcp.buildwithorbit.ai/mcp" + } + } +} diff --git a/README.md b/README.md index 4273724..7311098 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,19 @@ This lets agents make informed decisions about which APIs to integrate without r codex plugin add Postman-Devrel/orbit-codex-plugin ``` +The plugin bundles Orbit's MCP server, so there is nothing else to configure -- no API +key, no `codex mcp add`, no edits to `~/.codex/config.toml`. Installing the plugin +registers the `search` and `integrate` tools, and the skill drives them. + +Requires a Codex version that supports plugin-bundled MCP servers over streamable HTTP. +If your Codex only picks up stdio servers, add the server manually instead: + +```toml +# ~/.codex/config.toml +[mcp_servers.orbit] +url = "https://mcp.buildwithorbit.ai/mcp" +``` + ## Usage Run the `discover` skill with a capability query: @@ -37,19 +50,23 @@ Search for multiple capabilities at once: ### Example output ``` -### Results for: "payment processing" +### Results for: "send transactional email" -**Stripe - Create Subscription** +**Send a transactional email** (Brevo) - Method: `POST` -- URL: `https://api.stripe.com/v1/subscriptions` -- Description: Creates a new subscription on an existing customer. -- **Evaluate Guide:** Use for: recurring billing, subscription lifecycle management, - plan upgrades/downgrades. Not supported: one-time payments (use Payment Intents), - physical goods shipping, tax calculation (use Stripe Tax). +- URL: `https://api.brevo.com/v3/smtp/email` +- **Evaluate Guide:** Sends a transactional email through Brevo's SMTP API, enabling + an agent to deliver an email payload to recipients. + Use for: send transactional messages, deliver notifications, send account emails + Not supported: inbound email processing, contact management, campaign analytics ``` Results are automatically saved to the `orbit-output/` directory as markdown files for later reference. +Once you have chosen endpoints, the skill can also produce a **task brief** -- the auth +requirements, base URLs, ordered request steps, and gotchas needed to write the +integration. + ## Design process Orbit works best when you use it at the start of a project to build an API blueprint before writing code. Here's the workflow: @@ -62,27 +79,46 @@ Orbit works best when you use it at the start of a project to build an API bluep 4. **Iterate.** Use those gaps as your next round of queries. "Find me APIs that handle payment refunds" or "I need an auth provider that supports token refresh." Each round narrows the design. -5. **Save the blueprint.** The agent saves results to `orbit-output/` as a structured file you can reference throughout the project. This becomes your API design document, readable by both humans and agents. +5. **Get the task brief.** Once the endpoint set is settled, the agent sends the selected endpoints plus your task to Orbit's `integrate` tool and gets back a brief covering auth, base URLs, and the request sequence -- the implementation plan, before you write code. + +6. **Save the blueprint.** The agent saves results to `orbit-output/` as a structured file you can reference throughout the project. This becomes your API design document, readable by both humans and agents. The goal is to make API selection decisions intentionally at design time, not discover limitations mid-sprint after you've already integrated half the stack. -## The Orbit API +## How it works -The plugin calls a single endpoint: +The plugin is a thin workflow layer over Orbit's MCP server: -``` -POST https://fabric-gateway.postmanlabs.com/api/search -Content-Type: application/json +| | Provided by | +|---|---| +| `search` / `integrate` tools, request + response schemas | Orbit's MCP server (bundled) | +| Capability decomposition, gap analysis, iteration, saved blueprint | This plugin's skill | -{"q": "your search query"} -``` +Keeping the API contract on the server side means Orbit can change its parameters +without breaking installed copies of the plugin. + +### The underlying API + +No authentication is required. The MCP tools map one-to-one onto two REST endpoints on +`https://api.buildwithorbit.ai`: + +| MCP tool | REST equivalent | +|---|---| +| `search` | `POST /v1/search` | +| `integrate` | `POST /v1/integrate` | -No authentication required. The response includes: +`search` takes `q` (max 512 chars) plus optional `limit` (default 10, max 25) and +`cursor`, and returns `data[]` entries with `id`, `resourceType`, `name`, +`description`, `method`, `url`, and `evaluateGuide`, alongside `meta` carrying `q`, +`total`, and `nextCursor`. `integrate` takes a `task` and 1-10 `resources` and returns +a `taskBrief`. -- `data[]` - Array of API endpoints with `id`, `name`, `description`, `method`, `url`, and `evaluateGuide` -- `meta` - Search metadata with `q`, `total`, and `nextCursor` +If the MCP server is ever unreachable, the skill falls back to these REST endpoints, +documented in [references/orbit-api.md](skills/discover/references/orbit-api.md). ## Links +- [Orbit documentation](https://www.buildwithorbit.ai/) +- [Orbit API reference](https://www.buildwithorbit.ai/api-reference) - [Postman API Network](https://www.postman.com/explore) - [Postman](https://www.postman.com) diff --git a/skills/discover/SKILL.md b/skills/discover/SKILL.md index 2f3f123..61c87b9 100644 --- a/skills/discover/SKILL.md +++ b/skills/discover/SKILL.md @@ -1,12 +1,14 @@ --- name: discover -description: Discover APIs from the Postman API Network using Orbit's agent-friendly search. Returns endpoints with evaluateGuide fields showing what each API can and can't do. +description: Discover APIs from the Postman API Network using Orbit's agent-friendly search. Returns endpoints with evaluateGuide fields showing what each API can and can't do, and can generate an integration task brief for the ones you pick. --- # Orbit API Discovery You are an API discovery agent. You help developers find the right APIs for their project by querying **Postman Orbit**, an agent-friendly search API built on top of the Postman API Network. +This plugin bundles Orbit's MCP server, so its tools are available with no setup and no authentication. + ## When to use Use this skill when a developer wants to: @@ -14,6 +16,7 @@ Use this skill when a developer wants to: - Compare multiple APIs that serve the same purpose - Understand what an API can and cannot do before integrating it - Discover APIs for multiple capabilities in a single session +- Get a concrete integration plan for APIs they have already chosen ## Input @@ -24,17 +27,29 @@ The user provides one or more capability queries as natural language. Examples: Parse the user's message to extract individual capability queries. If the user lists multiple capabilities, run a separate search for each one. +## Tools + +The bundled `orbit` MCP server provides two tools: + +- **`search`** — find and evaluate public API endpoints +- **`integrate`** — turn chosen endpoints into an integration task brief + +Prefer these tools. If they are unavailable in the current session, read `references/orbit-api.md` and call the equivalent REST endpoints with curl; the request and response shapes are identical. + ## How to search -For each capability query, use Bash to call the Orbit API: +Call the `search` tool once per capability query: + +- `q` — the query (required, max 512 characters) +- `limit` — results per page (optional, default 10, max 25) +- `clientName` — pass `"codex/orbit-plugin"` for anonymous usage analytics -``` -curl -s -X POST https://fabric-gateway.postmanlabs.com/api/search \ - -H "Content-Type: application/json" \ - -d '{"q": "QUERY_HERE"}' -``` +Query style materially affects result quality: -Replace `QUERY_HERE` with the capability query. Keep queries concise and descriptive. +- Include the product or provider name alongside the endpoint detail — `"PayPal create invoice"`. +- Natural language works too — `"PayPal API to create an invoice"`. +- Do **not** cram unrelated keywords into one query — `"paypal invoice payment delivery ordering"` returns worse results. +- Do **not** use `OR`-separated queries. Run a separate `search` call per intent instead. ## How to format results @@ -44,7 +59,7 @@ For each query, present results in this format: For each result in the `data` array, show: -**{name}** +**{name}** ({provider}) - Method: `{method}` - URL: `{url}` - Description: {description} @@ -57,7 +72,20 @@ The `evaluateGuide` field is the most valuable part of the response. It tells ag Always highlight the evaluateGuide content prominently. This is what differentiates Orbit from a standard API directory. -If the `meta.total` count exceeds the number of returned results, mention that more results are available. +Keep each result's `id` and `resourceType` on hand — the `integrate` tool needs them. Preserve `id` values verbatim; never parse, edit, or construct one. + +If `meta.total` exceeds the number of returned results, mention that more results are available. If `meta.nextCursor` is present, more pages exist — pass that value as `cursor` on a follow-up `search` call, but do not paginate automatically unless the user asks. Note that `nextCursor` is *absent* on the last page rather than null, and pagination stops at 40 results per query. + +## How to integrate + +When the user has a concrete task and has settled on endpoints, call the `integrate` tool: + +- `task` — what they are building (required, max 512 characters) +- `resources` — **1 to 10** entries of `{id, type}`, where `id` is a search result's `id` and `type` is that result's `resourceType` + +More than 10 resources is rejected. If the user needs more, split the work into several `integrate` calls grouped by sub-task. + +The response contains a `taskBrief` covering authentication requirements, base URLs, ordered request steps, parameters, expected responses, dependencies between steps, and other considerations. Present the brief and save it alongside the search results. ## Saving results @@ -72,6 +100,7 @@ Filename pattern: `orbit-output/{slug}.md` Examples: - Single query "payment processing" -> `orbit-output/payment-processing.md` - Multiple queries "send emails" + "geocoding" -> `orbit-output/send-emails--geocoding.md` +- A task brief -> `orbit-output/{task-slug}-brief.md` The saved file should contain: - A top-level heading with the date and queries @@ -80,7 +109,8 @@ The saved file should contain: ## Guidelines - If no results are found for a query, say so clearly and suggest rephrasing. -- Do not fabricate API results. Only show what the Orbit API returns. +- Do not fabricate API results. Only show what Orbit returns. - When the user asks for multiple capabilities, run all searches and present results grouped by capability. +- Lead your summary with the "Not supported" lines — those are the design gaps worth acting on before any code is written. - Keep your commentary brief. Let the API results speak for themselves. -- If the response includes a `nextCursor` in `meta`, mention that more results are available but do not automatically paginate. +- Both tools are read-only and safe to retry. On a rate-limit error, back off and retry. diff --git a/skills/discover/references/orbit-api.md b/skills/discover/references/orbit-api.md new file mode 100644 index 0000000..5d0006f --- /dev/null +++ b/skills/discover/references/orbit-api.md @@ -0,0 +1,230 @@ +# Orbit API Reference — REST fallback + +Docs: https://www.buildwithorbit.ai/api-reference +OpenAPI: https://www.buildwithorbit.ai/openapi.json + +> **Prefer the MCP tools.** This plugin bundles Orbit's MCP server, so the `search` +> and `integrate` tools are normally available and carry live, self-describing +> schemas. Use the REST calls below only when those tools are unavailable. See +> [MCP tools](#mcp-tools) at the end for the mapping. + +**Base URL:** `https://api.buildwithorbit.ai` + +No authentication is required. Only `Content-Type: application/json` is needed. + +There are two endpoints: `/v1/search` finds candidate endpoints, `/v1/integrate` turns +the ones you pick into a task brief. + +--- + +## POST /v1/search + +Describe your goal in `q`. Returns matching public endpoints, each with an +`evaluateGuide` explaining what it does, when to use it, and its limitations. + +### Query parameters + +| Parameter | Type | Default | Notes | +|-----------|------|---------|-------| +| `limit` | integer | 10 | Results per page. Min 1, max 25. | +| `cursor` | string | — | Pass `meta.nextCursor` from the previous response. Omit for the first page. | + +### Request body + +| Field | Type | Required | Notes | +|-------|------|----------|-------| +| `q` | string | Yes | Natural language query, keywords, an API name, or a question. 1–512 characters. | + +`q` is the only accepted body field — unknown fields return `400`. + +```json +{ "q": "Add tracking details for an existing paypal order" } +``` + +### Example curl + +```bash +curl -s -X POST 'https://api.buildwithorbit.ai/v1/search?limit=10' \ + -H 'Content-Type: application/json' \ + -d '{"q": "payment processing"}' | jq . +``` + +### Response (200) + +```json +{ + "data": [ + { + "id": "urn:orbit:endpoint:v1:...:brevo:send-a-transactional-ema", + "resourceType": "endpoint", + "name": "Send a transactional email", + "description": "string", + "method": "POST", + "url": "https://api.brevo.com/v3/smtp/email", + "evaluateGuide": "string", + "provider": "Brevo", + "product": "Brevo" + } + ], + "meta": { + "q": "send transactional email", + "total": 2, + "nextCursor": "eyJmcm9tIjoyfQ==" + } +} +``` + +| Field | Description | +|-------|-------------| +| `id` | Opaque identifier of the form `urn:orbit:endpoint:v1:...`. Pass it back verbatim to `/v1/integrate` — never parse or construct it. | +| `resourceType` | Kind of entity, e.g. `endpoint`. Pass it to `/v1/integrate` as the resource's `type`. | +| `name` | Human-readable name of the endpoint | +| `description` | What the endpoint does (may be empty) | +| `method` | HTTP method used to call the endpoint | +| `url` | URL the endpoint is called at | +| `evaluateGuide` | Three-part evaluation: brief summary, recommended use cases, unsupported use cases/limitations | +| `provider` / `product` | Owning provider and product (returned by the live API; not in the published OpenAPI spec, so treat as optional) | + +`meta` carries `q`, `total`, and `nextCursor`. **`nextCursor` is absent on the last +page** — check for its presence rather than comparing to `null`. + +### Pagination + +Pass `nextCursor` as the `cursor` **query parameter** (not a body field): + +```bash +curl -s -X POST 'https://api.buildwithorbit.ai/v1/search?cursor=eyJmcm9tIjoyfQ==' \ + -H 'Content-Type: application/json' \ + -d '{"q": "payment processing"}' +``` + +Pagination stops at 40 results total; a cursor past 40 is rejected. + +### Errors + +`400` invalid input · `429` rate limited · `500` server error. +Error bodies are RFC 9457 problem details: `type`, `title`, `status`, `detail`, `instance`. + +--- + +## POST /v1/integrate + +After selecting endpoints from `/v1/search`, send them here along with the task you +want to accomplish. Returns a **task brief** with the information and steps needed to +call those endpoints. + +Takes no query parameters. + +### Request body + +| Field | Type | Required | Notes | +|-------|------|----------|-------| +| `task` | string | Yes | What you want to accomplish. 1–512 characters, must contain non-whitespace. | +| `resources` | array | Yes | Endpoints to integrate, 1–10 items. Each item needs `id` and `type`. The MCP tool schema enforces a max of 10; the published OpenAPI spec omits the limit, so assume it applies to REST too and split larger sets across calls. | +| `resources[].id` | string | Yes | The `id` from a `/v1/search` result, verbatim. | +| `resources[].type` | string | Yes | The result's `resourceType`. Currently only `endpoint`. | + +```json +{ + "task": "Build an app to post current weather to Slack", + "resources": [ + { "id": "urn:orbit:endpoint:v1:...:weatherapi-com:current-weather-json", "type": "endpoint" }, + { "id": "urn:orbit:endpoint:v1:...:slack:send-message-to-slack", "type": "endpoint" } + ] +} +``` + +### Example curl + +```bash +curl -s -X POST https://api.buildwithorbit.ai/v1/integrate \ + -H 'Content-Type: application/json' \ + -d '{ + "task": "Send a transactional email when a user signs up", + "resources": [ + { "id": "urn:orbit:endpoint:v1:...:sendmux:send-a-single-email", "type": "endpoint" } + ] + }' | jq -r '.data[0].taskBrief' +``` + +### Response (200) + +```json +{ + "data": [ + { "taskBrief": "string" } + ] +} +``` + +The `taskBrief` is a multi-line document covering FIT, AUTH (including which +credentials you must supply), BASE URL, STEPS with parameters and expected responses, +dependencies between steps, and important considerations. It is built from the +selected endpoints' schemas plus shared variables, auth settings, and descriptions +defined by their parent APIs. + +### Errors + +`400` invalid input · `404` none of the `id`s could be resolved · `429` rate limited · +`500` server error. + +--- + +## Idempotency + +Both endpoints are read-only and never create or mutate data, so retries are safe and +no idempotency key is needed. Search results may change as the public catalog changes; +task brief wording may vary between otherwise identical calls. + +## The evaluateGuide field + +`evaluateGuide` is what makes Orbit results agent-friendly. It is a newline-separated +string in three parts, so an agent can decide whether an API fits without +trial-and-error: + +- **Summary** — a concise description of the endpoint's purpose +- **`Use for:`** — specific scenarios where this endpoint is the right choice +- **`Not supported:`** — capabilities this endpoint does not cover, preventing wasted + integration effort + +Example: + +``` +Sends a transactional email through Brevo's SMTP API, enabling an agent to deliver an email payload to recipients. +Use for: send transactional messages, deliver notifications, send account emails +Not supported: inbound email processing, contact management, campaign analytics +``` + +--- + +## MCP tools + +The plugin bundles Orbit's MCP server (`https://mcp.buildwithorbit.ai/mcp`, streamable +HTTP transport, no auth) via `.mcp.json`, referenced from `.codex-plugin/plugin.json` +as `"mcpServers": "./.mcp.json"`. It exposes two tools that map one-to-one onto the +REST endpoints and return identical payloads: + +| MCP tool | REST equivalent | +|----------|-----------------| +| `search` | `POST /v1/search` | +| `integrate` | `POST /v1/integrate` | + +Differences from REST: + +- `limit` and `cursor` are ordinary tool arguments, not query parameters. +- Both tools accept an optional `clientName` string for anonymous usage analytics. + Pass `"codex/orbit-plugin"`. +- `integrate` declares `resources` as 1–10 items in its schema. + +The tool schemas are the authoritative contract — they are fetched live from the +server, so they stay correct even when this file drifts. + +### Query guidance (from the tool description) + +- Use focused keyword queries including the product or provider name plus the endpoint + detail — e.g. `"PayPal create invoice"`. +- Natural language works too — e.g. `"PayPal API to create an invoice"`. +- Avoid jumbled queries cramming unrelated keywords together — e.g. + `"paypal invoice payment delivery payments ordering"`. +- Avoid `OR`-separated queries — e.g. `"paypal invoice OR paypal create invoice"`. +- To explore multiple intents, make a separate call per intent. From 59e91ef5a340a435bdb6e43d1d5b5c3e48da4033 Mon Sep 17 00:00:00 2001 From: Avdev4J <37835668+avdev4j@users.noreply.github.com> Date: Thu, 3 Sep 2026 12:46:21 +0200 Subject: [PATCH 2/3] Narrow the integrate guidance to a few resources per call Testing the Claude Code sibling plugin against the live Orbit server showed a 5-resource integrate call returning a one-line restatement instead of a task brief, while a 2-resource call returned the full document. The schema still accepts up to 10. Co-Authored-By: Claude --- skills/discover/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skills/discover/SKILL.md b/skills/discover/SKILL.md index 61c87b9..0f68c3d 100644 --- a/skills/discover/SKILL.md +++ b/skills/discover/SKILL.md @@ -81,9 +81,9 @@ If `meta.total` exceeds the number of returned results, mention that more result When the user has a concrete task and has settled on endpoints, call the `integrate` tool: - `task` — what they are building (required, max 512 characters) -- `resources` — **1 to 10** entries of `{id, type}`, where `id` is a search result's `id` and `type` is that result's `resourceType` +- `resources` — entries of `{id, type}`, where `id` is a search result's `id` and `type` is that result's `resourceType` -More than 10 resources is rejected. If the user needs more, split the work into several `integrate` calls grouped by sub-task. +The schema allows up to 10 resources, but **keep calls narrow — 2 or 3 related endpoints**. Wide calls have been observed to return a one-line restatement instead of a real brief. To cover more endpoints, make several focused calls grouped by sub-task rather than one wide call. The response contains a `taskBrief` covering authentication requirements, base URLs, ordered request steps, parameters, expected responses, dependencies between steps, and other considerations. Present the brief and save it alongside the search results. From 997ac11ef3bdae91d6ee66019ca69137a50b7860 Mon Sep 17 00:00:00 2001 From: Avdev4J <37835668+avdev4j@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:07:46 +0200 Subject: [PATCH 3/3] Restore Stripe in the README example, with real data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keeps Stripe as the illustrative provider. The values are now taken from an actual Orbit response rather than being invented. The heading is "Stripe create subscription" rather than "payment processing" because the generic query does not return Stripe at all — it returns Adyen, Moneris, and Peach Payments. Naming the provider is the query guidance the skill already documents, so the example now demonstrates it instead of contradicting it. Co-Authored-By: Claude --- README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7311098..f687611 100644 --- a/README.md +++ b/README.md @@ -50,17 +50,25 @@ Search for multiple capabilities at once: ### Example output ``` -### Results for: "send transactional email" +### Results for: "Stripe create subscription" -**Send a transactional email** (Brevo) +**Create a subscription** (Stripe / Stripe Billing) - Method: `POST` -- URL: `https://api.brevo.com/v3/smtp/email` -- **Evaluate Guide:** Sends a transactional email through Brevo's SMTP API, enabling - an agent to deliver an email payload to recipients. - Use for: send transactional messages, deliver notifications, send account emails - Not supported: inbound email processing, contact management, campaign analytics +- URL: `https://api.stripe.com/v1/subscriptions` +- Description: Creates a new subscription on an existing customer. Each customer can + have up to 500 active or scheduled subscriptions. +- **Evaluate Guide:** Creates a recurring subscription for an existing customer and + determines how its initial invoice and payment are handled. + Use for: start recurring billing, configure initial payment behavior, create + scheduled subscriptions + Not supported: customer creation, one-time charges, changing existing subscription + items ``` +Note the query includes the provider name. A generic `"payment processing"` search +returns Adyen, Moneris, and Peach Payments -- not Stripe. Naming the provider is the +single biggest lever on result quality. + Results are automatically saved to the `orbit-output/` directory as markdown files for later reference. Once you have chosen endpoints, the skill can also produce a **task brief** -- the auth