cg-oci: the Chainguard container registry MCP server
Connect an MCP client to cg-oci and read manifests, image configs, SBOMs, apko configs, and SLSA provenance directly …
For the complete documentation index, see llms.txt.
cg-versions gives an AI tool a read-only catalog of the upstream projects Chainguard tracks version information for. Through it, a client can find a tracked project, list its version streams with their end-of-life dates, and read the release history of one stream, whole or a page at a time, with attribution back to the upstream tag and commit each release came from. It answers questions about what upstream projects have published and what is still supported: whether Python 3.9 is past end of life, which streams of a project are still receiving releases, and which upstream commit a given version corresponds to.
The server uses the Streamable HTTP transport, at this endpoint:
https://versions.cgr.dev/mcpcg-versions tracks upstream releases, not what Chainguard builds. A version listed here means the upstream project published it. It doesn’t mean Chainguard has built a package or image for that version. A stream that has reached end of life upstream may also still be one Chainguard supports for customers.
To find out what Chainguard actually builds, use a different server:
cg-apk reads the APK index, so it shows whether a package exists at a given version.cg-oci reads the registry, so it shows whether an image tag exists at a given version.If you ask an AI tool “Can I get Python 3.9 from Chainguard?”, it may answer from this server’s upstream end-of-life data, which can’t answer that question. The Chainguard Containers product release lifecycle covers Chainguard’s support for versions that upstream has dropped.
“Versions” also names an unrelated concept in Chainguard Libraries: the +cgr.N and -0.cgr.N suffixes that mark a remediated build of a library package. Those suffixes are Chainguard’s own rebuild counters for Java, JavaScript, and Python artifacts, and they have nothing to do with this server. cg-versions serves upstream version history for the projects behind Chainguard’s images and packages. It does not serve library remediation versions, and no tool here returns a cgr.N suffix.
Add the server with claude mcp add, using the HTTP transport:
claude mcp add --transport http cg-versions https://versions.cgr.dev/mcpPick 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):
claude mcp add --transport http --scope user cg-versions https://versions.cgr.dev/mcpThe server is added unauthenticated. To complete OAuth, start a session and run the /mcp command:
/mcpSelect cg-versions, choose Authenticate, and approve the connection in the browser window that opens. Check the status any time with:
claude mcp listcg-versions: https://versions.cgr.dev/mcp (HTTP) - ✓ ConnectedCursor supports HTTP transport natively. Add the server to your MCP configuration:
{
"mcpServers": {
"cg-versions": {
"url": "https://versions.cgr.dev/mcp"
}
}
}Restart Cursor, then connect the server from Tools & MCPs in settings and complete the browser sign-in.
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-versions": {
"command": "npx",
"args": [
"mcp-remote",
"https://versions.cgr.dev/mcp"
]
}
}
}The configuration file lives at:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonnpx downloads and runs mcp-remote on demand, so you need Node.js installed on the host. Restart Claude Desktop after saving the file.
Any client that supports a remote Streamable HTTP MCP server with OAuth can connect to the same endpoint. Point it at https://versions.cgr.dev/mcp and complete the browser sign-in when prompted.
Authentication is OAuth 2.0 against the Chainguard issuer.
cg-versions does not authenticate you to cg-oci, cg-apk, or cg-api. Connecting all four means completing the browser sign-in four times. As of this writing, there is no unified sign-in across the four servers.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-versions’s audience is https://versions.cgr.dev/mcp.
The catalog has three levels, and each tool works at one of them:
nodejs, not node.3.12. Each stream carries its own end-of-life date and support status.3.9.25, with attribution to the upstream tag and commit it was cut from.| Tool | Parameters | Returns | Example prompt |
|---|---|---|---|
search_projects | name_pattern, page_size, page_token | {projects, next_page_token} — names only | “Is there a tracked project for Node?” |
get_project | project | {project: {name, streams}, size_bytes} with per-stream EOL status | “Which Python versions are still supported upstream?” |
get_stream | project, stream | {stream: {project, stream, eol_date, is_eol, versions}, size_bytes} | “List every Python 3.9 release with its upstream commit” |
list_stream_versions | project, stream, page_size, cursor | {page: {project, stream, eol_date, is_eol, versions, count, total_versions, has_more, next_cursor}} | “What are the three most recent Python 3.12 releases?” |
Finds tracked projects by name. Results are paginated alphabetically.
| Parameter | Type | Required | Description |
|---|---|---|---|
name_pattern | string | yes | A Go regular expression applied to project names, such as kube.*, ^go$, or .* to match everything |
page_size | integer | no | Entries per page (default 25, max 200) |
page_token | string | no | The next_page_token from a previous call. Reuse the same name_pattern when continuing. |
This takes a regular expression rather than a literal string. ^node returns node-feature-discovery, node-problem-detector, and nodejs, so a partial name usually finds the catalog’s name for the project. Anchor the pattern with ^ and $ when you want one project and nothing else.
Matches come back as names only, with no version data attached. Chain to get_project for anything more.
Returns a project’s identity together with a support-status summary for each of its version streams.
| Parameter | Type | Required | Description |
|---|---|---|---|
project | string | yes | Project name as search_projects returns it, such as python |
Each stream in the response carries:
| Field | Description |
|---|---|
stream | The release line, such as 3.12 |
eol_date | The upstream end-of-life date, where known |
is_eol | Whether the stream is past that date |
version_count | How many releases the catalog holds for the stream |
Use this tool to find which streams are still supported. For python it returns streams 3.8 through 3.14, with 3.9 and 3.8 marked is_eol: true and 3.14 carrying an eol_date of 2030-10-31. A version_count of zero means the catalog tracks the stream’s support dates but holds no individual releases for it, which is common for streams that reached end of life some time ago.
Returns the release history for one stream of a project, with upstream source attribution for each version.
| Parameter | Type | Required | Description |
|---|---|---|---|
project | string | yes | Project name, such as python |
stream | string | yes | Stream name within the project, such as 3.9 |
Both parameters are required, so the call is always scoped to a single release line; there is no way to pull a project’s entire history in one request. The response repeats the stream’s eol_date and is_eol, then lists its versions newest first. Each version carries a sources array, where each source has a type and whatever attribution that source provides:
| Source type | What it contributes |
|---|---|
git | The upstream tag, a URL for it, the commit hash, and the tag’s publication timestamp |
endoflife.date | When the release was recorded in endoflife.date |
release_monitor | The tag as release-monitoring.org saw it |
A single version usually carries all three, which is what makes this tool useful for provenance questions: Python 3.9.25 resolves to tag v3.9.25 at commit 0bbaf5de in python/cpython, published 2025-10-31.
This tool has no page_size or cursor. Streams usually hold only a few releases (Python 3.9 has five). The server refuses a response over 512 KB rather than truncating it, and get_project has the same limit. To read a long history a page at a time, use list_stream_versions.
Returns one stream’s release history a page at a time, newest first, with the same source attribution as get_stream.
| Parameter | Type | Required | Description |
|---|---|---|---|
project | string | yes | Project name, such as python |
stream | string | yes | Stream name within the project, such as 3.12 |
page_size | integer | no | Versions per page (default 50, max 200) |
cursor | string | no | The next_cursor from a previous call. Omit it on the first request. |
The response repeats the stream’s eol_date and is_eol, and adds count for the versions on this page and total_versions for the whole stream. When has_more is true, pass next_cursor as the next call’s cursor. For python stream 3.12, a page_size of 2 returns 3.12.14 and 3.12.13 out of 11 versions.
Use this tool instead of get_stream when you only need the most recent releases, or when get_stream refuses a stream for size.
Sample exchanges from a Claude Code session with cg-versions connected.
Which Python versions are still supported upstream? Called cg-versions (ctrl+o to expand)
● Upstream Python currently supports 3.10 through 3.14. End-of-life dates
run from 2026-10-31 for 3.10 out to 2030-10-31 for 3.14. Python 3.9 went
end of life on 2025-10-31 and 3.8 on 2024-10-07.
This is upstream support only. It doesn't tell you what Chainguard
builds; cg-apk or cg-oci can answer that.Is there a tracked project for Node? Called cg-versions (ctrl+o to expand)
● Three projects match: nodejs, node-feature-discovery, and
node-problem-detector. The Node.js runtime is tracked as "nodejs".Show me every Python 3.9 release and where it came from. Called cg-versions (ctrl+o to expand)
● The catalog doesn't have every Python 3.9 release. Its history starts in
December 2024 and holds five releases, newest first:
3.9.25 — tag v3.9.25, commit 0bbaf5de, published 2025-10-31
3.9.24 — tag v3.9.24, commit 91bdb00d, published 2025-10-09
3.9.23 — tag v3.9.23, commit 86527026, published 2025-06-03
3.9.22 — tag v3.9.22, commit 05c55492, published 2025-04-08
3.9.21 — tag v3.9.21, commit f3994ade, published 2024-12-03
All five are tagged in python/cpython. Python 3.9 reached end of life
upstream on 2025-10-31.| Symptom | What it means | What to do |
|---|---|---|
| A project lookup finds nothing | The name doesn’t match the catalog’s. Names follow upstream convention, not Chainguard image names. | Search with an unanchored pattern first, such as node, and use the name the search returns. |
| A search returns far more than you expected | name_pattern is a regular expression, so an unanchored pattern matches as a substring anywhere in the name. | Anchor it: ^go$ for the Go project alone, rather than go. |
| A stream you expected is missing | The catalog tracks streams the upstream project publishes as distinct release lines. Some projects don’t maintain parallel streams. | Call get_project to see the streams that exist before asking for one by name. |
get_stream or get_project is refused for size | The response exceeds the server’s 512 KB limit. Responses are never truncated. | Use list_stream_versions to read the stream a page at a time. |
A stream shows version_count: 0 | The catalog knows the stream’s support dates but holds no individual releases for it. | Use get_project for the support status; there is no release history to fetch. |
| The AI tool says a version is unavailable from Chainguard | It may be reasoning from upstream end-of-life data, which says nothing about Chainguard’s builds. | Ask it to check cg-apk or cg-oci instead, and refer to the product release lifecycle. |
Server shows as not connected in claude mcp list | OAuth 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-versions, and authenticate again, or switch to the chainctl helper. |
401 invalid token when using the chainctl helper | The audience was registered as a bare hostname. MCP audiences must include the /mcp path. | Run chainctl auth login --audience=https://versions.cgr.dev/mcp and try again. |
cg-apk — check whether a package is actually built at a given versioncg-oci — check whether an image tag exists at a given versioncg-api — query organizations, IAM, and registry metadata through the platform APIchainctl authentication recipeLast updated: 2026-09-28 00:00