tunnel-manager 0.0.5__py3-none-any.whl → 1.0.1__py3-none-any.whl

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.

Potentially problematic release.


This version of tunnel-manager might be problematic. Click here for more details.

@@ -0,0 +1,440 @@
1
+ Metadata-Version: 2.4
2
+ Name: tunnel-manager
3
+ Version: 1.0.1
4
+ Summary: Create SSH Tunnels to your remote hosts and host as an MCP Server for Agentic AI!
5
+ Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
+ License: MIT
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: License :: Public Domain
9
+ Classifier: Environment :: Console
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: fastmcp>=2.11.3
16
+ Requires-Dist: paramiko>=4.0.0
17
+ Dynamic: license-file
18
+
19
+ # Tunnel Manager
20
+
21
+ ![PyPI - Version](https://img.shields.io/pypi/v/tunnel-manager)
22
+ ![PyPI - Downloads](https://img.shields.io/pypi/dd/tunnel-manager)
23
+ ![GitHub Repo stars](https://img.shields.io/github/stars/Knuckles-Team/tunnel-manager)
24
+ ![GitHub forks](https://img.shields.io/github/forks/Knuckles-Team/tunnel-manager)
25
+ ![GitHub contributors](https://img.shields.io/github/contributors/Knuckles-Team/tunnel-manager)
26
+ ![PyPI - License](https://img.shields.io/pypi/l/tunnel-manager)
27
+ ![GitHub](https://img.shields.io/github/license/Knuckles-Team/tunnel-manager)
28
+
29
+ ![GitHub last commit (by committer)](https://img.shields.io/github/last-commit/Knuckles-Team/tunnel-manager)
30
+ ![GitHub pull requests](https://img.shields.io/github/issues-pr/Knuckles-Team/tunnel-manager)
31
+ ![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/Knuckles-Team/tunnel-manager)
32
+ ![GitHub issues](https://img.shields.io/github/issues/Knuckles-Team/tunnel-manager)
33
+
34
+ ![GitHub top language](https://img.shields.io/github/languages/top/Knuckles-Team/tunnel-manager)
35
+ ![GitHub language count](https://img.shields.io/github/languages/count/Knuckles-Team/tunnel-manager)
36
+ ![GitHub repo size](https://img.shields.io/github/repo-size/Knuckles-Team/tunnel-manager)
37
+ ![GitHub repo file count (file type)](https://img.shields.io/github/directory-file-count/Knuckles-Team/tunnel-manager)
38
+ ![PyPI - Wheel](https://img.shields.io/pypi/wheel/tunnel-manager)
39
+ ![PyPI - Implementation](https://img.shields.io/pypi/implementation/tunnel-manager)
40
+
41
+ *Version: 1.0.1*
42
+
43
+ This project provides a Python-based `Tunnel` class for secure SSH connections and file transfers, integrated with a FastMCP server (`tunnel_manager_mcp.py`) to expose these capabilities as tools for AI-driven workflows. The implementation supports both standard SSH (e.g., for local networks) and Teleport's secure access platform, leveraging the `paramiko` library for SSH operations.
44
+
45
+ ## Features
46
+
47
+ ### Tunnel Class
48
+ - **Purpose**: Facilitates secure SSH connections, file transfers, and key management for single or multiple hosts.
49
+ - **Key Functionality**:
50
+ - **Run Remote Commands**: Execute shell commands on a remote host and retrieve output.
51
+ - **File Upload/Download**: Transfer files to/from a single host or all hosts in an inventory group using SFTP.
52
+ - **Passwordless SSH Setup**: Configure key-based authentication for secure, passwordless access, with support for RSA and Ed25519 key types.
53
+ - **SSH Config Management**: Copy local SSH config files to remote hosts.
54
+ - **Key Rotation**: Generate and deploy new SSH key pairs (RSA or Ed25519), updating `authorized_keys`.
55
+ - **Inventory Support**: Operate on multiple hosts defined in an Ansible-style YAML inventory, with group targeting (e.g., `all`, `homelab`, `poweredge`).
56
+ - **Teleport Support**: Seamlessly integrates with Teleport's certificate-based authentication and proxying.
57
+ - **Configuration Flexibility**: Loads SSH settings from `~/.ssh/config` by default, with optional overrides for username, password, identity files, certificates, and proxy commands.
58
+ - **Logging**: Optional file-based logging for debugging and auditing.
59
+ - **Parallel Execution**: Support for parallel operations across multiple hosts with configurable thread limits.
60
+ - **Key Type Support**: Explicit support for both RSA and Ed25519 keys in authentication, generation, and rotation for enhanced security and compatibility.
61
+
62
+ ## FastMCP Server
63
+ - **Purpose**: Exposes `Tunnel` class functionality as a FastMCP server, enabling AI tools to perform remote operations programmatically.
64
+ - **Tools Provided**:
65
+ - `run_command_on_remote_host`: Runs a shell command on a single remote host.
66
+ - `send_file_to_remote_host`: Uploads a file to a single remote host via SFTP.
67
+ - `receive_file_from_remote_host`: Downloads a file from a single remote host via SFTP.
68
+ - `check_ssh_server`: Checks if the SSH server is running and configured for key-based authentication.
69
+ - `test_key_auth`: Tests key-based authentication for a host.
70
+ - `setup_passwordless_ssh`: Sets up passwordless SSH for a single host.
71
+ - `copy_ssh_config`: Copies an SSH config file to a single remote host.
72
+ - `rotate_ssh_key`: Rotates SSH keys for a single host.
73
+ - `remove_host_key`: Removes a host’s key from the local `known_hosts` file.
74
+ - `configure_key_auth_on_inventory`: Sets up passwordless SSH for all hosts in an inventory group.
75
+ - `run_command_on_inventory`: Runs a command on all hosts in an inventory group.
76
+ - `copy_ssh_config_on_inventory`: Copies an SSH config file to all hosts in an inventory group.
77
+ - `rotate_ssh_key_on_inventory`: Rotates SSH keys for all hosts in an inventory group.
78
+ - `send_file_to_inventory`: Uploads a file to all hosts in an inventory group via SFTP.
79
+ - `receive_file_from_inventory`: Downloads a file from all hosts in an inventory group via SFTP.
80
+ - **Transport Options**: Supports `stdio` (for local scripting) and `http` (for networked access) transport modes.
81
+ - **Progress Reporting**: Integrates with FastMCP's `Context` for progress updates during operations.
82
+ - **Logging**: Comprehensive logging to a file (`tunnel_mcp.log` by default) or a user-specified file.
83
+
84
+ <details>
85
+ <summary><b>Usage:</b></summary>
86
+
87
+ ## Tunnel Class
88
+ The `Tunnel` class can be used standalone for SSH operations. Examples:
89
+
90
+ ### Using RSA Keys
91
+ ```python
92
+ from tunnel_manager.tunnel_manager import Tunnel
93
+
94
+ # Initialize with a remote host (assumes ~/.ssh/config or explicit params)
95
+ tunnel = Tunnel(
96
+ remote_host="192.168.1.10",
97
+ username="admin",
98
+ password="mypassword",
99
+ identity_file="/path/to/id_rsa",
100
+ certificate_file="/path/to/cert", # Optional for Teleport
101
+ proxy_command="tsh proxy ssh %h", # Optional for Teleport
102
+ ssh_config_file="~/.ssh/config",
103
+ )
104
+
105
+ # Connect and run a command
106
+ tunnel.connect()
107
+ out, err = tunnel.run_command("ls -la /tmp")
108
+ print(f"Output: {out}\nError: {err}")
109
+
110
+ # Upload a file
111
+ tunnel.send_file("/local/file.txt", "/remote/file.txt")
112
+
113
+ # Download a file
114
+ tunnel.receive_file("/remote/file.txt", "/local/downloaded.txt")
115
+
116
+ # Setup passwordless SSH with RSA
117
+ tunnel.setup_passwordless_ssh(local_key_path="~/.ssh/id_rsa", key_type="rsa")
118
+
119
+ # Copy SSH config
120
+ tunnel.copy_ssh_config("/local/ssh_config", "~/.ssh/config")
121
+
122
+ # Rotate SSH key with RSA
123
+ tunnel.rotate_ssh_key("/path/to/new_rsa_key", key_type="rsa")
124
+
125
+ # Close the connection
126
+ tunnel.close()
127
+ ```
128
+
129
+ ### Using Ed25519 Keys
130
+ ```python
131
+ from tunnel_manager.tunnel_manager import Tunnel
132
+
133
+ # Initialize with a remote host (assumes ~/.ssh/config or explicit params)
134
+ tunnel = Tunnel(
135
+ remote_host="192.168.1.10",
136
+ username="admin",
137
+ password="mypassword",
138
+ identity_file="/path/to/id_ed25519",
139
+ certificate_file="/path/to/cert", # Optional for Teleport
140
+ proxy_command="tsh proxy ssh %h", # Optional for Teleport
141
+ ssh_config_file="~/.ssh/config",
142
+ )
143
+
144
+ # Connect and run a command
145
+ tunnel.connect()
146
+ out, err = tunnel.run_command("ls -la /tmp")
147
+ print(f"Output: {out}\nError: {err}")
148
+
149
+ # Upload a file
150
+ tunnel.send_file("/local/file.txt", "/remote/file.txt")
151
+
152
+ # Download a file
153
+ tunnel.receive_file("/remote/file.txt", "/local/downloaded.txt")
154
+
155
+ # Setup passwordless SSH with Ed25519
156
+ tunnel.setup_passwordless_ssh(local_key_path="~/.ssh/id_ed25519", key_type="ed25519")
157
+
158
+ # Copy SSH config
159
+ tunnel.copy_ssh_config("/local/ssh_config", "~/.ssh/config")
160
+
161
+ # Rotate SSH key with Ed25519
162
+ tunnel.rotate_ssh_key("/path/to/new_ed25519_key", key_type="ed25519")
163
+
164
+ # Close the connection
165
+ tunnel.close()
166
+ ```
167
+
168
+ ## Tunnel Manager CLI Usage
169
+ The `tunnel_manager.py` script provides a CLI for managing SSH operations across hosts defined in an Ansible-style YAML inventory file. Below are examples for each command, targeting different inventory groups (`all`, `homelab`, `poweredge`). The CLI now supports both RSA and Ed25519 keys via the `--key-type` flag for relevant commands (default: `ed25519`).
170
+
171
+ **Inventory File Example (`inventory.yml`)**:
172
+ ```yaml
173
+ all:
174
+ hosts:
175
+ r510:
176
+ ansible_host: 192.168.1.10
177
+ ansible_user: admin
178
+ ansible_ssh_private_key_file: "~/.ssh/id_ed25519"
179
+ r710:
180
+ ansible_host: 192.168.1.11
181
+ ansible_user: admin
182
+ ansible_ssh_pass: mypassword
183
+ gr1080:
184
+ ansible_host: 192.168.1.14
185
+ ansible_user: admin
186
+ ansible_ssh_private_key_file: "~/.ssh/id_rsa"
187
+ homelab:
188
+ hosts:
189
+ r510:
190
+ ansible_host: 192.168.1.10
191
+ ansible_user: admin
192
+ ansible_ssh_private_key_file: "~/.ssh/id_ed25519"
193
+ r710:
194
+ ansible_host: 192.168.1.11
195
+ ansible_user: admin
196
+ ansible_ssh_pass: mypassword
197
+ gr1080:
198
+ ansible_host: 192.168.1.14
199
+ ansible_user: admin
200
+ ansible_ssh_private_key_file: "~/.ssh/id_rsa"
201
+ poweredge:
202
+ hosts:
203
+ r510:
204
+ ansible_host: 192.168.1.10
205
+ ansible_user: admin
206
+ ansible_ssh_private_key_file: "~/.ssh/id_ed25519"
207
+ r710:
208
+ ansible_host: 192.168.1.11
209
+ ansible_user: admin
210
+ ansible_ssh_pass: mypassword
211
+ ```
212
+
213
+ Replace IPs, usernames, and passwords with your actual values.
214
+
215
+ ### CLI Commands
216
+
217
+ #### 1. Setup Passwordless SSH
218
+ Set up passwordless SSH for hosts in the inventory, distributing a shared key. Use `--key-type` to specify RSA or Ed25519 (default: ed25519).
219
+ - **Target `all` group (sequential, Ed25519)**:
220
+ ```bash
221
+ tunnel-manager setup-all --inventory inventory.yml --shared-key-path ~/.ssh/id_shared --key-type ed25519
222
+ ```
223
+ - **Target `homelab` group (parallel, 3 threads, RSA)**:
224
+ ```bash
225
+ tunnel-manager setup-all --inventory inventory.yml --shared-key-path ~/.ssh/id_shared_rsa --key-type rsa --group homelab --parallel --max-threads 3
226
+ ```
227
+ - **Target `poweredge` group (sequential, Ed25519)**:
228
+ ```bash
229
+ tunnel-manager --log-file setup_poweredge.log setup-all --inventory inventory.yml --shared-key-path ~/.ssh/id_shared --key-type ed25519 --group poweredge
230
+ ```
231
+
232
+ #### 2. Run a Command
233
+ Execute a shell command on all hosts in the specified group.
234
+ - **Run `uptime` on `all` group (sequential)**:
235
+ ```bash
236
+ tunnel-manager run-command --inventory inventory.yml --remote-command "uptime"
237
+ ```
238
+ - **Run `df -h` on `homelab` group (parallel, 5 threads)**:
239
+ ```bash
240
+ tunnel-manager run-command --inventory inventory.yml --remote-command "df -h" --group homelab --parallel --max-threads 5
241
+ ```
242
+ - **Run `whoami` on `poweredge` group (sequential)**:
243
+ ```bash
244
+ tunnel-manager run-command --inventory inventory.yml --remote-command "whoami" --group poweredge
245
+ ```
246
+
247
+ #### 3. Copy SSH Config
248
+ Copy a local SSH config file to the remote hosts’ `~/.ssh/config`.
249
+ - **Copy to `all` group (sequential)**:
250
+ ```bash
251
+ tunnel-manager copy-config --inventory inventory.yml --local-config-path ~/.ssh/config
252
+ ```
253
+ - **Copy to `homelab` group (parallel, 4 threads)**:
254
+ ```bash
255
+ tunnel-manager copy-config --inventory inventory.yml --local-config-path ~/.ssh/config --group homelab --parallel --max-threads 4
256
+ ```
257
+ - **Copy to `poweredge` group with custom remote path**:
258
+ ```bash
259
+ tunnel-manager --log-file copy_config.log copy-config --inventory inventory.yml --local-config-path ~/.ssh/config --remote-config-path ~/.ssh/custom_config --group poweredge
260
+ ```
261
+
262
+ #### 4. Rotate SSH Keys
263
+ Rotate SSH keys for hosts, generating new keys with a prefix. Use `--key-type` to specify RSA or Ed25519 (default: ed25519).
264
+ - **Rotate keys for `all` group (sequential, Ed25519)**:
265
+ ```bash
266
+ tunnel-manager rotate-key --inventory inventory.yml --key-prefix ~/.ssh/id_ --key-type ed25519
267
+ ```
268
+ - **Rotate keys for `homelab` group (parallel, 3 threads, RSA)**:
269
+ ```bash
270
+ tunnel-manager rotate-key --inventory inventory.yml --key-prefix ~/.ssh/id_rsa_ --key-type rsa --group homelab --parallel --max-threads 3
271
+ ```
272
+ - **Rotate keys for `poweredge` group (sequential, Ed25519)**:
273
+ ```bash
274
+ tunnel-manager --log-file rotate.log rotate-key --inventory inventory.yml --key-prefix ~/.ssh/id_ --key-type ed25519 --group poweredge
275
+ ```
276
+
277
+ #### 5. Upload a File
278
+ Upload a local file to all hosts in the specified group.
279
+ - **Upload to `all` group (sequential)**:
280
+ ```bash
281
+ tunnel-manager send-file --inventory inventory.yml --local-path ./myfile.txt --remote-path /home/user/myfile.txt
282
+ ```
283
+ - **Upload to `homelab` group (parallel, 3 threads)**:
284
+ ```bash
285
+ tunnel-manager send-file --inventory inventory.yml --local-path ./myfile.txt --remote-path /home/user/myfile.txt --group homelab --parallel --max-threads 3
286
+ ```
287
+ - **Upload to `poweredge` group (sequential)**:
288
+ ```bash
289
+ tunnel-manager --log-file upload_poweredge.log send-file --inventory inventory.yml --local-path ./myfile.txt --remote-path /home/user/myfile.txt --group poweredge
290
+ ```
291
+
292
+ #### 6. Download a File
293
+ Download a file from all hosts in the specified group, saving to host-specific subdirectories (e.g., `downloads/R510/myfile.txt`).
294
+ - **Download from `all` group (sequential)**:
295
+ ```bash
296
+ tunnel-manager receive-file --inventory inventory.yml --remote-path /home/user/myfile.txt --local-path-prefix ./downloads
297
+ ```
298
+ - **Download from `homelab` group (parallel, 3 threads)**:
299
+ ```bash
300
+ tunnel-manager receive-file --inventory inventory.yml --remote-path /home/user/myfile.txt --local-path-prefix ./downloads --group homelab --parallel --max-threads 3
301
+ ```
302
+ - **Download from `poweredge` group (sequential)**:
303
+ ```bash
304
+ tunnel-manager --log-file download_poweredge.log receive-file --inventory inventory.yml --remote-path /home/user/myfile.txt --local-path-prefix ./downloads --group poweredge
305
+ ```
306
+
307
+ ### CLI Command Table
308
+ | Short Flag | Long Flag | Description | Required | Default Value |
309
+ |------------|----------------------|----------------------------------------------------------|----------|---------------|
310
+ | -h | --help | Show usage for the script | No | None |
311
+ | | --log-file | Log to specified file (default: console output) | No | Console |
312
+ | | setup-all | Setup passwordless SSH for all hosts in inventory | Yes* | None |
313
+ | | --inventory | YAML inventory path | Yes | None |
314
+ | | --shared-key-path | Path to shared private key | No | ~/.ssh/id_shared |
315
+ | | --key-type | Key type (rsa or ed25519) | No | ed25519 |
316
+ | | --group | Inventory group to target | No | all |
317
+ | | --parallel | Run operation in parallel | No | False |
318
+ | | --max-threads | Max threads for parallel execution | No | 5 |
319
+ | | run-command | Run a shell command on all hosts in inventory | Yes* | None |
320
+ | | --remote-command | Shell command to run | Yes | None |
321
+ | | copy-config | Copy SSH config to all hosts in inventory | Yes* | None |
322
+ | | --local-config-path | Local SSH config path | Yes | None |
323
+ | | --remote-config-path | Remote path for SSH config | No | ~/.ssh/config |
324
+ | | rotate-key | Rotate SSH keys for all hosts in inventory | Yes* | None |
325
+ | | --key-prefix | Prefix for new key paths (appends hostname) | No | ~/.ssh/id_ |
326
+ | | --key-type | Key type (rsa or ed25519) | No | ed25519 |
327
+ | | send-file | Upload a file to all hosts in inventory | Yes* | None |
328
+ | | --local-path | Local file path to upload | Yes | None |
329
+ | | --remote-path | Remote destination path | Yes | None |
330
+ | | receive-file | Download a file from all hosts in inventory | Yes* | None |
331
+ | | --remote-path | Remote file path to download | Yes | None |
332
+ | | --local-path-prefix | Local directory path prefix to save files | Yes | None |
333
+
334
+ ### Notes
335
+ One of the commands (`setup-all`, `run-command`, `copy-config`, `rotate-key`, `send-file`, `receive-file`) must be specified as the first argument to `tunnel_manager.py`. Each command has required arguments that must be specified with flags:
336
+ - `setup-all`: Requires `--inventory`.
337
+ - `run-command`: Requires `--inventory` and `--remote-command`.
338
+ - `copy-config`: Requires `--inventory` and `--local-config-path`.
339
+ - `rotate-key`: Requires `--inventory`.
340
+ - `send-file`: Requires `--inventory`, `--local-path`, and `--remote-path`.
341
+ - `receive-file`: Requires `--inventory`, `--remote-path`, and `--local-path-prefix`.
342
+
343
+ ### Additional Notes
344
+ - Ensure `ansible_host` values in `inventory.yml` are resolvable IPs or hostnames.
345
+ - Update `ansible_ssh_private_key_file` in the inventory after running `rotate-key`.
346
+ - Use `--log-file` for file-based logging or omit for console output.
347
+ - The `--parallel` option speeds up operations but may overload resources; adjust `--max-threads` as needed.
348
+ - The `receive-file` command saves files to `local_path_prefix/<hostname>/<filename>` to preserve original filenames and avoid conflicts.
349
+ - Ed25519 keys are recommended for better security and performance over RSA, but RSA is supported for compatibility with older systems.
350
+
351
+ ## FastMCP Server
352
+ The FastMCP server exposes the `Tunnel` functionality as AI-accessible tools. Start the server with:
353
+
354
+ ```bash
355
+ python tunnel_manager_mcp.py --transport stdio
356
+ ```
357
+
358
+ Or for HTTP transport:
359
+ ```bash
360
+ python tunnel_manager_mcp.py --transport http --host 127.0.0.1 --port 8080
361
+ ```
362
+
363
+ </details>
364
+
365
+ <details>
366
+ <summary><b>Installation Instructions:</b></summary>
367
+
368
+ ## Use with AI
369
+
370
+ Configure `mcp.json`
371
+ ```json
372
+ {
373
+ "mcpServers": {
374
+ "tunnel_manager": {
375
+ "command": "uv",
376
+ "args": [
377
+ "run",
378
+ "--with",
379
+ "tunnel-manager",
380
+ "tunnel_manager_mcp"
381
+ ],
382
+ "env": {
383
+ "TUNNEL_REMOTE_HOST": "192.168.1.12", // Optional
384
+ "TUNNEL_USERNAME": "admin", // Optional
385
+ "TUNNEL_PASSWORD": "", // Optional
386
+ "TUNNEL_REMOTE_PORT": "22", // Optional
387
+ "TUNNEL_IDENTITY_FILE": "", // Optional
388
+ "TUNNEL_INVENTORY": "~/inventory.yaml", // Optional
389
+ "TUNNEL_INVENTORY_GROUP": "all", // Optional
390
+ "TUNNEL_PARALLEL": "true", // Optional
391
+ "TUNNEL_CERTIFICATE": "", // Optional
392
+ "TUNNEL_PROXY_COMMAND": "", // Optional
393
+ "TUNNEL_LOG_FILE": "~/tunnel_log.txt", // Optional
394
+ "TUNNEL_MAX_THREADS": "6" // Optional
395
+ },
396
+ "timeout": 200000
397
+ }
398
+ }
399
+ }
400
+ ```
401
+
402
+ ### Deploy MCP Server as a Container
403
+ ```bash
404
+ docker pull knucklessg1/tunnel-manager:latest
405
+ ```
406
+
407
+ Modify the `compose.yml`
408
+ ```yaml
409
+ services:
410
+ tunnel-manager:
411
+ image: knucklessg1/tunnel-manager:latest
412
+ environment:
413
+ - HOST=0.0.0.0
414
+ - PORT=8021
415
+ ports:
416
+ - 8021:8021
417
+ ```
418
+
419
+ ### Install Python Package
420
+ ```bash
421
+ python -m pip install tunnel-manager
422
+ ```
423
+
424
+ or
425
+
426
+ ```bash
427
+ uv pip install --upgrade tunnel-manager
428
+ ```
429
+
430
+ </details>
431
+
432
+ <details>
433
+ <summary><b>Repository Owners:</b></summary>
434
+
435
+
436
+ <img width="100%" height="180em" src="https://github-readme-stats.vercel.app/api?username=Knucklessg1&show_icons=true&hide_border=true&&count_private=true&include_all_commits=true" />
437
+
438
+ ![GitHub followers](https://img.shields.io/github/followers/Knucklessg1)
439
+ ![GitHub User's stars](https://img.shields.io/github/stars/Knucklessg1)
440
+ </details>
@@ -0,0 +1,11 @@
1
+ tests/test_tunnel.py,sha256=Dj6z1EM50uGqEJA0GBDP6L8ZPUMRAJNT7dAnwkuSgNU,2461
2
+ tunnel_manager/__init__.py,sha256=cqAitAkoCcEkaCQcP7Y8tngiUK7pU6SIMlmpABShh9g,807
3
+ tunnel_manager/__main__.py,sha256=Z1uxNLjwIjJpvu97bXrvsawnghJScA52E2wtAgg5MLo,152
4
+ tunnel_manager/tunnel_manager.py,sha256=DZn2Zs0OPxB_2wWqkro--UbFLdoe8kivaeLvKZKWANM,39384
5
+ tunnel_manager/tunnel_manager_mcp.py,sha256=_TVDIH7fZpNsADbCKpMU8uzTUU41l9YqKNuK6dvaxl4,76157
6
+ tunnel_manager-1.0.1.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
7
+ tunnel_manager-1.0.1.dist-info/METADATA,sha256=ky7DsUsho_CrI18mKDvvY74aE-L29tcJiI1jwkdg89w,20683
8
+ tunnel_manager-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ tunnel_manager-1.0.1.dist-info/entry_points.txt,sha256=hYtm4jvOAew8CbeqqUBH2nXY51mSQwhF4GhU0yclV6c,154
10
+ tunnel_manager-1.0.1.dist-info/top_level.txt,sha256=W4J-lyPPNeOS696f0LneZsP2MVERR8HE9UHbAFQ550A,21
11
+ tunnel_manager-1.0.1.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ tunnel-manager = tunnel_manager.tunnel_manager:tunnel_manager
2
3
  tunnel-manager-mcp = tunnel_manager.tunnel_manager_mcp:tunnel_manager_mcp
@@ -1,190 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: tunnel-manager
3
- Version: 0.0.5
4
- Summary: Create SSH Tunnels to your remote hosts and host as an MCP Server for Agentic AI!
5
- Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
- License: MIT
7
- Classifier: Development Status :: 5 - Production/Stable
8
- Classifier: License :: Public Domain
9
- Classifier: Environment :: Console
10
- Classifier: Operating System :: POSIX :: Linux
11
- Classifier: Programming Language :: Python :: 3
12
- Requires-Python: >=3.10
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
- Requires-Dist: fastmcp>=2.11.3
16
- Requires-Dist: paramiko>=4.0.0
17
- Dynamic: license-file
18
-
19
- # Tunnel Manager
20
-
21
- ![PyPI - Version](https://img.shields.io/pypi/v/tunnel-manager)
22
- ![PyPI - Downloads](https://img.shields.io/pypi/dd/tunnel-manager)
23
- ![GitHub Repo stars](https://img.shields.io/github/stars/Knuckles-Team/tunnel-manager)
24
- ![GitHub forks](https://img.shields.io/github/forks/Knuckles-Team/tunnel-manager)
25
- ![GitHub contributors](https://img.shields.io/github/contributors/Knuckles-Team/tunnel-manager)
26
- ![PyPI - License](https://img.shields.io/pypi/l/tunnel-manager)
27
- ![GitHub](https://img.shields.io/github/license/Knuckles-Team/tunnel-manager)
28
-
29
- ![GitHub last commit (by committer)](https://img.shields.io/github/last-commit/Knuckles-Team/tunnel-manager)
30
- ![GitHub pull requests](https://img.shields.io/github/issues-pr/Knuckles-Team/tunnel-manager)
31
- ![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/Knuckles-Team/tunnel-manager)
32
- ![GitHub issues](https://img.shields.io/github/issues/Knuckles-Team/tunnel-manager)
33
-
34
- ![GitHub top language](https://img.shields.io/github/languages/top/Knuckles-Team/tunnel-manager)
35
- ![GitHub language count](https://img.shields.io/github/languages/count/Knuckles-Team/tunnel-manager)
36
- ![GitHub repo size](https://img.shields.io/github/repo-size/Knuckles-Team/tunnel-manager)
37
- ![GitHub repo file count (file type)](https://img.shields.io/github/directory-file-count/Knuckles-Team/tunnel-manager)
38
- ![PyPI - Wheel](https://img.shields.io/pypi/wheel/tunnel-manager)
39
- ![PyPI - Implementation](https://img.shields.io/pypi/implementation/tunnel-manager)
40
-
41
- *Version: 0.0.5*
42
-
43
- This project provides a Python-based `Tunnel` class for secure SSH connections and file transfers,
44
- integrated with a FastMCP server (`tunnel_mcp.py`) to expose these capabilities as tools for AI-driven workflows.
45
- The implementation supports both standard SSH (e.g., for local networks) and
46
- Teleport's secure access platform, leveraging the `paramiko` library for SSH operations.
47
-
48
- ## Features
49
-
50
- ### Tunnel Class
51
- - **Purpose**: Facilitates secure SSH connections and file transfers to remote hosts.
52
- - **Key Functionality**:
53
- - **Run Remote Commands**: Execute shell commands on a remote host and retrieve output.
54
- - **File Upload/Download**: Transfer files to/from a remote host using SFTP.
55
- - **Teleport Support**: Seamlessly integrates with Teleport's certificate-based authentication and proxying.
56
- - **Configuration Flexibility**: Loads SSH settings from `~/.ssh/config` by default, with optional overrides for identity files, certificates, and proxy commands.
57
- - **Logging**: Optional file-based logging for debugging and auditing.
58
-
59
- ### FastMCP Server
60
- - **Purpose**: Exposes `Tunnel` class functionality as a FastMCP server, enabling AI tools to perform remote operations programmatically.
61
- - **Tools Provided**:
62
- - `run_remote_command`: Runs a shell command on a remote host and returns output.
63
- - `upload_file`: Uploads a file to a remote host via SFTP.
64
- - `download_file`: Downloads a file from a remote host via SFTP.
65
- - **Transport Options**: Supports `stdio` (for local scripting) and `http` (for networked access) transport modes.
66
- - **Progress Reporting**: Integrates with FastMCP's `Context` for progress updates during operations.
67
- - **Logging**: Comprehensive logging to a file (`tunnel_mcp.log` by default).
68
-
69
-
70
- <details>
71
- <summary><b>Usage:</b></summary>
72
-
73
- ## Tunnel Class
74
- The `Tunnel` class can be used standalone for SSH operations. Example:
75
-
76
- ```python
77
- from tunnel_manager import Tunnel
78
-
79
- # Initialize with a remote host (assumes ~/.ssh/config or explicit params)
80
- tunnel = Tunnel(
81
- remote_host="example.com",
82
- identity_file="/path/to/id_rsa",
83
- certificate_file="/path/to/cert", # Optional for Teleport
84
- proxy_command="tsh proxy ssh %h", # Optional for Teleport
85
- log_file="tunnel.log"
86
- )
87
-
88
- # Connect and run a command
89
- tunnel.connect()
90
- out, err = tunnel.run_command("ls -la /tmp")
91
- print(f"Output: {out}\nError: {err}")
92
-
93
- # Upload a file
94
- tunnel.send_file("/local/file.txt", "/remote/file.txt")
95
-
96
- # Download a file
97
- tunnel.receive_file("/remote/file.txt", "/local/downloaded.txt")
98
-
99
- # Close the connection
100
- tunnel.close()
101
- ```
102
-
103
-
104
- ## FastMCP Server
105
- The FastMCP server exposes the `Tunnel` functionality as AI-accessible tools. Start the server with:
106
-
107
- ```bash
108
- python tunnel_mcp.py --transport stdio
109
- ```
110
-
111
- Or for HTTP transport:
112
- ```bash
113
- python tunnel_mcp.py --transport http --host 127.0.0.1 --port 8080
114
- ```
115
-
116
- </details>
117
-
118
- <details>
119
- <summary><b>Installation Instructions:</b></summary>
120
-
121
- ## Use with AI
122
-
123
- Configure `mcp.json`
124
- ```json
125
- {
126
- "mcpServers": {
127
- "tunnel_manager": {
128
- "command": "uv",
129
- "args": [
130
- "run",
131
- "--with",
132
- "tunnel-manager",
133
- "tunnel-manager-mcp"
134
- ],
135
- "env": {
136
- "TUNNEL_REMOTE_HOST": "user@192.168.1.12", // Optional
137
- "TUNNEL_REMOTE_PORT": "22", // Optional
138
- "TUNNEL_IDENTITY_FILE": "", // Optional
139
- "TUNNEL_CERTIFICATE": "", // Optional
140
- "TUNNEL_PROXY_COMMAND": "", // Optional
141
- "TUNNEL_LOG_FILE": "~./tunnel_log.txt" // Optional
142
- },
143
- "timeout": 200000
144
- }
145
- }
146
- }
147
- ```
148
-
149
- ### Deploy MCP Server as a container
150
- ```bash
151
- docker pull knucklessg1/tunnel-manager:latest
152
- ```
153
-
154
- Modify the `compose.yml`
155
-
156
- ```compose
157
- services:
158
- tunnel-manager:
159
- image: knucklessg1/tunnel-manager:latest
160
- environment:
161
- - HOST=0.0.0.0
162
- - PORT=8021
163
- ports:
164
- - 8021:8021
165
- ```
166
-
167
- ### Install Python Package
168
-
169
- ```bash
170
- python -m pip install tunnel-manager
171
- ```
172
-
173
- or
174
-
175
- ```bash
176
- uv pip install --upgrade tunnel-manager
177
- ```
178
-
179
-
180
- </details>
181
-
182
- <details>
183
- <summary><b>Repository Owners:</b></summary>
184
-
185
-
186
- <img width="100%" height="180em" src="https://github-readme-stats.vercel.app/api?username=Knucklessg1&show_icons=true&hide_border=true&&count_private=true&include_all_commits=true" />
187
-
188
- ![GitHub followers](https://img.shields.io/github/followers/Knucklessg1)
189
- ![GitHub User's stars](https://img.shields.io/github/stars/Knucklessg1)
190
- </details>
@@ -1,10 +0,0 @@
1
- tunnel_manager/__init__.py,sha256=9I_qajRiMP4bxiKdEIx0bKIeTg8b4x1TsYnTMfbWIJA,273
2
- tunnel_manager/__main__.py,sha256=Z1uxNLjwIjJpvu97bXrvsawnghJScA52E2wtAgg5MLo,152
3
- tunnel_manager/tunnel_manager.py,sha256=_MokYwLLe0ekQA1CeAaH_4JTRx0TctGUJLwai3MIQvc,6565
4
- tunnel_manager/tunnel_manager_mcp.py,sha256=ZYhmenIaApFBHMKDh05zxk6NffYw0yI67flt30VFDfQ,10568
5
- tunnel_manager-0.0.5.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
- tunnel_manager-0.0.5.dist-info/METADATA,sha256=yeWbqoTI2PzWJOHz0Mi9FNq2h-dOki2q2zUDsn8J2pY,6568
7
- tunnel_manager-0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- tunnel_manager-0.0.5.dist-info/entry_points.txt,sha256=mxjinmmRNDVn_VbKHi63vkSvj7pp8btUKFQeXLm4-WY,92
9
- tunnel_manager-0.0.5.dist-info/top_level.txt,sha256=AlbS1pBPQr8wIlDsmwNxGDLK4L4s4CY_X9AellT3-x8,15
10
- tunnel_manager-0.0.5.dist-info/RECORD,,