github agentic-community/mcp-gateway-registry 1.34.0
1.34.0 - LiteLLM Removal, Entra Group Recovery, Embeddings Hardening, and a Trust-Store Update

4 hours ago

Release 1.34.0 - LiteLLM Removal, Entra Group Recovery, Embeddings Hardening, and a Trust-Store Update

October 2026


Upgrading from 1.33.0

This section covers everything you need to know to upgrade from 1.33.0 to 1.34.0.

Breaking Changes

The registry no longer uses LiteLLM for remote embeddings. It calls the embeddings APIs through its own adapters for OpenAI and any OpenAI-compatible endpoint, Azure OpenAI, Amazon Titan on Amazon Bedrock, and Cohere on Amazon Bedrock. These send the same requests LiteLLM sent, so stored vectors stay valid and nothing re-embeds. EMBEDDINGS_PROVIDER=litellm keeps its name and still selects the remote path. A deployment that uses sentence-transformers, or an openai/, azure/, bedrock/amazon.titan-embed-* or bedrock/cohere.embed-* model name, needs no change.

Three configurations now stop the registry at startup, each with a message that names the fix:

  • A cohere/... model name (Cohere's own API) or a voyage/... name. Use bedrock/cohere.embed-english-v3 for Cohere, or openai/<model> with EMBEDDINGS_API_BASE for Voyage's OpenAI-compatible endpoint.
  • Any other LiteLLM-only prefix, such as mistral/, hosted_vllm/ or ollama/. Every OpenAI-compatible service (vLLM, Ollama, Mistral, a gateway) works as openai/<model> with EMBEDDINGS_API_BASE set to its base URL.
  • A model name with no prefix while EMBEDDINGS_PROVIDER=litellm. That combination never produced embeddings; it used to fail on the first call instead of at startup.

The remote embeddings request timeout drops from 600 seconds to 30. LiteLLM's default was 600. Raise EMBEDDINGS_REQUEST_TIMEOUT_SECONDS if a self-hosted endpoint needs longer.

The security scanners' llm analyzer is unavailable. The Cisco AI Defense scanners load LiteLLM for that analyzer, and the image no longer installs it. If SECURITY_ANALYZERS, AGENT_SECURITY_ANALYZERS or SKILL_SECURITY_ANALYZERS includes llm, the registry logs a warning at startup naming the setting, and each scan fails and records the entity as unsafe. Use yara for servers, yara,spec for agents, and static for skills. The analyzer can return once cisco-ai-defense/mcp-scanner#285 makes LiteLLM optional.

The shell CLI for server management and Anthropic import is removed. cli/service_mgmt.sh, its copy terraform/aws-ecs/scripts/service_mgmt.sh, cli/import_from_anthropic_registry.sh and cli/import_server_list.txt are gone. They have been deprecated in favour of the Registry Management API since #288, and the Anthropic import interpolated fields from public registry definitions into shell and Python command strings (reported in #1794). Scripts that call them need the API equivalents (#1935):

Removed Use instead
service_mgmt.sh add <config> api/registry_management.py register --config <config>
service_mgmt.sh delete ... api/registry_management.py remove --path <path>
service_mgmt.sh enable / disable api/registry_management.py toggle --path <path>
service_mgmt.sh monitor api/registry_management.py healthcheck
service_mgmt.sh test <config> api/registry_management.py server-search --query ...
import_from_anthropic_registry.sh <name> api/registry_management.py federation-add-anthropic-server --server-name <name>, then federation-sync --source anthropic, or cli/registry_cli_wrapper.py anthropic import <name>

Every registry_management.py command takes --registry-url and --token-file. cli/mcp_security_scanner.py --auto-disable now disables a failing server through the registry API and takes --registry-url and --registry-token-file. See Importing Servers from Anthropic MCP Registry.

Other upgrade notes

Entra deployments: delegated bearer tokens without group claims now need Microsoft Graph consent. Group recovery (#1913) is on by default (ENTRA_GROUP_RECOVERY_ENABLED=true). It runs for a delegated user token that carries an overage marker, and also for one that carries neither groups nor roles, which is common when the app registration does not emit group claims. The auth server then exchanges the token on behalf of the user for a Microsoft Graph token and reads the user's memberships. If the tenant has not granted delegated Graph User.Read consent for the gateway's app registration, those requests return 503 (Entra group lookup unavailable) where they previously reached the existing fallbacks. Grant the consent before upgrading, or set ENTRA_GROUP_RECOVERY_ENABLED=false to keep the previous behavior. Machine-to-machine tokens are not affected. See Group membership for user-delegated bearer tokens.

ENTRA_ENABLED is parsed like the registry's other booleans. true, 1 and yes enable Entra; false, 0 and no disable it. An unrecognized value logs an error and leaves Entra disabled, rather than stopping the auth server. Before this release a value such as 0 stayed a string and enabled Entra, so a deployment that set ENTRA_ENABLED=0 expecting it off now has it off (#1934).

This release removes two distrusted root CAs from every image we build. On 2026-10-20 the root programs distrusted "emSign ECC Root CA - G3" and "AAA Certificate Services" after eMudhra intermediates under those roots were found to have recoverable private keys (details). The registry, auth-server, mcpgw and metrics-service read their roots from certifi, not the operating system, so their outbound HTTPS trusted both roots until now. 1.34.0 ships certifi 2026.10.19 in every project lockfile, pip 26.2.2, and base images with an updated OS bundle. Upgrade to pick it up: no configuration change fixes it. Until you can upgrade, setting SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt on the Python services makes httpx use the OS bundle, which the updated base images already fix. That setting replaces certifi rather than adding to it, so do not use it if you rely on a private CA added to the default store. Run docker compose pull (or redeploy) as well, so third-party images that their publishers rebuilt under the same tag, such as postgres:16-alpine, are refreshed too.

Some images still carry those roots. Keycloak and four vendor images (Grafana, OpenBao, MongoDB, and the AWS Distro for OpenTelemetry collector on ECS) still ship them, and the fix has to come from their publishers. #1933 tracks each one. If your Keycloak brokers to an outside identity provider, you can remove the roots from its Java trust store with keytool -delete -cacerts -storepass changeit -alias emsigneccrootca-g3 (and -alias comodoaaaservicesroot on Keycloak 25) in a derived image.

Agents flagged for a null signature need a rescan. The registry sent agent cards to a2a-scanner with optional fields set to null, and the YARA rule UnauthorizedNetworkAccess_UnsignedMessages matched "signature": null as a finding (#1921). On one test catalog, 51 of 193 agents carried it. New scans omit null fields, but stored results keep the finding until the agent is scanned again. Rescan with POST /api/agents/{path}/rescan. An agent disabled because of this finding stays disabled until it is rescanned.

MCP_PROXY_TIMEOUT now bounds the whole proxied MCP request. It used to apply to each read, so an upstream that kept sending (for example SSE progress events) could run up to MCP_PROXY_TIMEOUT plus 30 seconds before nginx cut it. Such a call now returns 504 at MCP_PROXY_TIMEOUT. Raise it for servers with long-running tools.

The proxy answers subscriptions/listen itself. It returns JSON-RPC error -32601 (method not found) instead of forwarding the call. Each forwarded listen stream used to hold an egress connection open indefinitely, and about 100 of them filled the pool and made every egress call return 504 (#1890). A client that gets -32601 runs without server notifications.

An oauth_user server lists one tool before the user connects. While no credential is stored, tools/list on a direct route returns a single gateway tool named connect_mcpgw_<server>. Calling it starts the consent flow. Chat clients such as Claude Desktop only call tools they can see, so the empty list they got before left users with no way to connect (#1860).

Docker Compose now passes EMBEDDINGS_RESPONSE_FORMAT to the registry container. It was missing from all three compose files, so a Compose deployment that set it sees it take effect on upgrade.

New Environment Variables

Variable Default Description
EMBEDDINGS_EXTRA_HEADER_1 to EMBEDDINGS_EXTRA_HEADER_5 empty One Name: value header per slot, sent on every remote embeddings request. Startup rejects a malformed slot, a repeated name, and Authorization, Content-Type or Accept. Terraform: embeddings_extra_headers (map). Helm: registry.embeddings.extraHeaders (list).
EMBEDDINGS_REQUEST_TIMEOUT_SECONDS 30 Timeout for each remote embeddings request, 1 to 600 seconds.
EMBEDDINGS_MAX_RETRIES 2 Retries on HTTP 429, 5xx and connection errors, with exponential backoff, 0 to 10. On Amazon Bedrock it sets botocore's standard retry mode.
EMBEDDINGS_RETRY_MAX_INPUT_CHARS unset Length the registry trims an entry's text to when an embedding call fails. Unset means 2048 for Cohere on Amazon Bedrock and 28000 for other models. Lower it for a self-hosted model with a small input limit.
ENTRA_GROUP_RECOVERY_ENABLED true Recover Entra group memberships from Microsoft Graph when a delegated token is overage-marked or carries no group claims. false skips Graph and drops unreliable overage groups.
ENTRA_BROWSER_USER_READ_ENABLED false Request delegated Graph User.Read at browser login, so browser sign-in can recover groups too. Bearer-token recovery does not need it.
ENTRA_GROUP_CACHE_TTL_SECONDS 300 How long a recovered membership list is cached per user, 30 to 3600 seconds. A removed group can stay effective until the entry expires.
ENTRA_GRAPH_BASE_URL empty Graph fetch URL. Leave unset on standard Entra clouds; a custom login proxy needs an explicit HTTPS URL.
ENTRA_GRAPH_RESOURCE_URL empty Native Microsoft Graph OAuth audience, separate from the fetch URL. Leave unset on standard Entra clouds.
OPENBAO_AUTH_MOUNT empty Mount path of the OpenBao kubernetes or approle auth method. Empty keeps the default path (auth/kubernetes, auth/approle).

All ten rows are in the unified parameter reference with their Docker, Terraform and Helm names.

Upgrade Instructions

Docker Compose

cd mcp-gateway-registry
git pull origin main
git checkout 1.34.0

# Review new env vars in .env.example and update your .env if needed.
# Check EMBEDDINGS_MODEL_NAME and the *_SECURITY_ANALYZERS settings against
# the breaking changes above. Refresh third-party images, then rebuild and restart:
docker compose pull
./build_and_run.sh

Kubernetes / Helm (EKS)

cd mcp-gateway-registry
git pull origin main
git checkout 1.34.0

# REQUIRED: the registry, auth-server, keycloak-configure and stack charts changed in this release
cd charts/mcp-gateway-registry-stack
helm dependency build
helm dependency update

# Update values.yaml if needed, then upgrade:
helm upgrade mcp-gateway . -f your-values.yaml

Terraform / ECS

cd mcp-gateway-registry
git pull origin main
git checkout 1.34.0

# Optional new variables: embeddings_extra_headers,
# embeddings_request_timeout_seconds, embeddings_max_retries,
# embeddings_retry_max_input_chars, entra_group_recovery_enabled,
# entra_browser_user_read_enabled, entra_group_cache_ttl_seconds,
# entra_graph_base_url, entra_graph_resource_url
cd terraform/aws-ecs
terraform plan
terraform apply

Major Features

Embeddings without LiteLLM

The registry now calls remote embeddings APIs through about 500 lines of its own code instead of LiteLLM. OpenAI-compatible endpoints and Azure OpenAI go through httpx; Amazon Bedrock goes through boto3 and the standard AWS credential chain. The registry image shrinks from 1912 MB to 1843 MB, and LiteLLM, tiktoken and four smaller packages are no longer installed.

  • The adapters send the same request bodies LiteLLM sent. OpenAI and Amazon Titan vectors were compared before and after and match.
  • Startup rejects a model name no adapter can serve, instead of failing on the first embedding call.
  • Two new settings, EMBEDDINGS_REQUEST_TIMEOUT_SECONDS and EMBEDDINGS_MAX_RETRIES, control the timeout and retries.
  • GET /api/admin/embeddings/missing now lists entries stored with an empty vector, and POST /api/admin/embeddings/reindex reports such an entry as failed instead of succeeded.

PR #1920

Entra group recovery from Microsoft Graph

Entra leaves group IDs out of a token when a user belongs to more than about 200 groups, and some app registrations never emit a groups claim. Before this release, browser login looked up direct memberships only for a recognized overage marker, and a delegated bearer token with missing groups authenticated with no group-derived access. The auth server now reads the user's direct and nested memberships from Microsoft Graph /me/transitiveMemberOf whenever the token is overage-marked or carries no group claims.

  • Bearer tokens use an on-behalf-of exchange for a Graph token. Browser login can request delegated User.Read with ENTRA_BROWSER_USER_READ_ENABLED=true.
  • Results are cached per tenant and user for ENTRA_GROUP_CACHE_TTL_SECONDS (default 300). A failed lookup denies the request with 503 instead of granting partial access.
  • Graph calls go only to Microsoft Graph or to one configured proxy host, and paging links cannot redirect the token elsewhere.
  • Delegated tokens that cannot reach Graph need consent first; see the upgrade note above.

PR #1913

Extra headers on embeddings requests

An embeddings endpoint behind an API gateway often needs headers of its own, such as a tenant or module name. Operators can now set up to five, as EMBEDDINGS_EXTRA_HEADER_1 to _5 (Terraform embeddings_extra_headers, Helm registry.embeddings.extraHeaders). The registry sends them on every remote embeddings request and never lets them replace Authorization, Content-Type or Accept.

PR #1915

Long entries get embedded

A server with many tools can produce text longer than the model accepts. The provider rejected it and the entry never got a vector, so semantic search could not find it. The registry now retries a failed embedding once with shorter text: it keeps every name and cuts the longest descriptions first, at word boundaries. It retries only after a failure, and only when the text is longer than the target, so a normal entry is embedded exactly as before.

On the ECS test deployment, one server's 86,757 characters (20,375 tokens) exceeded the OpenAI model's 8,192-token limit. The retry cut it to 26,185 characters and the server now ranks first for searches that match it. On a local catalog using Cohere on Amazon Bedrock, a reindex went from 354 succeeded and 21 failed to 374 succeeded and none failed.

The stored content hash stays the hash of the full text, so a trimmed entry is skipped like any other until its content changes.

PR #1925

Configurable OpenBao auth mount

A shared Vault or OpenBao that serves several Kubernetes clusters keeps one kubernetes auth mount per cluster, each under its own path. The registry always logged in at the default path, so it could authenticate from only one cluster. OPENBAO_AUTH_MOUNT (Helm registry.egressAuth.openbao.authMount) sets the mount path for the kubernetes and approle methods.

PR #1882

New logo

The project has a new AI Gateway & Registry logo. It appears in the README, the docs, the web UI header and favicon, the server-rendered pages, the GitHub Pages landing page and the slide deck. docs/logo/ holds the full set in SVG and PNG.

PR #1919


What's New

Security

  • certifi 2026.10.19 in all seven project lockfiles, plus pip 26.2.2, python:3.14.9-slim base images and uv 0.13.5 in every Python image, so none of them trusts the two root CAs distrusted on 2026-10-20 (#1930)

  • metrics-service pins python:3.14.9-slim instead of the floating python:3.14-slim, which could resolve to a stale cached base, and metrics-db moves from alpine:3.19 to alpine:3.22 with apk upgrade, so both get an updated CA bundle (#1930)

  • Docker Compose moves Prometheus to v3.15.1 and the OpenTelemetry collector to 0.163.2, whose images no longer carry the distrusted roots. Helm and Terraform do not deploy either image (#1932)

  • A unit test fails if the installed certifi bundle contains a distrusted root, or if any lockfile pins a certifi older than the release that removed it (#1932)

  • Entra users with groups get registry scopes only from their group mappings. #1913 had also added the token's delegated scp values, which an app registration names and users grant by consent, outside administrator control (#1934)

  • The shell CLI whose Anthropic import ran fields from public registry definitions as shell and Python is removed (#1935)

Egress and Consent

  • tools/list returns a connect_mcpgw_<server> tool before consent, so chat clients can reach the connect step (#1902)
  • GET /oauth2/egress/connect without a session sends the browser to the configured login provider instead of a hard-coded Keycloak login (#1904)
  • The OpenBao kubernetes and approle auth methods take a configurable mount path (#1882)

MCP Proxy

  • MCP_PROXY_TIMEOUT bounds the whole proxied request, and the proxy answers subscriptions/listen locally, so idle listen streams no longer fill the egress connection pool (#1891)

AI Registry Tools

  • The intelligent_tool_finder description no longer promises removal in v1.26.0. The tool stays deprecated in favour of search_registry and will be removed in a future release (#1931)

CLI

  • cli/registry_cli_wrapper.py anthropic import <server-name> adds an Anthropic registry server to federation and syncs it, and the interactive CLI's import task uses it (#1935)
  • cli/registry_cli_wrapper.py accepts the nested .token layout the registry UI downloads (#1935)

Telemetry

  • Cloud detection honors the AWS, Azure and GCP answers given in the admin banner, recognizes EKS Auto Mode and Karpenter node names, and labels developer machines cloud=local (#1912)

Deployment

  • .dockerignore keeps .env files at any depth, .token* files and .claude/ out of the Docker build context. The images never copied them, but every build sent them to the Docker daemon (#1924)

Bug Fixes

  • The auth server crashed at startup after #1925 because it imported a module that needs numpy, which the auth server does not install. Fixed before release (#1928)
  • A malformed ENTRA_ENABLED no longer stops the auth server for every provider, and ENTRA_ENABLED=0 no longer enables Entra (#1934)
  • cli/mcp_security_scanner.py --auto-disable reads a server's state before disabling it, so it never re-enables a disabled server, and no longer reports a server as disabled when the disable failed (#1935)
  • A2A agent scans no longer report a false HIGH finding for null fields the registry adds to the card (#1923)
  • Tool discovery during health checks no longer wipes the OAuth client secret of oauth_user servers, which made every consent after the first discovery fail (#1900)
  • The health check sends notifications/initialized before its ping, so servers that enforce the MCP lifecycle are no longer marked unhealthy (#1906)
  • The Secrets Manager store retries its write verification when the read-back returns the previous version, instead of failing the egress token refresh with a 503 (#1898)
  • Skill security scans fetch SKILL.md with the same credentials as the content fetch, so private-repository skills scan instead of failing with a 404 (#1892)
  • GET /api/skills applies metadata_fields on every request, not only on the admin fast path (#1893)
  • GET /api/skills list items include created_at and updated_at, as server and agent lists already did (#1889)
  • On macOS, the log directory gets the right owner so registry, auth-server and mcpgw start, and a failed first nginx render reports the real error instead of a template placeholder (#1910)

Closed Issues

Issue Title Closed By
#1921 A2A agent scans report a false HIGH finding for null fields the registry adds to the scanned card PR #1923
#1918 Adopt the new AI Gateway & Registry logo in the README, docs, web UI and slide deck PR #1919
#1917 Retry embedding with trimmed text so servers with many tools can be indexed PR #1925
#1914 nginx resolver should default to /etc/resolv.conf (or take an explicit IP) manual (withdrawn by the reporter)
#1911 Cloud detection: honor AWS, Azure and GCP banner answers, and recognize instance-ID node names PR #1912
#1903 Egress consent link bounces to /oauth2/login/keycloak (hard-coded) and never reaches the configured IdP login PR #1904
#1901 Add cached Entra transitive group lookup when token group claims are missing PR #1913
#1899 Health-check tool discovery wipes the OAuth client secret of oauth_user servers PR #1900
#1890 mcp_proxy never releases subscriptions/listen streams: the egress pool fills up and every proxied call times out (504) PR #1891
#1881 OpenBao secret store: auth method mount path is not configurable PR #1882
#1876 Skill security scan does not use global GitHub credentials, so private-repo skills fail to scan PR #1892
#1875 Secrets Manager store: write verification reads back a stale version, egress refresh fails with 503 PR #1898
#1860 Pre-consent tools/list returns an empty list instead of the documented synthetic "connect" tool PR #1902
#1826 Remove the LiteLLM dependency: replace it with httpx and a small embeddings provider adapter PR #1920
#1819 Support operator-configured extra HTTP headers on requests to a custom embeddings endpoint PR #1915
#1817 Health check skips notifications/initialized, so strict MCP servers are marked unhealthy PR #1906
#1809 GET /api/skills ignores metadata_fields for nearly every caller PR #1893
#1575 macOS: prepare-log-dirs.sh 0750/uid-1000 blocks the bind mount and nginx logging PR #1910

Pull Requests Included

PR Title
#1935 chore(cli): remove deprecated service_mgmt.sh and the shell Anthropic import
#1934 fix(auth): keep Entra scp out of group-mapped scopes and parse ENTRA_ENABLED safely
#1932 fix: bump Prometheus and OTel collector images and guard certifi against eMudhra roots
#1931 docs(mcpgw): drop stale v1.26.0 removal date from intelligent_tool_finder
#1930 bump python, pip, uv, and certifi
#1928 fix(auth): keep numpy out of the auth server's import of search_repository
#1926 Revert "chore(deps): bump the uv group across 6 directories with 1 update"
#1925 feat(embeddings): retry a failed embedding once with trimmed text (#1917)
#1924 chore(docker): keep local env and token files out of the build context
#1923 fix(security): drop null fields from the A2A scan card (#1921)
#1922 chore(deps): bump the uv group across 6 directories with 1 update
#1920 feat(embeddings): replace LiteLLM with our own embeddings adapters (#1826)
#1919 feat(branding): adopt the new AI Gateway & Registry logo
#1915 feat(embeddings): send operator-configured extra headers on embeddings requests (#1819)
#1913 fix(auth): recover Entra groups omitted from login and bearer tokens
#1912 fix(telemetry): honor banner cloud answers and detect more environments (#1911)
#1910 fix: macOS log directory owner and unrendered nginx last-good config (#1575)
#1906 fix(health): send notifications/initialized before the health ping
#1904 fix(egress): bounce /oauth2/egress/connect to the configured login provider
#1902 fix(auth): list a connect tool before egress consent
#1900 fix(health): keep server secrets when tool discovery updates the card
#1898 fix(secrets): retry the Secrets Manager write verification on a stale read-back
#1896 chore(deps): weekly lockfile update (2026-10-19)
#1895 chore(deps): bump the actions group in /.github/workflows with 5 updates
#1894 chore(deps): bump python from 3.14.7-slim to 3.14.8-slim in /docker in the docker-images group
#1893 fix(skills): apply metadata_fields projection on every list path
#1892 fix(skills): send skill credentials with security scans
#1891 fix(auth): bound the mcp-proxy buffered read and refuse subscriptions/listen
#1889 fix(skills): return created_at and updated_at on GET /api/skills items
#1882 feat(egress): configurable mount path for the OpenBao auth method

Security Dependency Updates

Package Previous Updated Scope
python (base image) 3.14.7-slim 3.14.9-slim Docker images (metrics-service from the floating 3.14-slim)
certifi 2026.7.22 2026.10.19 all seven project lockfiles
pip 26.2.1 26.2.2 Python images and the registry venv
uv 0.11.14 0.13.5 Docker image builds
alpine (metrics-db base) 3.19 3.22 metrics-db image
prom/prometheus v3.11.3 v3.15.1 Docker Compose
otel/opentelemetry-collector-contrib 0.153.0 0.163.2 Docker Compose
cisco-ai-mcp-scanner 4.3.0 4.8.6 registry
cisco-ai-skill-scanner 2.2.1 2.2.2 registry
fastapi 0.142.2 0.143.0 registry
pydantic 2.13.5 2.14.1 registry
aiohttp 3.14.4 3.14.5 registry
boto3 / botocore 1.43.108 1.43.111 registry
pymongo 4.18.2 4.18.3 registry
opentelemetry-* 1.45.0 / 0.66b0 1.45.1 / 0.66b1 registry
litellm 1.104.0 removed registry

The certifi bump in #1922 was reverted in #1926 and replaced by #1930, which moves every project lockfile to 2026.10.19.


Contributors

Thank you to all contributors for this release:


Support


Full Changelog: 1.33.0...1.34.0

Don't miss a new mcp-gateway-registry release

NewReleases is sending notifications on new releases.