For the complete documentation index, see llms.txt.

cg-api: the Chainguard platform API MCP server

Connect an MCP client to cg-api to query Chainguard organizations, IAM, registry metadata, and security advisories through the platform API.
  12 min read

cg-api exposes the Chainguard platform API — the same API behind chainctl and the Chainguard Console — to an MCP client. Through it, a client can resolve which organizations and folders you belong to, list the image repositories and tags your account holds, inspect roles, role bindings, identity providers, and cloud account associations, and read security advisories. It is the broadest of Chainguard’s four product-data MCP servers, and the only one that reaches organization and IAM data.

The server uses the Streamable HTTP transport, at this endpoint:

https://console-api.enforce.dev/mcp

Like the other three servers, cg-api is read-only. It exposes none of the platform API’s create, update, or delete operations, so use chainctl or the Console to change platform resources.

Prerequisites

  • An MCP-compatible client such as Claude Code, Claude Desktop, or Cursor
  • A Chainguard account and an organization
  • chainctl installed, if you plan to narrow your token’s scope or use the headless authentication path

Connect to the server

Claude Code

Add the server with claude mcp add, using the HTTP transport:

claude mcp add --transport http cg-api https://console-api.enforce.dev/mcp

Pick the scope that fits how you want to use it: local (the default — only you, in the current directory), project (writes a shared .mcp.json at the repository root, checked in for teammates), or user (only you, across every project).

The server is added unauthenticated. To complete OAuth, start a session and run the /mcp command:

/mcp

Select cg-api, choose Authenticate, and approve the connection in the browser window that opens. Check the status any time with:

claude mcp list
cg-api: https://console-api.enforce.dev/mcp (HTTP) - ✓ Connected

Cursor

Cursor supports HTTP transport natively. Add the server to your MCP configuration:

{
  "mcpServers": {
    "cg-api": {
      "url": "https://console-api.enforce.dev/mcp"
    }
  }
}

Restart Cursor, then connect the server from Tools & MCPs in settings and complete the browser sign-in.

Claude Desktop

Claude Desktop reads MCP servers from a JSON file but does not yet support HTTP transport directly. Use mcp-remote to bridge to the hosted server:

{
  "mcpServers": {
    "cg-api": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://console-api.enforce.dev/mcp"
      ]
    }
  }
}

The configuration file lives at:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

npx downloads and runs mcp-remote on demand, so you need Node.js installed on the host. Restart Claude Desktop after saving the file.

Other MCP clients

Any client that supports a remote Streamable HTTP MCP server with OAuth can connect to the same endpoint. Point it at https://console-api.enforce.dev/mcp and complete the browser sign-in when prompted.

Authentication

Authentication is OAuth 2.0 against the Chainguard issuer, and every call runs with your own platform permissions. The server grants no access beyond what your role already allows.

On a remote or headless workstation, you can supply a token from chainctl instead of completing the browser flow. Refer to Authenticate with chainctl instead of a browser for the full recipe; cg-api’s audience is https://console-api.enforce.dev/mcp.

The tool list depends on your token

cg-api filters its advertised tools against the capabilities of the token you connected with. Two people connected to the same endpoint can see different tool lists, and a missing tool means your token can’t call it, not that the server doesn’t offer it. Run /mcp in Claude Code to see what your own token receives.

Narrow what an AI tool can do

chainctl auth token accepts two flags that reduce a token’s reach:

  • --capabilities requests a token narrowed to the capabilities you name. List the ones a token currently carries with chainctl auth token capabilities.
  • --scope reduces a token’s scope to the groups you name, which confines it to one organization or folder.

The browser OAuth flow offers no equivalent, so narrowing means authenticating through chainctl. Add the flags to the chainctl auth token call inside the headers helper described in the overview, and every connection that helper opens inherits the narrowed token. A helper that scopes its token to one organization produces a cg-api session that can’t read data from your other organizations.

Common parameters

Most tools share the following conventions.

UIDPs

Platform resources are addressed by UIDP, a slash-delimited path that encodes the resource’s position in the group hierarchy. A root organization has a bare UIDP such as 0ac7ff905850c35723a7f376e10d007c958c45c8; a folder beneath it appends a segment, as in 0ac7ff905850c35723a7f376e10d007c958c45c8/014da1131bcc7f51. Every *_get tool takes a uid of this shape, and you normally obtain it from a *_list call rather than constructing it.

The uidp filter

list tools accept a uidp object that scopes results to part of the hierarchy:

FieldTypeDescription
idsarray of stringsRestrict to these exact UIDPs
children_ofstringDirect children of this UIDP
descendants_ofstringEvery descendant of this UIDP, at any depth
ancestors_ofstringThe chain of groups above this UIDP
in_rootbooleanRestrict to root-level groups

Pagination

Every list tool returns at most 200 results per page and 50 by default; a larger page_size is reduced rather than rejected. Continue by passing the response’s nextPageToken as the next call’s page_token. Note the casing difference: the parameter is snake_case, and the response field is camelCase. Responses also carry totalCount, so an MCP client can report a total without paging through the results.

Most list tools additionally accept order_by and skip.

Tool reference

The server advertises 30 tools across 15 services, grouped by the service they belong to.

Run api_list to enumerate the services your own token reaches, and api_read to see an individual RPC’s metadata.

API discovery

ToolParametersReturns
api_listpathServices at the root, or the RPCs under a service such as iam.v2beta1.GroupsService
api_readpathThe metadata payload for one RPC, such as iam.v2beta1.GroupsService/ListGroups
api_callerstypeThe RPCs you can call that use a given proto message type

Example prompt: “What parts of the Chainguard API can I reach?”

Organizations and folders

ToolParametersReturns
iam_groups_listname, uidp, order_by, page_size, page_token, skipGroups you can access
iam_groups_getuidOne group

Example prompt: “What Chainguard organizations am I a member of?”

Roles and role bindings

ToolParametersReturns
iam_roles_listname, uidp, order_by, page_size, page_token, skipRoles available to you
iam_roles_getuidOne role
iam_role_bindings_getuidOne role binding

Example prompt: “What roles exist in my organization?”

Identities and identity providers

ToolParametersReturns
iam_identities_getuidOne identity
iam_identity_providers_listname, uidp, paginationConfigured identity providers
iam_identity_providers_getuidOne identity provider
iam_external_group_role_mappings_listuidp, paginationMappings from IdP groups to Chainguard roles
iam_external_group_role_mappings_getuidOne mapping

Example prompt: “Which identity providers are configured for my org?”

Invitations

ToolParametersReturns
iam_group_invites_getuidOne invitation

Cloud account associations

ToolParametersReturns
iam_account_associations_listuidp, paginationConfigured cloud account associations
iam_account_associations_getuidOne association
iam_account_associations_checkuid, provider_typeVerifies an association by performing a live credential exchange against Google, Amazon, or Azure

Example prompt: “Is my AWS account association working?”

Event subscriptions

ToolParametersReturns
iam_subscriptions_listuidp, paginationEvent subscriptions you can access
iam_subscriptions_getuidOne subscription

Despite the iam_ prefix, these tools address the events service rather than IAM. Refer to the events reference for the event types available.

Registry metadata

ToolParametersReturns
registry_repos_listname, uidp, order_by, page_size, page_token, skipRepositories you can access
registry_repos_getuidOne repository
registry_tags_listname, digest, updated_since, include_dates, include_epochs, include_referrers, include_vcs_snapshots, uidp, paginationTags you can access
registry_tags_getuidOne tag
registry_images_get_architecturesimage identifierThe architectures an image provides
registry_images_get_sizeimage identifierAn image’s size
registry_overlays_list / registry_overlays_getuidp, pagination, uidCustom Assembly overlays
registry_overlay_bindings_list / registry_overlay_bindings_getuidp, pagination, uidWhich overlays are bound to which repositories

Example prompt: “Which repositories in my org have been updated this week?”

Security advisories

ToolParametersReturns
vulnerabilities_advisories_getuidOne security advisory

Tools that are deliberately withheld

The server exposes no write tools. Every create, update, and delete operation in the platform API, and iam_terms_accept, is absent from the MCP tool list.

Six collection-listing tools are also withheld, because enumerating them wholesale would pull sensitive organization data into a model’s context. Four of the six have a per-resource *_get form, so you can still read a specific record when you have its UIDP:

Withheld toolRead one instead with
iam_scim_users_list—
iam_identities_listiam_identities_get
iam_group_invites_listiam_group_invites_get
iam_role_bindings_listiam_role_bindings_get
iam_terms_list_terms_acceptances—
vulnerabilities_advisories_listvulnerabilities_advisories_get

To enumerate any of these, or to change platform resources, use chainctl or the Console rather than an MCP client.

Core tools in detail

iam_groups_list

Lists the groups — organizations and folders — that the caller can access. An AI tool usually calls this first, because it returns the UIDPs that almost every other call needs.

ParameterTypeRequiredDescription
namestringnoFilter by group name
uidpobjectnoScope to part of the hierarchy
order_bystringnoSort order
page_sizeintegernoResults per page (default 50, max 200)
page_tokenstringnoThe nextPageToken from a previous call
skipintegernoSkip this many results

Each group returns name, uid, description, createTime, updateTime, and verified. The response carries totalCount and, when more pages remain, nextPageToken.

Example prompt: “What Chainguard organizations and folders can I see?”

registry_repos_list

Lists the container image repositories the caller can access, with the same filtering and pagination conventions. The response key is repos.

Each repository carries its full activeTags list, so pages get large quickly. A page of 50 repositories can exceed an MCP client’s result limit; use a smaller page_size when listing a large organization.

Example prompt: “List the repositories in my organization.”

