For the complete documentation index, see llms.txt.

cg-versions: the upstream version history MCP server

Connect an MCP client to cg-versions to look up upstream release history, version streams, and end-of-life dates for the projects Chainguard tracks.
  10 min read

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/mcp

What this server does not tell you

cg-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.

Not to be confused with Chainguard Libraries versions

“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.

Prerequisites

  • An MCP-compatible client such as Claude Code, Claude Desktop, or Cursor
  • A Chainguard account

Connect to the server

Claude Code

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

claude mcp add --transport http cg-versions https://versions.cgr.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):

claude mcp add --transport http --scope user cg-versions https://versions.cgr.dev/mcp

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

/mcp

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

claude mcp list
cg-versions: https://versions.cgr.dev/mcp (HTTP) - ✓ Connected

Cursor

Cursor 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

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:

  • 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://versions.cgr.dev/mcp and complete the browser sign-in when prompted.

Authentication

Authentication is OAuth 2.0 against the Chainguard issuer.

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.

Concepts

The catalog has three levels, and each tool works at one of them:

  • A project is a tracked upstream piece of software, named as the catalog names it. Names follow upstream convention rather than Chainguard image names, so Node.js is nodejs, not node.
  • A stream is a release line within a project, such as Python’s 3.12. Each stream carries its own end-of-life date and support status.
  • A version is a single release within a stream, such as 3.9.25, with attribution to the upstream tag and commit it was cut from.

Tool reference

ToolParametersReturnsExample prompt
search_projectsname_pattern, page_size, page_token{projects, next_page_token} — names only“Is there a tracked project for Node?”
get_projectproject{project: {name, streams}, size_bytes} with per-stream EOL status“Which Python versions are still supported upstream?”
get_streamproject, stream{stream: {project, stream, eol_date, is_eol, versions}, size_bytes}“List every Python 3.9 release with its upstream commit”
list_stream_versionsproject, 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?”

search_projects

Finds tracked projects by name. Results are paginated alphabetically.

ParameterTypeRequiredDescription
name_patternstringyesA Go regular expression applied to project names, such as kube.*, ^go$, or .* to match everything
page_sizeintegernoEntries per page (default 25, max 200)
page_tokenstringnoThe 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.

get_project

Returns a project’s identity together with a support-status summary for each of its version streams.

ParameterTypeRequiredDescription
projectstringyesProject name as search_projects returns it, such as python

Each stream in the response carries:

FieldDescription
streamThe release line, such as 3.12
eol_dateThe upstream end-of-life date, where known
is_eolWhether the stream is past that date
version_countHow 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.

get_stream

Returns the release history for one stream of a project, with upstream source attribution for each version.

ParameterTypeRequiredDescription
projectstringyesProject name, such as python
streamstringyesStream 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 typeWhat it contributes
gitThe upstream tag, a URL for it, the commit hash, and the tag’s publication timestamp
endoflife.dateWhen the release was recorded in endoflife.date
release_monitorThe 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.

list_stream_versions

Returns one stream’s release history a page at a time, newest first, with the same source attribution as get_stream.

ParameterTypeRequiredDescription
projectstringyesProject name, such as python
streamstringyesStream name within the project, such as 3.12
page_sizeintegernoVersions per page (default 50, max 200)
cursorstringnoThe 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.

Example usage

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.

Troubleshooting

SymptomWhat it meansWhat to do
A project lookup finds nothingThe 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 expectedname_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 missingThe 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 sizeThe 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: 0The 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 ChainguardIt 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 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-versions, 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://versions.cgr.dev/mcp and try again.

Next steps

  • cg-apk — check whether a package is actually built at a given version
  • cg-oci — check whether an image tag exists at a given version
  • cg-api — query organizations, IAM, and registry metadata through the platform API
  • Chainguard MCP servers overview — the full set, and the chainctl authentication recipe

Last updated: 2026-09-28 00:00