Skip to content

Available MCPs Catalog API

The available MCPs catalog is a platform-curated list of known remote MCP servers. Authenticated users can browse and filter it; platform admins manage entries via mutations.

When a user selects a catalog entry from the UI, the frontend calls the existing POST /ai/agents/:agentId/mcp-servers endpoint with the optional availableMcpId, variantType, and credentials fields — the catalog entry is NOT provisioned through this endpoint directly.

All paths below are not under the /ai prefix — the catalog is a top-level resource.


Authentication Model

EndpointAuth RequiredPolicy Required
GET /available-mcpsJWT (@Auth())None — any valid session
POST /available-mcpsJWT + platform.ai.available-mcp createPlatform Admin role
PATCH /available-mcps/:idJWT + platform.ai.available-mcp updatePlatform Admin role
DELETE /available-mcps/:idJWT + platform.ai.available-mcp deletePlatform Admin role

Requests without a valid Authorization: Bearer <jwt> header return 401. Authenticated users without the platform policy return 403.


GET /available-mcps

Returns all active catalog entries. Optionally filtered by tags (OR semantics).

Query Parameters

ParameterTypeDescription
tagsstring[]Optional. Filter entries by tags. Returns entries matching any of the provided tags (OR semantics). Example: ?tags[0]=crm&tags[1]=payments
pagenumberOptional. Pagination page (default: 1).
limitnumberOptional. Page size (default: 20).
sortstringOptional. Sort field and direction. Example: sort[0][field]=createdAt&sort[0][direction]=desc

Response — 200 OK

Returns an array of AvailableMcpDto objects. Returns [] (not 404) when no entries match.

json
[
  {
    "id": "019f3a...",
    "name": "GitHub",
    "description": "Connect to GitHub to manage repositories, issues, pull requests, and more.",
    "logo": "/mcp-logos/github.svg",
    "tags": ["dev-tools"],
    "variants": [
      {
        "type": "apikey",
        "url": "https://api.githubcopilot.com/mcp/",
        "transportType": "http",
        "credentialSchema": {
          "type": "apikey",
          "fields": [
            {
              "key": "apiKey",
              "label": "GitHub Personal Access Token",
              "type": "password",
              "required": true,
              "placeholder": "Enter your API key"
            }
          ]
        }
      }
    ],
    "isActive": true,
    "createdAt": "2026-04-16T00:00:00.000Z",
    "updatedAt": "2026-04-16T00:00:00.000Z"
  }
]

Inactive Entries

Entries with isActive: false (soft-deleted) are never returned by this endpoint.


POST /available-mcps

Creates a new catalog entry. Platform Admin only.

Request Body

json
{
  "name": "My MCP",
  "description": "A description of what this MCP does.",
  "logo": "/mcp-logos/my-mcp.svg",
  "tags": ["dev-tools"],
  "variants": [
    {
      "type": "apikey",
      "url": "https://api.example.com/mcp",
      "transportType": "http",
      "credentialSchema": {
        "type": "apikey",
        "fields": [
          {
            "key": "apiKey",
            "label": "API Key",
            "type": "password",
            "required": true
          }
        ]
      }
    }
  ]
}

Validation Rules

  • name — non-empty, unique (conflict returns 409)
  • tags — at least one non-empty string
  • variants — at least one variant required (422 otherwise)
  • apikey variant — must have at least one field in credentialSchema.fields
  • free and oauth variants — credentialSchema.fields must be empty

Response — 201 Created

Returns the full AvailableMcpDto including the generated id.


PATCH /available-mcps/:id

Partially updates a catalog entry. All fields are optional. Platform Admin only.

Path Parameters

ParameterTypeDescription
idUUID v7The catalog entry ID

Request Body

All fields are optional — only provided fields are updated.

json
{
  "tags": ["crm", "productivity"],
  "logo": "/mcp-logos/updated.svg"
}

Response — 200 OK

Returns the full updated AvailableMcpDto.

Errors

  • 404 — Entry not found

DELETE /available-mcps/:id

Soft-deletes a catalog entry by setting isActive = false. Platform Admin only.

Hard delete is not supported — existing agent_mcp_servers rows referencing the entry via available_mcp_id would be orphaned. The ON DELETE SET NULL FK constraint handles the FK side, but the catalog record must remain for audit purposes.

Path Parameters

ParameterTypeDescription
idUUID v7The catalog entry ID

Response — 200 OK

Returns the updated AvailableMcpDto with isActive: false.

Errors

  • 404 — Entry not found

Variant Schema (Discriminated Union)

Each variant in variants[] is a discriminated union on the type field:

typeAuth modelcredentialSchema.fields
freeNo authMust be empty []
apikeyStatic headersMust have ≥1 field
oauthOAuth 2.0 / PKCEMust be empty []

Credential Field Schema

For apikey variants, each field in credentialSchema.fields has:

PropertyTypeDescription
keystringUnique key within the variant. Used as the credential map key.
labelstringDisplay label shown in the UI.
type"text" | "password" | "header"UI input type. password fields are masked.
requiredbooleanWhether the field is required when provisioning.
placeholderstring?Optional input placeholder text.
helpTextstring?Optional helper text shown below the input.
defaultstring?Optional default value pre-filled in the UI.

Tag Filter — OR Semantics

The tags query parameter uses OR semantics: an entry is returned if its tags array overlaps with any of the requested tags.

Example: GET /available-mcps?tags[0]=crm&tags[1]=payments

Returns entries tagged [crm], [payments], or [crm, payments]. All three qualify because at least one tag matches.

This is implemented using PostgreSQL's && array overlap operator with a GIN index on the tags column for performance.


Handoff: Adding a Catalog Entry to an Agent

To provision an AgentMcpServer row from a catalog entry, call the existing endpoint:

POST /ai/agents/:agentId/mcp-servers

With the optional catalog fields:

json
{
  "name": "GitHub (my project)",
  "url": "https://api.githubcopilot.com/mcp/",
  "transportType": "http",
  "availableMcpId": "019f3a...",
  "variantType": "apikey",
  "credentials": {
    "apiKey": "ghp_xxxxxxxxxxxxx"
  }
}

The handler will:

  1. Load the catalog entry by availableMcpId
  2. Find the variant matching variantType
  3. Validate required credential fields (returns 422 with missing field names if incomplete)
  4. Map variant type → McpAuthType: free → none, apikey → static_headers, oauth → oauth
  5. Save the AgentMcpServer with the available_mcp_id FK set

For oauth variants, credentials can be empty — OAuth flow is initiated separately via POST /ai/agents/:agentId/mcp-servers/:serverId/oauth/initiate.


Seed Behavior

On every application bootstrap, AvailableMcpSeedLoader runs automatically and inserts the 23 curated entries if they do not yet exist.

PropertyBehavior
Natural keyname — entries are looked up by name before insert
SemanticsInsert-only — existing entries are skipped unchanged
IdempotentSafe to run on every restart; count never exceeds 23 on repeat boots
Admin edits preservedTags, logo, and variant edits made via the API are never overwritten by the seed

The seed covers: GitHub, Supabase, Postman, Context7, Stripe, Slack, Notion, HubSpot, Linear, Jira, Confluence, Airtable, Google Sheets, Google Calendar, Datadog, Sentry, Vercel, Netlify, Twilio, Zapier, Firecrawl, Browserbase, Semrush.

Note: A 24th entry slot is reserved pending product confirmation. It is intentionally absent from the seed to avoid a placeholder entry.