This overlaps with cg-oci’s list_repos but answers a different question. registry_repos_list returns the platform’s record of a repository — its UIDP, its parent group, its configuration. cg-oci’s list_repos returns what the registry serves you over the OCI protocol. Use this one for organization and configuration questions, and cg-oci for pulling content.

registry_tags_list

Lists tags. It has more filters than any other tool on this server.

ParameterTypeRequiredDescription
namestringnoFilter by tag name
digeststringnoFind the tags pointing at a digest
updated_sincedate-timenoOnly tags updated after this timestamp
include_datesbooleannoInclude tag timestamps
include_epochsbooleannoInclude epoch information
include_referrersbooleannoInclude referring artifacts
include_vcs_snapshotsbooleannoInclude version control snapshot information
uidpobjectnoScope to part of the hierarchy

include_dates combined with updated_since is how you answer freshness questions across a whole organization, rather than one image at a time.

Example prompt: “Which tags in my org have been rebuilt since Monday?”

api_list, api_read, and api_callers

These three describe the API rather than query it, which makes them the reliable way to find out what your token can do.

api_list with an empty path returns the services available to you. On a broadly capable token that is 15 services, all at v2beta1: the iam, registry, vulnerabilities, and events families.

Pass a fully qualified service name to list that service’s RPCs. Use the name exactly as the root listing returns it — iam.v2beta1.GroupsService, not iam.Groups:

api_list(path: "iam.v2beta1.GroupsService")
  → GetGroup, ListGroups

A path that doesn’t resolve returns an empty entries list rather than an error, so an empty result usually means the name was abbreviated rather than that you lack access.

api_read takes a single RPC in Service/Rpc form and returns its metadata:

api_read(path: "iam.v2beta1.GroupsService/ListGroups")
  → capabilities: ["groups.list"]
    method: GET
    path: /iam/v2beta1/groups
    request:  chainguard.platform.iam.v2beta1.ListGroupsRequest
    response: chainguard.platform.iam.v2beta1.ListGroupsResponse

The capabilities field names the exact capability an RPC requires, which is what you need when narrowing a token to the smallest useful set.

api_callers works backwards from a proto message type, such as chainguard.platform.iam.Group, to the RPCs that use it.

Example prompt: “What RPCs can I call on the Groups service, and what capability does each need?”

Example usage

Sample exchanges from a Claude Code session with cg-api connected.

What Chainguard organizations can I see?
  Called cg-api (ctrl+o to expand)

● Your token reaches 24 groups in total. The root organization is
  acme-corp.com, which holds folders including platform, data-services,
  and a sandbox per team. Want me to page through the rest?
Which repositories in my org were updated in the last week?
  Called cg-api (ctrl+o to expand)

● 132 of the 142 repositories in your organization have at least one tag
  that moved in the last seven days, including gitlab-base, keycloak,
  python, and most of your Helm charts. The 10 that didn't change are
  mostly untagged test repositories, plus one expired entitlement
  (rabbitmq).
What parts of the API can I actually reach?
  Called cg-api (ctrl+o to expand)

● Your token reaches 15 services, all at v2beta1: eight under iam (Groups,
  Roles, RoleBindings, Identities, IdentityProviders, GroupInvites,
  AccountAssociations, ExternalGroupRoleMappings), five under registry
  (Repos, Tags, Images, Overlays, OverlayBindings), plus
  vulnerabilities.Advisories and events.Subscriptions.

Troubleshooting

SymptomWhat it meansWhat to do
A tool you expected isn’t listedcg-api filters its tool list by your token’s capabilities, and it withholds every write tool and six collection-listing tools from everyone.Run /mcp to see your session’s tools, and api_list to see the services your token reaches. For a write operation or a withheld list tool, use chainctl or the Console.
PERMISSION_DENIED on a callYour role does not carry the capability that RPC requires. The server enforces your existing permissions and adds nothing.Run api_read on the RPC to see the capability it requires, then check your role bindings with chainctl iam role-bindings list or ask an organization administrator.
A *_get call fails on a UIDP you typed by handUIDPs are slash-delimited hierarchy paths, not names, and a folder’s UIDP includes its parent’s.Get the UIDP from the matching *_list call rather than composing it.
A list call returns fewer results than totalCountThe response is one page. The default page size is 50 and the maximum is 200.Pass the response’s nextPageToken as page_token to continue.
Results look like another team’s dataThe API returns everything your token reaches across every organization you belong to, not just your current one.Scope the call with the uidp filter — children_of or descendants_of your own organization’s UIDP.
Server shows as not connected in claude mcp listOAuth was never completed, or the token expired. Claude Code’s tokens against the Chainguard issuer last about an hour and carry no refresh token.Run /mcp, select cg-api, and authenticate again, or switch to the chainctl helper.
401 invalid token when using the chainctl helperThe audience was registered as a bare hostname. MCP audiences must include the /mcp path.Run chainctl auth login --audience=https://console-api.enforce.dev/mcp and try again.

Next steps

Last updated: 2026-09-28 00:00