termius-mcp 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- termius_mcp-3.0.0/AUTHORS +7 -0
- termius_mcp-3.0.0/LICENSE +30 -0
- termius_mcp-3.0.0/MANIFEST.in +7 -0
- termius_mcp-3.0.0/PKG-INFO +278 -0
- termius_mcp-3.0.0/README.md +229 -0
- termius_mcp-3.0.0/README.zh-CN.md +198 -0
- termius_mcp-3.0.0/contrib/mcp/codex.toml +8 -0
- termius_mcp-3.0.0/contrib/mcp/termius.mcp.json +8 -0
- termius_mcp-3.0.0/pyproject.toml +3 -0
- termius_mcp-3.0.0/setup.cfg +4 -0
- termius_mcp-3.0.0/setup.py +73 -0
- termius_mcp-3.0.0/termius/__init__.py +3 -0
- termius_mcp-3.0.0/termius/account/__init__.py +2 -0
- termius_mcp-3.0.0/termius/account/managers.py +226 -0
- termius_mcp-3.0.0/termius/cli.py +317 -0
- termius_mcp-3.0.0/termius/cloud/__init__.py +2 -0
- termius_mcp-3.0.0/termius/cloud/client/__init__.py +2 -0
- termius_mcp-3.0.0/termius/cloud/client/browser_sso.py +184 -0
- termius_mcp-3.0.0/termius/cloud/client/controllers.py +180 -0
- termius_mcp-3.0.0/termius/cloud/client/cryptor.py +339 -0
- termius_mcp-3.0.0/termius/cloud/client/grpc_login.py +422 -0
- termius_mcp-3.0.0/termius/cloud/client/keyring.py +252 -0
- termius_mcp-3.0.0/termius/cloud/client/sodium.py +216 -0
- termius_mcp-3.0.0/termius/cloud/client/srp_session.py +348 -0
- termius_mcp-3.0.0/termius/cloud/client/transformers/__init__.py +2 -0
- termius_mcp-3.0.0/termius/cloud/client/transformers/base.py +34 -0
- termius_mcp-3.0.0/termius/cloud/client/transformers/many.py +270 -0
- termius_mcp-3.0.0/termius/cloud/client/transformers/mixins.py +15 -0
- termius_mcp-3.0.0/termius/cloud/client/transformers/single.py +232 -0
- termius_mcp-3.0.0/termius/cloud/client/transformers/utils.py +12 -0
- termius_mcp-3.0.0/termius/core/__init__.py +2 -0
- termius_mcp-3.0.0/termius/core/api.py +264 -0
- termius_mcp-3.0.0/termius/core/constants.py +24 -0
- termius_mcp-3.0.0/termius/core/device.py +34 -0
- termius_mcp-3.0.0/termius/core/exceptions.py +59 -0
- termius_mcp-3.0.0/termius/core/models/__init__.py +2 -0
- termius_mcp-3.0.0/termius/core/models/base.py +174 -0
- termius_mcp-3.0.0/termius/core/models/terminal.py +243 -0
- termius_mcp-3.0.0/termius/core/models/utils.py +66 -0
- termius_mcp-3.0.0/termius/core/paths.py +19 -0
- termius_mcp-3.0.0/termius/core/settings.py +85 -0
- termius_mcp-3.0.0/termius/core/signals.py +22 -0
- termius_mcp-3.0.0/termius/core/ssh_command.py +60 -0
- termius_mcp-3.0.0/termius/core/ssh_exec.py +138 -0
- termius_mcp-3.0.0/termius/core/ssh_files.py +335 -0
- termius_mcp-3.0.0/termius/core/ssh_merge.py +69 -0
- termius_mcp-3.0.0/termius/core/storage/__init__.py +248 -0
- termius_mcp-3.0.0/termius/core/storage/driver.py +152 -0
- termius_mcp-3.0.0/termius/core/storage/idgenerators.py +25 -0
- termius_mcp-3.0.0/termius/core/storage/operators.py +11 -0
- termius_mcp-3.0.0/termius/core/storage/query.py +50 -0
- termius_mcp-3.0.0/termius/core/storage/strategies.py +150 -0
- termius_mcp-3.0.0/termius/core/subscribers.py +41 -0
- termius_mcp-3.0.0/termius/core/utils.py +44 -0
- termius_mcp-3.0.0/termius/main.py +43 -0
- termius_mcp-3.0.0/termius/mcp/__init__.py +2 -0
- termius_mcp-3.0.0/termius/mcp/protocol.py +93 -0
- termius_mcp-3.0.0/termius/mcp/server.py +140 -0
- termius_mcp-3.0.0/termius/mcp/tools.py +718 -0
- termius_mcp-3.0.0/termius/runtime.py +50 -0
- termius_mcp-3.0.0/termius/session.py +129 -0
- termius_mcp-3.0.0/termius/sync.py +186 -0
- termius_mcp-3.0.0/termius/vault.py +65 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/PKG-INFO +278 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/SOURCES.txt +68 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/dependency_links.txt +1 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/entry_points.txt +3 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/not-zip-safe +1 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/requires.txt +10 -0
- termius_mcp-3.0.0/termius_mcp.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Copyright (c) 2020, Termius Corporation.
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms of the software as well
|
|
4
|
+
as documentation, with or without modification, are permitted provided
|
|
5
|
+
that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright
|
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
* Redistributions in binary form must reproduce the above
|
|
11
|
+
copyright notice, this list of conditions and the following
|
|
12
|
+
disclaimer in the documentation and/or other materials provided
|
|
13
|
+
with the distribution.
|
|
14
|
+
|
|
15
|
+
* The names of the contributors may not be used to endorse or
|
|
16
|
+
promote products derived from this software without specific
|
|
17
|
+
prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
20
|
+
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
|
21
|
+
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
22
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
23
|
+
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
24
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
25
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
26
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
27
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
28
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
29
|
+
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
30
|
+
DAMAGE.
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: termius-mcp
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: Termius Cloud MCP server.
|
|
5
|
+
Home-page: https://github.com/MiaM1ku/termius-mcp
|
|
6
|
+
Author: MiaM1ku
|
|
7
|
+
Author-email: 61079068+MiaM1ku@users.noreply.github.com
|
|
8
|
+
License: BSD
|
|
9
|
+
Project-URL: Source, https://github.com/MiaM1ku/termius-mcp
|
|
10
|
+
Project-URL: Issues, https://github.com/MiaM1ku/termius-mcp/issues
|
|
11
|
+
Keywords: termius,mcp
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
15
|
+
Classifier: Operating System :: Unix
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
License-File: AUTHORS
|
|
26
|
+
Requires-Dist: requests>=2.7.0
|
|
27
|
+
Requires-Dist: cryptography>=3.2
|
|
28
|
+
Requires-Dist: six>=1.10.0
|
|
29
|
+
Requires-Dist: cached-property>=1.3.0
|
|
30
|
+
Requires-Dist: paramiko>=1.16.0
|
|
31
|
+
Requires-Dist: pathlib2>=2.1.0
|
|
32
|
+
Requires-Dist: blinker>=1.4
|
|
33
|
+
Requires-Dist: pynacl>=1.5.0
|
|
34
|
+
Requires-Dist: python-socketio>=5.11.0
|
|
35
|
+
Requires-Dist: websocket-client>=1.6.0
|
|
36
|
+
Dynamic: author
|
|
37
|
+
Dynamic: author-email
|
|
38
|
+
Dynamic: classifier
|
|
39
|
+
Dynamic: description
|
|
40
|
+
Dynamic: description-content-type
|
|
41
|
+
Dynamic: home-page
|
|
42
|
+
Dynamic: keywords
|
|
43
|
+
Dynamic: license
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
Dynamic: project-url
|
|
46
|
+
Dynamic: requires-dist
|
|
47
|
+
Dynamic: requires-python
|
|
48
|
+
Dynamic: summary
|
|
49
|
+
|
|
50
|
+
# Termius MCP
|
|
51
|
+
|
|
52
|
+
[English](README.md) · [简体中文](README.zh-CN.md)
|
|
53
|
+
|
|
54
|
+
stdio MCP server for [Termius](https://termius.com/) Cloud.
|
|
55
|
+
|
|
56
|
+
Repository: [MiaM1ku/termius-mcp](https://github.com/MiaM1ku/termius-mcp).
|
|
57
|
+
|
|
58
|
+
`termius` with no arguments is the MCP server. An MCP client starts that
|
|
59
|
+
binary with no args. The process speaks newline-delimited JSON-RPC on
|
|
60
|
+
stdin/stdout (MCP stdio). It negotiates `protocolVersion` `2025-11-25` or
|
|
61
|
+
`2025-06-18` (echoes the client when supported). Login, vault sync, host
|
|
62
|
+
lookup, SSH exec, and SFTP file transfer are tools.
|
|
63
|
+
|
|
64
|
+
`termius login` signs in from a terminal. Use it for Google SSO, email and
|
|
65
|
+
password, and OTP.
|
|
66
|
+
|
|
67
|
+
This tree talks to **Termius desktop 10.0.6** APIs (DeviceToken, SRP / gRPC
|
|
68
|
+
login, RNCryptor v3 and Sodium v4/v5, `v4/terminal/sync/`).
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
Python 3.9+ is required.
|
|
73
|
+
The PyPI name is `termius-mcp`. The official Termius CLI already uses `termius`.
|
|
74
|
+
After install, the command is still `termius`.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install termius-mcp
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
On Debian/Ubuntu (PEP 668) use a venv or `pipx`:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pipx install termius-mcp
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
From a git clone:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python3 -m venv ~/.local/share/termius-mcp
|
|
90
|
+
~/.local/share/termius-mcp/bin/pip install -U pip
|
|
91
|
+
~/.local/share/termius-mcp/bin/pip install -e .
|
|
92
|
+
ln -sf ~/.local/share/termius-mcp/bin/termius ~/.local/bin/termius
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Point the MCP client at that binary. Do not pass `mcp` or other args.
|
|
96
|
+
Do not pass `login` in the MCP client `args` list.
|
|
97
|
+
|
|
98
|
+
Claude / generic (`contrib/mcp/termius.mcp.json`):
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"termius": {
|
|
104
|
+
"command": "termius",
|
|
105
|
+
"args": []
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Codex (`contrib/mcp/codex.toml`, merge into `~/.codex/config.toml`):
|
|
112
|
+
|
|
113
|
+
```toml
|
|
114
|
+
[mcp_servers.termius]
|
|
115
|
+
command = "termius"
|
|
116
|
+
args = []
|
|
117
|
+
startup_timeout_sec = 30.0
|
|
118
|
+
tool_timeout_sec = 60.0
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Pi / OMP (`~/.omp/agent/mcp.json`):
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"termius": {
|
|
127
|
+
"type": "stdio",
|
|
128
|
+
"command": "termius",
|
|
129
|
+
"args": []
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Restart the MCP client after you edit the config. `connecting [stdio]` is the
|
|
136
|
+
handshake. It becomes connected when `initialize` succeeds. Sign in with
|
|
137
|
+
`termius login` before that, or use the login tools after connect.
|
|
138
|
+
|
|
139
|
+
Optional environment variables:
|
|
140
|
+
|
|
141
|
+
| Variable | Purpose |
|
|
142
|
+
| --- | --- |
|
|
143
|
+
| `TERMIUS_VAULT_PASSWORD` | Vault encryption password (preferred over the remember file) |
|
|
144
|
+
| `TERMIUS_SYNC_TTL` | Seconds before the next automatic pull. Default `60`. `0` pulls on every read. |
|
|
145
|
+
|
|
146
|
+
## First-time setup
|
|
147
|
+
|
|
148
|
+
Sign in from a terminal, then start the MCP client.
|
|
149
|
+
|
|
150
|
+
### Terminal login
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
termius login
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The command prompts for `google` or `email` when stdin is a TTY.
|
|
157
|
+
You can also pass the method:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
termius login google
|
|
161
|
+
termius login email -u you@example.com
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Google:
|
|
165
|
+
|
|
166
|
+
1. Open the printed `https://account.termius.com/sso/desktop?...` URL.
|
|
167
|
+
2. Sign in with Google.
|
|
168
|
+
3. When the page tries to open Termius, copy
|
|
169
|
+
`termius://app/continue-sso?...`.
|
|
170
|
+
4. Paste that URL.
|
|
171
|
+
5. Enter the vault encryption password from the Termius app. This is not
|
|
172
|
+
the Google password.
|
|
173
|
+
6. If 2FA is on, enter the OTP.
|
|
174
|
+
|
|
175
|
+
Email:
|
|
176
|
+
|
|
177
|
+
1. Enter the Termius email if you did not pass `-u`.
|
|
178
|
+
2. Enter the vault / account password.
|
|
179
|
+
3. If 2FA is on, enter the OTP.
|
|
180
|
+
|
|
181
|
+
`TERMIUS_VAULT_PASSWORD` supplies the vault password and skips the prompt.
|
|
182
|
+
Default remember writes `~/.termius/vault` mode `0600`. Pass `--no-remember`
|
|
183
|
+
to skip that file.
|
|
184
|
+
|
|
185
|
+
Check the session:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
termius status
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Sign out:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
termius logout
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### MCP tools
|
|
198
|
+
|
|
199
|
+
After the server is connected, you can also use the tools.
|
|
200
|
+
|
|
201
|
+
If `~/.termius/config` already has a DeviceToken (a previous login):
|
|
202
|
+
|
|
203
|
+
1. Call `status`. Expect `logged_in: true` and often `vault_remembered: false`.
|
|
204
|
+
2. Call `sync` with the **vault encryption password** from the Termius app
|
|
205
|
+
(not the Google password). Default `remember=true` writes `~/.termius/vault`
|
|
206
|
+
mode `0600`.
|
|
207
|
+
3. Call `hosts`. Later reads auto-pull when the cache is older than
|
|
208
|
+
`TERMIUS_SYNC_TTL`.
|
|
209
|
+
|
|
210
|
+
If this machine has never signed in and you are not using `termius login`:
|
|
211
|
+
|
|
212
|
+
1. Call `status`. Expect `logged_in: false`.
|
|
213
|
+
2. Google: call `login` with `method=google`. Open the returned URL. Sign in.
|
|
214
|
+
When the page tries to open Termius, copy
|
|
215
|
+
`termius://app/continue-sso?...`. Call `login_complete` with that URL and
|
|
216
|
+
the vault encryption password.
|
|
217
|
+
3. Email: call `login` with `method=email`, username, and the vault password.
|
|
218
|
+
Add `otp` if 2FA is on.
|
|
219
|
+
4. Call `hosts`.
|
|
220
|
+
|
|
221
|
+
The process never returns the vault password in a tool result.
|
|
222
|
+
|
|
223
|
+
## Tools
|
|
224
|
+
|
|
225
|
+
Call `status` first.
|
|
226
|
+
|
|
227
|
+
| Tool | Purpose |
|
|
228
|
+
| --- | --- |
|
|
229
|
+
| `status` | Login state, last sync, stale flag, vault remembered, counts. Does not pull. |
|
|
230
|
+
| `login` | `method=email` with username + password, or `method=google` to get an SSO URL |
|
|
231
|
+
| `login_complete` | Finish Google SSO with `callback_url` + vault password |
|
|
232
|
+
| `logout` | Clear the session, remembered password, and local inventory |
|
|
233
|
+
| `sync` | Force a cloud pull now |
|
|
234
|
+
| `hosts` | List hosts (optional `query`) |
|
|
235
|
+
| `host` | One host + merged SSH settings + `ssh_command` |
|
|
236
|
+
| `exec` | Run a remote command over SSH |
|
|
237
|
+
| `files` | SFTP list / stat / read / write / get / put / mkdir / rm / rename |
|
|
238
|
+
| `inventory` | `kind=groups\|identities\|keys\|snippets` |
|
|
239
|
+
|
|
240
|
+
`hosts`, `host`, `exec`, `files`, and `inventory` pull automatically when the
|
|
241
|
+
local cache is older than `TERMIUS_SYNC_TTL` and a vault password is available.
|
|
242
|
+
|
|
243
|
+
`files` uses SFTP on the same SSH credentials as `exec`. `get` and `put` copy
|
|
244
|
+
between the MCP host filesystem and the remote host. `read` and `write` move
|
|
245
|
+
file content through the tool result (max 200000 bytes). `get` and `put` allow
|
|
246
|
+
up to 50 MiB. `list` defaults `path` to the SSH login directory.
|
|
247
|
+
|
|
248
|
+
## Local data
|
|
249
|
+
|
|
250
|
+
After a successful pull, decrypted inventory lives in:
|
|
251
|
+
|
|
252
|
+
- `~/.termius/config` — DeviceToken, salts, `last_synced`
|
|
253
|
+
- `~/.termius/storage` — hosts, groups, identities, keys, snippets (plaintext JSON)
|
|
254
|
+
- `~/.termius/ssh_keys/` — private key files
|
|
255
|
+
- `~/.termius/vault` — remembered vault password, if you chose `remember`
|
|
256
|
+
|
|
257
|
+
Treat that directory as secret.
|
|
258
|
+
|
|
259
|
+
## Encryption notes
|
|
260
|
+
|
|
261
|
+
Termius Cloud currently has two personal encryption schemas:
|
|
262
|
+
|
|
263
|
+
- **v3** — per-field RNCryptor (AES-CBC + HMAC). REST login is enough.
|
|
264
|
+
- **v5** — entity `content` blobs sealed with Argon2id + XChaCha20-Poly1305, plus SRP login.
|
|
265
|
+
|
|
266
|
+
The server auto-detects ciphertext version (`A…` = v3, `B…` = v5). Login uses
|
|
267
|
+
gRPC/SRP first (desktop `login_v2`); REST is only the fallback for accounts
|
|
268
|
+
that are not migrated (`NOT_MIGRATED`). For v5 SRP the vault password is Argon2id-hashed (libsodium interactive,
|
|
269
|
+
16-byte salt) and base64-encoded, then proven with Botan SRP-6a
|
|
270
|
+
``modp/srp/8192`` + **Blake2b-512**. ``public_data`` / ``proof`` are
|
|
271
|
+
uppercase hex **without** a ``0x`` prefix (Android ``libtermius`` strips
|
|
272
|
+
Botan's prefix before the gRPC/Socket.IO payload).
|
|
273
|
+
|
|
274
|
+
Team vaults: `sync` / auto-pull loads `/api/v4/team/vault/keys/`, unwraps each `encrypted_with` key with the personal X25519 keypair (ECDH + HChaCha20 + XChaCha20-Poly1305), and decrypts shared hosts/keys/identities. Entities whose vault key is missing are skipped, not deleted.
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Termius MCP
|
|
2
|
+
|
|
3
|
+
[English](README.md) · [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
stdio MCP server for [Termius](https://termius.com/) Cloud.
|
|
6
|
+
|
|
7
|
+
Repository: [MiaM1ku/termius-mcp](https://github.com/MiaM1ku/termius-mcp).
|
|
8
|
+
|
|
9
|
+
`termius` with no arguments is the MCP server. An MCP client starts that
|
|
10
|
+
binary with no args. The process speaks newline-delimited JSON-RPC on
|
|
11
|
+
stdin/stdout (MCP stdio). It negotiates `protocolVersion` `2025-11-25` or
|
|
12
|
+
`2025-06-18` (echoes the client when supported). Login, vault sync, host
|
|
13
|
+
lookup, SSH exec, and SFTP file transfer are tools.
|
|
14
|
+
|
|
15
|
+
`termius login` signs in from a terminal. Use it for Google SSO, email and
|
|
16
|
+
password, and OTP.
|
|
17
|
+
|
|
18
|
+
This tree talks to **Termius desktop 10.0.6** APIs (DeviceToken, SRP / gRPC
|
|
19
|
+
login, RNCryptor v3 and Sodium v4/v5, `v4/terminal/sync/`).
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
Python 3.9+ is required.
|
|
24
|
+
The PyPI name is `termius-mcp`. The official Termius CLI already uses `termius`.
|
|
25
|
+
After install, the command is still `termius`.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install termius-mcp
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
On Debian/Ubuntu (PEP 668) use a venv or `pipx`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pipx install termius-mcp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
From a git clone:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
python3 -m venv ~/.local/share/termius-mcp
|
|
41
|
+
~/.local/share/termius-mcp/bin/pip install -U pip
|
|
42
|
+
~/.local/share/termius-mcp/bin/pip install -e .
|
|
43
|
+
ln -sf ~/.local/share/termius-mcp/bin/termius ~/.local/bin/termius
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Point the MCP client at that binary. Do not pass `mcp` or other args.
|
|
47
|
+
Do not pass `login` in the MCP client `args` list.
|
|
48
|
+
|
|
49
|
+
Claude / generic (`contrib/mcp/termius.mcp.json`):
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"termius": {
|
|
55
|
+
"command": "termius",
|
|
56
|
+
"args": []
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Codex (`contrib/mcp/codex.toml`, merge into `~/.codex/config.toml`):
|
|
63
|
+
|
|
64
|
+
```toml
|
|
65
|
+
[mcp_servers.termius]
|
|
66
|
+
command = "termius"
|
|
67
|
+
args = []
|
|
68
|
+
startup_timeout_sec = 30.0
|
|
69
|
+
tool_timeout_sec = 60.0
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Pi / OMP (`~/.omp/agent/mcp.json`):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"termius": {
|
|
78
|
+
"type": "stdio",
|
|
79
|
+
"command": "termius",
|
|
80
|
+
"args": []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Restart the MCP client after you edit the config. `connecting [stdio]` is the
|
|
87
|
+
handshake. It becomes connected when `initialize` succeeds. Sign in with
|
|
88
|
+
`termius login` before that, or use the login tools after connect.
|
|
89
|
+
|
|
90
|
+
Optional environment variables:
|
|
91
|
+
|
|
92
|
+
| Variable | Purpose |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| `TERMIUS_VAULT_PASSWORD` | Vault encryption password (preferred over the remember file) |
|
|
95
|
+
| `TERMIUS_SYNC_TTL` | Seconds before the next automatic pull. Default `60`. `0` pulls on every read. |
|
|
96
|
+
|
|
97
|
+
## First-time setup
|
|
98
|
+
|
|
99
|
+
Sign in from a terminal, then start the MCP client.
|
|
100
|
+
|
|
101
|
+
### Terminal login
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
termius login
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The command prompts for `google` or `email` when stdin is a TTY.
|
|
108
|
+
You can also pass the method:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
termius login google
|
|
112
|
+
termius login email -u you@example.com
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Google:
|
|
116
|
+
|
|
117
|
+
1. Open the printed `https://account.termius.com/sso/desktop?...` URL.
|
|
118
|
+
2. Sign in with Google.
|
|
119
|
+
3. When the page tries to open Termius, copy
|
|
120
|
+
`termius://app/continue-sso?...`.
|
|
121
|
+
4. Paste that URL.
|
|
122
|
+
5. Enter the vault encryption password from the Termius app. This is not
|
|
123
|
+
the Google password.
|
|
124
|
+
6. If 2FA is on, enter the OTP.
|
|
125
|
+
|
|
126
|
+
Email:
|
|
127
|
+
|
|
128
|
+
1. Enter the Termius email if you did not pass `-u`.
|
|
129
|
+
2. Enter the vault / account password.
|
|
130
|
+
3. If 2FA is on, enter the OTP.
|
|
131
|
+
|
|
132
|
+
`TERMIUS_VAULT_PASSWORD` supplies the vault password and skips the prompt.
|
|
133
|
+
Default remember writes `~/.termius/vault` mode `0600`. Pass `--no-remember`
|
|
134
|
+
to skip that file.
|
|
135
|
+
|
|
136
|
+
Check the session:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
termius status
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Sign out:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
termius logout
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### MCP tools
|
|
149
|
+
|
|
150
|
+
After the server is connected, you can also use the tools.
|
|
151
|
+
|
|
152
|
+
If `~/.termius/config` already has a DeviceToken (a previous login):
|
|
153
|
+
|
|
154
|
+
1. Call `status`. Expect `logged_in: true` and often `vault_remembered: false`.
|
|
155
|
+
2. Call `sync` with the **vault encryption password** from the Termius app
|
|
156
|
+
(not the Google password). Default `remember=true` writes `~/.termius/vault`
|
|
157
|
+
mode `0600`.
|
|
158
|
+
3. Call `hosts`. Later reads auto-pull when the cache is older than
|
|
159
|
+
`TERMIUS_SYNC_TTL`.
|
|
160
|
+
|
|
161
|
+
If this machine has never signed in and you are not using `termius login`:
|
|
162
|
+
|
|
163
|
+
1. Call `status`. Expect `logged_in: false`.
|
|
164
|
+
2. Google: call `login` with `method=google`. Open the returned URL. Sign in.
|
|
165
|
+
When the page tries to open Termius, copy
|
|
166
|
+
`termius://app/continue-sso?...`. Call `login_complete` with that URL and
|
|
167
|
+
the vault encryption password.
|
|
168
|
+
3. Email: call `login` with `method=email`, username, and the vault password.
|
|
169
|
+
Add `otp` if 2FA is on.
|
|
170
|
+
4. Call `hosts`.
|
|
171
|
+
|
|
172
|
+
The process never returns the vault password in a tool result.
|
|
173
|
+
|
|
174
|
+
## Tools
|
|
175
|
+
|
|
176
|
+
Call `status` first.
|
|
177
|
+
|
|
178
|
+
| Tool | Purpose |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| `status` | Login state, last sync, stale flag, vault remembered, counts. Does not pull. |
|
|
181
|
+
| `login` | `method=email` with username + password, or `method=google` to get an SSO URL |
|
|
182
|
+
| `login_complete` | Finish Google SSO with `callback_url` + vault password |
|
|
183
|
+
| `logout` | Clear the session, remembered password, and local inventory |
|
|
184
|
+
| `sync` | Force a cloud pull now |
|
|
185
|
+
| `hosts` | List hosts (optional `query`) |
|
|
186
|
+
| `host` | One host + merged SSH settings + `ssh_command` |
|
|
187
|
+
| `exec` | Run a remote command over SSH |
|
|
188
|
+
| `files` | SFTP list / stat / read / write / get / put / mkdir / rm / rename |
|
|
189
|
+
| `inventory` | `kind=groups\|identities\|keys\|snippets` |
|
|
190
|
+
|
|
191
|
+
`hosts`, `host`, `exec`, `files`, and `inventory` pull automatically when the
|
|
192
|
+
local cache is older than `TERMIUS_SYNC_TTL` and a vault password is available.
|
|
193
|
+
|
|
194
|
+
`files` uses SFTP on the same SSH credentials as `exec`. `get` and `put` copy
|
|
195
|
+
between the MCP host filesystem and the remote host. `read` and `write` move
|
|
196
|
+
file content through the tool result (max 200000 bytes). `get` and `put` allow
|
|
197
|
+
up to 50 MiB. `list` defaults `path` to the SSH login directory.
|
|
198
|
+
|
|
199
|
+
## Local data
|
|
200
|
+
|
|
201
|
+
After a successful pull, decrypted inventory lives in:
|
|
202
|
+
|
|
203
|
+
- `~/.termius/config` — DeviceToken, salts, `last_synced`
|
|
204
|
+
- `~/.termius/storage` — hosts, groups, identities, keys, snippets (plaintext JSON)
|
|
205
|
+
- `~/.termius/ssh_keys/` — private key files
|
|
206
|
+
- `~/.termius/vault` — remembered vault password, if you chose `remember`
|
|
207
|
+
|
|
208
|
+
Treat that directory as secret.
|
|
209
|
+
|
|
210
|
+
## Encryption notes
|
|
211
|
+
|
|
212
|
+
Termius Cloud currently has two personal encryption schemas:
|
|
213
|
+
|
|
214
|
+
- **v3** — per-field RNCryptor (AES-CBC + HMAC). REST login is enough.
|
|
215
|
+
- **v5** — entity `content` blobs sealed with Argon2id + XChaCha20-Poly1305, plus SRP login.
|
|
216
|
+
|
|
217
|
+
The server auto-detects ciphertext version (`A…` = v3, `B…` = v5). Login uses
|
|
218
|
+
gRPC/SRP first (desktop `login_v2`); REST is only the fallback for accounts
|
|
219
|
+
that are not migrated (`NOT_MIGRATED`). For v5 SRP the vault password is Argon2id-hashed (libsodium interactive,
|
|
220
|
+
16-byte salt) and base64-encoded, then proven with Botan SRP-6a
|
|
221
|
+
``modp/srp/8192`` + **Blake2b-512**. ``public_data`` / ``proof`` are
|
|
222
|
+
uppercase hex **without** a ``0x`` prefix (Android ``libtermius`` strips
|
|
223
|
+
Botan's prefix before the gRPC/Socket.IO payload).
|
|
224
|
+
|
|
225
|
+
Team vaults: `sync` / auto-pull loads `/api/v4/team/vault/keys/`, unwraps each `encrypted_with` key with the personal X25519 keypair (ECDH + HChaCha20 + XChaCha20-Poly1305), and decrypts shared hosts/keys/identities. Entities whose vault key is missing are skipped, not deleted.
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
See [LICENSE](LICENSE).
|