Native Hermes plugin for Tesla Fleet API operations
Project description
Hermes Tesla Fleet plugin
Control and inspect Tesla Fleet API resources directly from Hermes.
This is a native, pip-installable Hermes plugin for Tesla owners, operators, and agents that need structured Tesla Fleet API tools instead of a terminal CLI wrapper. After you register your own Tesla Developer app and add your app credentials to the plugin config, Hermes gets a full Tesla tool surface for OAuth, vehicle reads, signed vehicle commands, charging, climate, security, energy sites, sharing, navigation, partner registration, and raw Fleet API escape hatches.
Why use this
- Native Hermes tools, not shell commands. The plugin registers through the
hermes_agent.pluginsentry point and returns structured JSON results. - Full Tesla Fleet coverage. The runtime registers 173 dedicated tools plus safe raw
/api/...escape hatches for future endpoints. - Built for real-world controls. Side-effecting commands require
confirm: trueand fail before network/file side effects when confirmation is missing. - Plugin-owned state. Tesla app config, OAuth tokens, vehicle-command keys, exports, and response cache live under
HERMES_HOME/plugins/hermes-tescmd-plugin/, not inside Hermes Agent config orsite-packages. - Signed-command aware. Known Vehicle Command Protocol commands use the plugin-owned P-256 key when required and fail closed if signing prerequisites are missing.
- Docs-only onboarding. There is intentionally no setup wizard or generic config mutation tool; Tesla app setup, HTTPS hosting, and virtual-key enrollment remain explicit operator-managed steps.
What this is not
- Not a wrapper around the upstream
tescmdCLI. - Not an MCP server, bridge daemon, Textual dashboard, or subprocess launcher.
- Not a tool that creates or mutates your Tesla Developer app for you.
- Not a public-key hosting automation service.
tescmd_key_deploy(method="local")prepares files; you publish them with your own HTTPS hosting.
Requirements
- Python 3.11+
- Hermes Agent with plugin support
- A Tesla Developer app you control
- Tesla Fleet API scopes appropriate for the operations you want
- A public HTTPS domain/callback if you use OAuth and vehicle-command key enrollment
- Optional: Google Maps Places API key for address/place-name lookup before multi-stop navigation
Install
From a local checkout:
pip install ~/hermes-tescmd-plugin
From a built wheel:
pip install dist/hermes_tescmd_plugin-*.whl
Restart Hermes after installation so plugin entry points reload.
For editable development, TestPyPI/prerelease installs, uninstall steps, and smoke checks, see INSTALL.md.
First-time setup at a glance
The full guided flow lives in docs/ONBOARDING.md. The short version is:
- Create a Tesla Developer app outside Hermes.
- Configure Tesla app URLs:
Allowed Origin URL(s): https://<your-domain>
Allowed Redirect URI(s): https://<your-domain>/callback
Allowed Returned URL(s): leave blank unless Tesla requires it
Do not put the .well-known public-key URL in those fields. Tesla discovers the vehicle-command public key from your app domain.
- Create plugin config at:
$HERMES_HOME/plugins/hermes-tescmd-plugin/config.json
Minimal single-profile shape:
{
"default": {
"profile": "default",
"client_id": "YOUR_TESLA_CLIENT_ID",
"client_secret": "YOUR_TESLA_CLIENT_SECRET_IF_USED",
"region": "na",
"domain": "cars.example.com",
"oauth_redirect_uri": "https://cars.example.com/callback",
"default_vin": "OPTIONAL_DEFAULT_VIN",
"google_maps_api_key": "OPTIONAL_GOOGLE_MAPS_PLACES_KEY",
"scopes": [
"openid",
"offline_access",
"vehicle_device_data",
"vehicle_cmds",
"vehicle_charging_cmds",
"vehicle_location",
"energy_device_data",
"energy_cmds",
"user_data"
]
}
}
- Ask Hermes to run
tescmd_status.
That status response is the best next-step dashboard. It reports readiness booleans, missing prerequisites, derived callback/public-key URLs, and recommended next actions.
-
Start OAuth with
tescmd_auth_login, open the returned Tesla URL, then complete withtescmd_auth_completeusing either the full callback URL orcode+state. -
For signed vehicle commands, generate and host a virtual-key public key:
tescmd_key_generate({"confirm": true})
tescmd_key_deploy({"method": "local", "confirm": true})
Upload or serve the generated hosting tree from your public HTTPS domain so Tesla can read:
https://<your-domain>/.well-known/appspecific/com.tesla.3p.public-key.pem
Then validate and enroll:
tescmd_key_validate({})
tescmd_key_enroll({})
docs/ONBOARDING.md includes a full OAuth + virtual-key enrollment walkthrough and an operator-managed Tailscale Funnel example for prerelease/testing setups.
Common Hermes tasks
| Goal | Start with |
|---|---|
| Check plugin/auth/key readiness | tescmd_status |
| Start Tesla OAuth | tescmd_auth_login |
| Complete OAuth callback | tescmd_auth_complete |
| List vehicles | tescmd_vehicle_list |
| Read vehicle status | tescmd_vehicle_status |
| Wake before a read | use wake: true with explicit confirmation where required |
| Start/stop climate | tescmd_climate_start, tescmd_climate_stop |
| Lock/unlock | tescmd_security_lock, tescmd_security_unlock |
| Set charge limit | tescmd_charge_limit |
| Open/close charge port | tescmd_charge_port_open, tescmd_charge_port_close |
| Search for a navigation place | tescmd_navigation_place_search |
| Send multi-stop navigation | tescmd_navigation_waypoints |
| Clear cached status data | tescmd_cache_clear |
| Reach a future Fleet endpoint | tescmd_raw_get, tescmd_raw_post, or tescmd_raw_delete |
Normal daily use should stay in the dedicated operational families: vehicle_*, charge_*, climate_*, security_*, media_*, navigation_*, energy_*, and sharing_*.
Tool surface
The plugin registers the complete 173-tool Hermes surface by default. Tool-load minimization is intentionally not used; if a call feels slow, profile command invocation, auth/cache behavior, and Tesla network latency rather than hiding tools from Hermes.
High-level families:
- status/help
- OAuth auth import/export/login/logout/refresh/register
- vehicle-command key generation, validation, enrollment, and local deploy prep
- user, billing, partner, energy, vehicle, charge, climate, security, media, navigation, software, power, sharing, telemetry guidance, cache, and raw Fleet API tools
For implementation details, see src/hermes_tescmd_plugin/runtime.py.
Safety model
Tesla controls can have physical effects. This plugin treats them that way.
Guardrails:
- side-effecting tools require
confirm: true - denied side effects make zero network requests/file writes
- wake-with-read is treated as a side effect when applicable
- known signed-command-required operations fail before network when no vehicle-command key is configured
- raw Fleet API paths must be relative
/api/...paths; absolute URLs, traversal, and NUL bytes are rejected - sensitive error payloads are redacted before returning to Hermes
- auth export writes a
0600file and does not return bearer/refresh tokens in tool output
Use the same care you would use with the Tesla app.
Stored state
The plugin stores mutable state under:
$HERMES_HOME/plugins/hermes-tescmd-plugin/
Typical files:
config.json— Tesla app/profile configauth.json— OAuth token statepending-auth.json— short-lived PKCE login stateresponse-cache.json— selected read-only Fleet responses; may include sensitive vehicle/location snapshotskeys/<profile>/vehicle-command-key.pem— private vehicle-command key, written0600keys/<profile>/vehicle-command-key.public.pem— public vehicle-command keyhosting/<profile>/...— static public-key hosting tree prepared by local deployexports/— explicit auth exports
No mutable auth/config is stored inside site-packages.
Tesla auth model
The plugin implements Tesla OAuth directly:
- browser authorization:
https://auth.tesla.com/oauth2/v3/authorize - token exchange/refresh/partner tokens:
https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token - Fleet API audience derived from the selected region
- profile-scoped token persistence under plugin-owned state
- partner registration via client credentials when configured
Partner/business-only scopes such as vehicle_specs, vehicle_pricing_info, and enterprise_management may be useful for partner flows, but tescmd_auth_login intentionally omits them from third-party customer OAuth URLs because Tesla does not grant them to ordinary user tokens.
Signed vehicle commands
tescmd_key_generate creates a Tesla-compatible P-256 keypair. tescmd_key_show and tescmd_status show the enrollment URL when a domain and public key are available:
https://tesla.com/_ak/<your-domain>
After virtual-key enrollment, commands that require Vehicle Command Protocol signing use the plugin-owned key and signed-session transport. Commands marked unsigned use Fleet REST command endpoints where Tesla still allows them.
Signed-command hardening includes:
- full VIN resolution before signing
- session-info HMAC verification
- session cache invalidation on protocol faults
- command registry fail-closed behavior for unknown commands
- private key files written with
0600permissions and no overwrite unlessforce: true
Navigation and Google Places
Tesla multi-waypoint navigation expects Google Maps Place IDs encoded as refId:<PLACE_ID>. If you already have Place IDs, no Google key is needed. If you want Hermes to resolve addresses or place names, add google_maps_api_key to plugin config with Places API enabled.
Use:
tescmd_navigation_place_searchto get candidates- choose the intended candidate
tescmd_navigation_waypoints({"place_ids": ["..."], "confirm": true})
Do not invent Place IDs. Use tescmd_navigation_send for a single address when multi-stop routing is unnecessary.
Upstream tescmd parity
A mechanical audit against the upstream tescmd Click tree found 155 upstream leaf commands. This plugin exposes 173 Hermes tools because it splits or renames some flows for native Hermes use.
Intentional differences:
- no
tescmd_setupor setup wizard; config is docs-only throughconfig.json - no upstream Textual dashboard, MCP server, OpenClaw bridge, telemetry daemon, or public-key hosting process launched inside Hermes
tescmd_serve,tescmd_openclaw_bridge, andtescmd_vehicle_telemetry_streamare compatibility/info tools- power, navigation, trunk, precondition, and telemetry names are normalized into clearer Hermes families
- GitHub Pages and Tailscale hosting automation are not plugin features; use your own HTTPS hosting
Development
Install dev dependencies:
python -m pip install -e '.[dev]'
Run the local release gate:
python -m pytest -q
python -m ruff check .
python -m mypy src/hermes_tescmd_plugin
python -m vulture src tests --min-confidence 90
python -m compileall -q src tests scripts
rm -rf dist build *.egg-info
python -m build --sdist --wheel
python -m twine check dist/*
CI runs the same checks on pull requests and pushes to main. Release publishing is handled separately by the GitHub Release-triggered PyPI Trusted Publishing workflow. See PUBLISHING.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_tescmd_plugin-0.5.0a11.tar.gz.
File metadata
- Download URL: hermes_tescmd_plugin-0.5.0a11.tar.gz
- Upload date:
- Size: 89.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b36a63a0305edac2b8ecdf6ad8a0c9cca8370be6511a4622386f0a19fbce39f
|
|
| MD5 |
28430befc2704c2977777a54a43d2ea3
|
|
| BLAKE2b-256 |
d9b42024c81aeb4d4cec40de057171d023c192065199e05eb597309cc1ef3657
|
Provenance
The following attestation bundles were made for hermes_tescmd_plugin-0.5.0a11.tar.gz:
Publisher:
publish-to-pypi.yml on Oceanswave/hermes-tescmd-plugin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hermes_tescmd_plugin-0.5.0a11.tar.gz -
Subject digest:
7b36a63a0305edac2b8ecdf6ad8a0c9cca8370be6511a4622386f0a19fbce39f - Sigstore transparency entry: 1568746973
- Sigstore integration time:
-
Permalink:
Oceanswave/hermes-tescmd-plugin@3f6b0eb4e6248394f5207e7770efe05e4475a1a9 -
Branch / Tag:
refs/tags/v0.5.0a11 - Owner: https://github.com/Oceanswave
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@3f6b0eb4e6248394f5207e7770efe05e4475a1a9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file hermes_tescmd_plugin-0.5.0a11-py3-none-any.whl.
File metadata
- Download URL: hermes_tescmd_plugin-0.5.0a11-py3-none-any.whl
- Upload date:
- Size: 75.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
325c90feda35d4b62b1a178fee97b8d5f8f7364d7c1ed115f6b27dbdaab28ede
|
|
| MD5 |
81c34342de16b3358133a8704b5c405d
|
|
| BLAKE2b-256 |
303e5cc53a6ad5152d7c05420baf676fb33df6433fb97425d46616a0b83cdf38
|
Provenance
The following attestation bundles were made for hermes_tescmd_plugin-0.5.0a11-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on Oceanswave/hermes-tescmd-plugin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hermes_tescmd_plugin-0.5.0a11-py3-none-any.whl -
Subject digest:
325c90feda35d4b62b1a178fee97b8d5f8f7364d7c1ed115f6b27dbdaab28ede - Sigstore transparency entry: 1568747010
- Sigstore integration time:
-
Permalink:
Oceanswave/hermes-tescmd-plugin@3f6b0eb4e6248394f5207e7770efe05e4475a1a9 -
Branch / Tag:
refs/tags/v0.5.0a11 - Owner: https://github.com/Oceanswave
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@3f6b0eb4e6248394f5207e7770efe05e4475a1a9 -
Trigger Event:
release
-
Statement type: