Meltano 4.3.0, cut on 21 September 2026 in the release commit, changes which plugin catalog meltano add and meltano lock read after meltano cloud auth login. Logged out sessions, and any project with its own Hub, keep the catalog they had. The same week adds meltano hub list and meltano plugin list, allows Click 8.5, and closes the system database connection opened by the startup probe.
A Cloud session selects a smaller catalog ¶
meltano cloud auth login used to store a token and then keep reading the public Hub. The catalog switch makes MeltanoHubService.hub_api_url return CLOUD_API_ROOT when the request carries a Cloud session and has_configured_hub is false. The constant sits in src/meltano/core/cloud/config.py and is also the OAuth audience, so the login token is one the API accepts.
Per the change, a live meltano hub list returned 555 plugins from Cloud, against 737 on the public Hub. tap-github resolved to matatika on Cloud and to meltanolabs on the public Hub. A logged in meltano add tap-github can write a different lock than it wrote a week ago. meltano install, meltano run, and meltano config never build the Hub service, so lock files already on disk stay in use. The commands that read the catalog are add, lock, hub ping, and hub list.
Highest precedence first:
hub_api_root
hub_url_auth
explicit hub_url
Cloud session
public Hub
has_configured_hub is true when hub_api_root or hub_url_auth is set, or when hub_url comes from anywhere other than the built in default, including meltano.yml and the environment. The cache file is the SHA256 of the index URL and lasts one hour, so the catalogs stay separate. Login and logout both make the next read fetch again.
A logged out project with no custom Hub logs one info line each time the service is constructed. The line names meltano cloud auth login. A project with its own Hub stays quiet, because the line and the URL choice both read has_configured_hub.
Listing the Hub and the project ¶
meltano hub list prints the configured catalog from the terminal. meltano discover is already gone, so the catalog is reachable from the CLI again. The command lives in src/meltano/cli/hub.py. Default output is one row per plugin, on the variant installed when the caller names none. --all prints every variant and marks the default. A positional pattern matches the plugin name or the variant, case insensitive, and only where that text appears on the row. --plugin-type takes the same values as meltano add.
meltano hub list github
meltano hub list --all --format json
meltano hub list --refresh
The match count is logged, including hidden variants, so --format json is rows only on stdout. The Hub has no search API and returns one plugin type per request. The pattern runs after that fetch. get_plugins_of_type defaults refresh to true, so add and hub ping still see a plugin published minutes ago. Only hub list reuses the one hour cache, unless --refresh is set.
meltano plugin list prints what the project declares in meltano.yml and included files, in file order inside each plugin type. Inherited plugins show (inherited) and the parent name. A definition that lives in the project is marked custom. JSON adds pip_url. Virtual environments stay unread. An installed version column was dropped because the Hub publishes no version to compare with. Mappings are omitted. The mapper is listed once.
meltano logs list now uses Rich SIMPLE_HEAD, cyan on status, bold on the log id, and folding columns. The values are unchanged.
Sessions, Hub errors, and from ref ¶
Cloud login is the session the catalog switch consumes. meltano cloud auth login, status, and logout run an OAuth 2.0 authorization code flow with PKCE. The identity provider is compiled in beside CLOUD_API_ROOT. The session is stored under the user config directory, attached on later Hub calls, and renewed when the access token expires.
hub_url_auth remains the header override for CI and for a private Hub. With that setting present, Cloud credentials stay unused and has_configured_hub is true, so the Cloud index stays out of the request.
Connection errors now include the URL and the underlying cause. A rejected response includes the Hub JSON message, so that text can change with no CLI release. meltano add --from-ref loads a YAML plugin definition and skips the Hub. lock and hub ping have no matching flag. Both still need a reachable catalog.
Reading the user config is new work on add, because that is where the session is loaded. A broken config file used to abort the command. It is now treated as logged out, and meltano add continues against the public Hub.
Click, environments, and the system database ¶
The Click pin in pyproject.toml moved from click>=8.2,<8.5,!=8.2.2 to click>=8.2,<8.6,!=8.2.2. Click 8.5 is inside the range. The 8.2.2 exclusion stays. src/meltano/cli/initialize.py wraps that click.prompt in typing.cast to Path. The cast is a type checker annotation. The widened pin is what allows Click 8.5 to install.
Environment handling in src/meltano/cli/utils.py calls project.deactivate_environment() when the invocation selected none and an environment is optional. It sets ProjectContext.environment_name to None on the tracker, including when the named environment is missing. Tests that reuse one Project were copying the old name forward. A fresh process starts empty.
The connectivity probe in project_engine calls connect() with database_max_retries and database_retry_timeout, then .close() on that connection, before check_database_compatibility and init_hook. The engine uses NullPool, so an open probe is a live server session. The returned engine is unchanged.
CI moved path filters into a files-changed job in .github/workflows/test.yml and .github/workflows/integration_tests.yml. Tests and typing run when runtime paths change. CI required checks treats a skip as success through re-actors/alls-green, and both workflows trigger on merge_group. Docs only pull requests merge with the suite skipped. Changes under src/ still run it.
Open notes followed the next day in a docs commit. The full list is the v4.3.0 release.
What to watch ¶
Compare meltano hub list tap-github logged out and logged in before adding plugins on a shared project. If the default variant moves, pass --variant on meltano add, or set hub_url so the public index stays selected. A Cloud session leaves an explicit hub_url alone.
meltano plugin list --format json reports declarations, inherited names, and custom definitions. Installed copies stay out of that output. A lock file versus the current Hub index is still a separate comparison.
The Click cap is 8.6, exclusive. The next Click minor fails resolution until the pin moves. The 8.2.2 exclusion remains in pyproject.toml.