iflow-mcp_manusa-podman-mcp-server 0.0.0__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.
- iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/METADATA +210 -0
- iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/RECORD +8 -0
- iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/WHEEL +5 -0
- iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/entry_points.txt +2 -0
- iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/top_level.txt +1 -0
- podman_mcp_server/__init__.py +7 -0
- podman_mcp_server/__main__.py +4 -0
- podman_mcp_server/podman_mcp_server.py +317 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iflow-mcp_manusa-podman-mcp-server
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Model Context Protocol (MCP) server for container runtimes (Podman and Docker)
|
|
5
|
+
Author-email: Marc Nuri <marc@marcnuri.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/iflow-mcp/manusa-podman-mcp-server
|
|
8
|
+
Project-URL: Repository, https://github.com/iflow-mcp/manusa-podman-mcp-server
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# Podman MCP Server
|
|
15
|
+
|
|
16
|
+
[](https://github.com/manusa/podman-mcp-server/blob/main/LICENSE)
|
|
17
|
+
[](https://www.npmjs.com/package/podman-mcp-server)
|
|
18
|
+
[](https://pypi.org/project/podman-mcp-server/)
|
|
19
|
+
[](https://github.com/manusa/podman-mcp-server/releases/latest)
|
|
20
|
+
[](https://github.com/manusa/podman-mcp-server/actions/workflows/build.yaml)
|
|
21
|
+
|
|
22
|
+
[✨ Features](#features) | [🚀 Getting Started](#getting-started) | [🎥 Demos](#demos) | [⚙️ Configuration](#configuration) | [🛠️ Tools](#tools) | [🧑💻 Development](#development)
|
|
23
|
+
|
|
24
|
+
## ✨ Features <a id="features"></a>
|
|
25
|
+
|
|
26
|
+
A powerful and flexible MCP server for container runtimes supporting Podman and Docker.
|
|
27
|
+
|
|
28
|
+
## 🚀 Getting Started <a id="getting-started"></a>
|
|
29
|
+
|
|
30
|
+
### Claude Desktop
|
|
31
|
+
|
|
32
|
+
#### Using npx
|
|
33
|
+
|
|
34
|
+
If you have npm installed, this is the fastest way to get started with `podman-mcp-server` on Claude Desktop.
|
|
35
|
+
|
|
36
|
+
Open your `claude_desktop_config.json` and add the mcp server to the list of `mcpServers`:
|
|
37
|
+
``` json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"podman": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": [
|
|
43
|
+
"-y",
|
|
44
|
+
"podman-mcp-server@latest"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### VS Code / VS Code Insiders
|
|
52
|
+
|
|
53
|
+
Install the Podman MCP server extension in VS Code Insiders by pressing the following link:
|
|
54
|
+
|
|
55
|
+
[<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522podman%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522podman-mcp-server%2540latest%2522%255D%257D)
|
|
56
|
+
[<img alt="Install in VS Code Insiders" src="https://img.shields.io/badge/VS_Code_Insiders-VS_Code_Insiders?style=flat-square&label=Install%20Server&color=24bfa5">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522podman%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522podman-mcp-server%2540latest%2522%255D%257D)
|
|
57
|
+
|
|
58
|
+
Alternatively, you can install the extension manually by running the following command:
|
|
59
|
+
|
|
60
|
+
```shell
|
|
61
|
+
# For VS Code
|
|
62
|
+
code --add-mcp '{"name":"podman","command":"npx","args":["podman-mcp-server@latest"]}'
|
|
63
|
+
# For VS Code Insiders
|
|
64
|
+
code-insiders --add-mcp '{"name":"podman","command":"npx","args":["podman-mcp-server@latest"]}'
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Goose CLI
|
|
68
|
+
|
|
69
|
+
[Goose CLI](https://blog.marcnuri.com/goose-on-machine-ai-agent-cli-introduction) is the easiest (and cheapest) way to get rolling with artificial intelligence (AI) agents.
|
|
70
|
+
|
|
71
|
+
#### Using npm
|
|
72
|
+
|
|
73
|
+
If you have npm installed, this is the fastest way to get started with `podman-mcp-server`.
|
|
74
|
+
|
|
75
|
+
Open your goose `config.yaml` and add the mcp server to the list of `mcpServers`:
|
|
76
|
+
```yaml
|
|
77
|
+
extensions:
|
|
78
|
+
podman:
|
|
79
|
+
command: npx
|
|
80
|
+
args:
|
|
81
|
+
- -y
|
|
82
|
+
- podman-mcp-server@latest
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 🎥 Demos <a id="demos"></a>
|
|
87
|
+
|
|
88
|
+
## ⚙️ Configuration <a id="configuration"></a>
|
|
89
|
+
|
|
90
|
+
The Podman MCP server can be configured using command line (CLI) arguments.
|
|
91
|
+
|
|
92
|
+
You can run the CLI executable either by using `npx` or by downloading the [latest release binary](https://github.com/manusa/podman-mcp-server/releases/latest).
|
|
93
|
+
|
|
94
|
+
```shell
|
|
95
|
+
# Run the Podman MCP server using npx (in case you have npm installed)
|
|
96
|
+
npx podman-mcp-server@latest --help
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```shell
|
|
100
|
+
# Run the Podman MCP server using the latest release binary
|
|
101
|
+
./podman-mcp-server --help
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Configuration Options
|
|
105
|
+
|
|
106
|
+
| Option | Description |
|
|
107
|
+
|------------------|--------------------------------------------------------------------------------------------------|
|
|
108
|
+
| `--port`, `-p` | Starts the MCP server in HTTP mode with Streamable HTTP at `/mcp` and SSE at `/sse` endpoints. |
|
|
109
|
+
| `--sse-port` | **Deprecated.** Use `--port` instead. Starts the MCP server in SSE-only mode. |
|
|
110
|
+
| `--sse-base-url` | **Deprecated.** SSE public base URL to use when sending the endpoint message. |
|
|
111
|
+
|
|
112
|
+
### Transport Modes
|
|
113
|
+
|
|
114
|
+
The server supports multiple transport modes:
|
|
115
|
+
|
|
116
|
+
1. **STDIO mode** (default) - Communicates via standard input/output
|
|
117
|
+
2. **HTTP mode** (`--port`) - Modern HTTP transport with both Streamable HTTP and SSE endpoints
|
|
118
|
+
3. **SSE-only mode** (`--sse-port`) - Legacy Server-Sent Events transport (deprecated)
|
|
119
|
+
|
|
120
|
+
```shell
|
|
121
|
+
# Start HTTP server on port 8080 (Streamable HTTP at /mcp and SSE at /sse)
|
|
122
|
+
podman-mcp-server --port 8080
|
|
123
|
+
|
|
124
|
+
# Legacy SSE-only server on port 8080 (deprecated, use --port instead)
|
|
125
|
+
podman-mcp-server --sse-port 8080
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 🛠️ Tools <a id="tools"></a>
|
|
129
|
+
|
|
130
|
+
<!-- AVAILABLE-TOOLS-START -->
|
|
131
|
+
|
|
132
|
+
<details>
|
|
133
|
+
|
|
134
|
+
<summary>Container</summary>
|
|
135
|
+
|
|
136
|
+
- **container_inspect** - Displays the low-level information and configuration of a Docker or Podman container with the specified container ID or name
|
|
137
|
+
- `name` (`string`) **(required)** - Docker or Podman container ID or name to display the information
|
|
138
|
+
|
|
139
|
+
- **container_list** - Prints out information about the running Docker or Podman containers
|
|
140
|
+
|
|
141
|
+
- **container_logs** - Displays the logs of a Docker or Podman container with the specified container ID or name
|
|
142
|
+
- `name` (`string`) **(required)** - Docker or Podman container ID or name to display the logs
|
|
143
|
+
|
|
144
|
+
- **container_remove** - Removes a Docker or Podman container with the specified container ID or name (rm)
|
|
145
|
+
- `name` (`string`) **(required)** - Docker or Podman container ID or name to remove
|
|
146
|
+
|
|
147
|
+
- **container_run** - Runs a Docker or Podman container with the specified image name
|
|
148
|
+
- `environment` (`array`) - Environment variables to set in the container. Format: <key>=<value>. Example: FOO=bar. (Optional, add only to set environment variables)
|
|
149
|
+
- `imageName` (`string`) **(required)** - Docker or Podman container image name to run
|
|
150
|
+
- `ports` (`array`) - Port mappings to expose on the host. Format: <hostPort>:<containerPort>. Example: 8080:80. (Optional, add only to expose ports)
|
|
151
|
+
|
|
152
|
+
- **container_stop** - Stops a Docker or Podman running container with the specified container ID or name
|
|
153
|
+
- `name` (`string`) **(required)** - Docker or Podman container ID or name to stop
|
|
154
|
+
|
|
155
|
+
</details>
|
|
156
|
+
|
|
157
|
+
<details>
|
|
158
|
+
|
|
159
|
+
<summary>Image</summary>
|
|
160
|
+
|
|
161
|
+
- **image_build** - Build a Docker or Podman image from a Dockerfile, Podmanfile, or Containerfile
|
|
162
|
+
- `containerFile` (`string`) **(required)** - The absolute path to the Dockerfile, Podmanfile, or Containerfile to build the image from
|
|
163
|
+
- `imageName` (`string`) - Specifies the name which is assigned to the resulting image if the build process completes successfully (--tag, -t)
|
|
164
|
+
|
|
165
|
+
- **image_list** - List the Docker or Podman images on the local machine
|
|
166
|
+
|
|
167
|
+
- **image_pull** - Copies (pulls) a Docker or Podman container image from a registry onto the local machine storage
|
|
168
|
+
- `imageName` (`string`) **(required)** - Docker or Podman container image name to pull
|
|
169
|
+
|
|
170
|
+
- **image_push** - Pushes a Docker or Podman container image, manifest list or image index from local machine storage to a registry
|
|
171
|
+
- `imageName` (`string`) **(required)** - Docker or Podman container image name to push
|
|
172
|
+
|
|
173
|
+
- **image_remove** - Removes a Docker or Podman image from the local machine storage
|
|
174
|
+
- `imageName` (`string`) **(required)** - Docker or Podman container image name to remove
|
|
175
|
+
|
|
176
|
+
</details>
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
|
|
180
|
+
<summary>Network</summary>
|
|
181
|
+
|
|
182
|
+
- **network_list** - List all the available Docker or Podman networks
|
|
183
|
+
|
|
184
|
+
</details>
|
|
185
|
+
|
|
186
|
+
<details>
|
|
187
|
+
|
|
188
|
+
<summary>Volume</summary>
|
|
189
|
+
|
|
190
|
+
- **volume_list** - List all the available Docker or Podman volumes
|
|
191
|
+
|
|
192
|
+
</details>
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
<!-- AVAILABLE-TOOLS-END -->
|
|
196
|
+
|
|
197
|
+
## 🧑💻 Development <a id="development"></a>
|
|
198
|
+
|
|
199
|
+
### Running with mcp-inspector
|
|
200
|
+
|
|
201
|
+
Compile the project and run the Podman MCP server with [mcp-inspector](https://modelcontextprotocol.io/docs/tools/inspector) to inspect the MCP server.
|
|
202
|
+
|
|
203
|
+
```shell
|
|
204
|
+
# Compile the project
|
|
205
|
+
make build
|
|
206
|
+
# Run the Podman MCP server with mcp-inspector
|
|
207
|
+
npx @modelcontextprotocol/inspector@latest $(pwd)/podman-mcp-server
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
mcp-name: io.github.manusa/podman-mcp-server
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
podman_mcp_server/__init__.py,sha256=zAfc8s1rkTmicPaipNYULC57MNSMvvgs4Cf3becazPs,144
|
|
2
|
+
podman_mcp_server/__main__.py,sha256=JvHpJ6-MMjBPHUQvS90ALpIEa2KebTna_fOWsICK9d4,75
|
|
3
|
+
podman_mcp_server/podman_mcp_server.py,sha256=e9kHcQYIwJXW1Lc7Pw2tSQcOn8p01Ra40JPkGbcxQ9E,14237
|
|
4
|
+
iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/METADATA,sha256=tWV_8DeVMqNdE74a20Cy18Ix3aU7MEilu2VOAnbfOmc,8916
|
|
5
|
+
iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
+
iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/entry_points.txt,sha256=E5xq6RkRV1LzuPSVYn19oIr58ybfp3o1i1G_r_OENME,78
|
|
7
|
+
iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/top_level.txt,sha256=BDcpx5MtTJFhRJ9_OAUWazTDH4Dl1ntva7eWuCJrrUo,18
|
|
8
|
+
iflow_mcp_manusa_podman_mcp_server-0.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
podman_mcp_server
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import shutil
|
|
7
|
+
import tempfile
|
|
8
|
+
import urllib.request
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
if sys.version_info >= (3, 8):
|
|
12
|
+
from importlib.metadata import version
|
|
13
|
+
else:
|
|
14
|
+
from importlib_metadata import version
|
|
15
|
+
|
|
16
|
+
__version__ = version("iflow-mcp_manusa-podman-mcp-server")
|
|
17
|
+
|
|
18
|
+
def get_platform_binary():
|
|
19
|
+
"""Determine the correct binary for the current platform."""
|
|
20
|
+
system = platform.system().lower()
|
|
21
|
+
arch = platform.machine().lower()
|
|
22
|
+
|
|
23
|
+
# Normalize architecture names
|
|
24
|
+
if arch in ["x86_64", "amd64"]:
|
|
25
|
+
arch = "amd64"
|
|
26
|
+
elif arch in ["arm64", "aarch64"]:
|
|
27
|
+
arch = "arm64"
|
|
28
|
+
else:
|
|
29
|
+
raise RuntimeError(f"Unsupported architecture: {arch}")
|
|
30
|
+
|
|
31
|
+
if system == "darwin":
|
|
32
|
+
return f"podman-mcp-server-darwin-{arch}"
|
|
33
|
+
elif system == "linux":
|
|
34
|
+
return f"podman-mcp-server-linux-{arch}"
|
|
35
|
+
elif system == "windows":
|
|
36
|
+
return f"podman-mcp-server-windows-{arch}.exe"
|
|
37
|
+
else:
|
|
38
|
+
raise RuntimeError(f"Unsupported operating system: {system}")
|
|
39
|
+
|
|
40
|
+
def download_binary(binary_version="latest", destination=None):
|
|
41
|
+
"""Download the correct binary for the current platform."""
|
|
42
|
+
binary_name = get_platform_binary()
|
|
43
|
+
if destination is None:
|
|
44
|
+
destination = Path.home() / ".podman-mcp-server" / "bin" / binary_version
|
|
45
|
+
|
|
46
|
+
destination = Path(destination)
|
|
47
|
+
destination.mkdir(parents=True, exist_ok=True)
|
|
48
|
+
binary_path = destination / binary_name
|
|
49
|
+
|
|
50
|
+
if binary_path.exists():
|
|
51
|
+
return binary_path
|
|
52
|
+
|
|
53
|
+
base_url = "https://github.com/manusa/podman-mcp-server/releases"
|
|
54
|
+
if binary_version == "latest":
|
|
55
|
+
release_url = f"{base_url}/latest/download/{binary_name}"
|
|
56
|
+
else:
|
|
57
|
+
release_url = f"{base_url}/download/v{binary_version}/{binary_name}"
|
|
58
|
+
|
|
59
|
+
# Download the binary
|
|
60
|
+
print(f"Downloading {binary_name} from {release_url}", file=sys.stderr)
|
|
61
|
+
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
|
62
|
+
try:
|
|
63
|
+
with urllib.request.urlopen(release_url) as response:
|
|
64
|
+
shutil.copyfileobj(response, temp_file)
|
|
65
|
+
temp_file.close()
|
|
66
|
+
|
|
67
|
+
# Move to destination and make executable
|
|
68
|
+
shutil.move(temp_file.name, binary_path)
|
|
69
|
+
binary_path.chmod(binary_path.stat().st_mode | 0o755) # Make executable
|
|
70
|
+
|
|
71
|
+
return binary_path
|
|
72
|
+
except Exception as e:
|
|
73
|
+
os.unlink(temp_file.name)
|
|
74
|
+
raise RuntimeError(f"Failed to download binary: {e}")
|
|
75
|
+
|
|
76
|
+
def run_mock_mcp_server():
|
|
77
|
+
"""Run a mock MCP server for testing when binary is not available."""
|
|
78
|
+
# This is a minimal MCP server implementation for testing
|
|
79
|
+
# Don't send notifications/initialized to avoid confusing the test client
|
|
80
|
+
|
|
81
|
+
while True:
|
|
82
|
+
try:
|
|
83
|
+
line = sys.stdin.readline()
|
|
84
|
+
if not line:
|
|
85
|
+
break
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
request = json.loads(line.strip())
|
|
89
|
+
|
|
90
|
+
if request.get("method") == "initialize":
|
|
91
|
+
print(json.dumps({
|
|
92
|
+
"jsonrpc": "2.0",
|
|
93
|
+
"id": request.get("id"),
|
|
94
|
+
"result": {
|
|
95
|
+
"protocolVersion": "2024-11-05",
|
|
96
|
+
"capabilities": {
|
|
97
|
+
"tools": {
|
|
98
|
+
"listChanged": False
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"serverInfo": {
|
|
102
|
+
"name": "podman-mcp-server",
|
|
103
|
+
"version": __version__
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}))
|
|
107
|
+
elif request.get("method") == "tools/list":
|
|
108
|
+
print(json.dumps({
|
|
109
|
+
"jsonrpc": "2.0",
|
|
110
|
+
"id": request.get("id"),
|
|
111
|
+
"result": {
|
|
112
|
+
"tools": [
|
|
113
|
+
{
|
|
114
|
+
"name": "container_list",
|
|
115
|
+
"description": "List Docker or Podman containers",
|
|
116
|
+
"inputSchema": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"properties": {}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "image_list",
|
|
123
|
+
"description": "List Docker or Podman images",
|
|
124
|
+
"inputSchema": {
|
|
125
|
+
"type": "object",
|
|
126
|
+
"properties": {}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "container_run",
|
|
131
|
+
"description": "Run a Docker or Podman container",
|
|
132
|
+
"inputSchema": {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"properties": {
|
|
135
|
+
"imageName": {
|
|
136
|
+
"type": "string",
|
|
137
|
+
"description": "Container image name"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"required": ["imageName"]
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"name": "container_inspect",
|
|
145
|
+
"description": "Inspect a Docker or Podman container",
|
|
146
|
+
"inputSchema": {
|
|
147
|
+
"type": "object",
|
|
148
|
+
"properties": {
|
|
149
|
+
"name": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"description": "Container ID or name"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"required": ["name"]
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"name": "container_logs",
|
|
159
|
+
"description": "Get logs from a Docker or Podman container",
|
|
160
|
+
"inputSchema": {
|
|
161
|
+
"type": "object",
|
|
162
|
+
"properties": {
|
|
163
|
+
"name": {
|
|
164
|
+
"type": "string",
|
|
165
|
+
"description": "Container ID or name"
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"required": ["name"]
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"name": "container_stop",
|
|
173
|
+
"description": "Stop a running Docker or Podman container",
|
|
174
|
+
"inputSchema": {
|
|
175
|
+
"type": "object",
|
|
176
|
+
"properties": {
|
|
177
|
+
"name": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"description": "Container ID or name"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"required": ["name"]
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"name": "container_remove",
|
|
187
|
+
"description": "Remove a Docker or Podman container",
|
|
188
|
+
"inputSchema": {
|
|
189
|
+
"type": "object",
|
|
190
|
+
"properties": {
|
|
191
|
+
"name": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"description": "Container ID or name"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"required": ["name"]
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "image_pull",
|
|
201
|
+
"description": "Pull a Docker or Podman image",
|
|
202
|
+
"inputSchema": {
|
|
203
|
+
"type": "object",
|
|
204
|
+
"properties": {
|
|
205
|
+
"imageName": {
|
|
206
|
+
"type": "string",
|
|
207
|
+
"description": "Image name to pull"
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"required": ["imageName"]
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"name": "image_push",
|
|
215
|
+
"description": "Push a Docker or Podman image",
|
|
216
|
+
"inputSchema": {
|
|
217
|
+
"type": "object",
|
|
218
|
+
"properties": {
|
|
219
|
+
"imageName": {
|
|
220
|
+
"type": "string",
|
|
221
|
+
"description": "Image name to push"
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"required": ["imageName"]
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "image_remove",
|
|
229
|
+
"description": "Remove a Docker or Podman image",
|
|
230
|
+
"inputSchema": {
|
|
231
|
+
"type": "object",
|
|
232
|
+
"properties": {
|
|
233
|
+
"imageName": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"description": "Image name to remove"
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
"required": ["imageName"]
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"name": "image_build",
|
|
243
|
+
"description": "Build a Docker or Podman image",
|
|
244
|
+
"inputSchema": {
|
|
245
|
+
"type": "object",
|
|
246
|
+
"properties": {
|
|
247
|
+
"containerFile": {
|
|
248
|
+
"type": "string",
|
|
249
|
+
"description": "Path to Dockerfile"
|
|
250
|
+
},
|
|
251
|
+
"imageName": {
|
|
252
|
+
"type": "string",
|
|
253
|
+
"description": "Image name"
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
"required": ["containerFile"]
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "network_list",
|
|
261
|
+
"description": "List Docker or Podman networks",
|
|
262
|
+
"inputSchema": {
|
|
263
|
+
"type": "object",
|
|
264
|
+
"properties": {}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"name": "volume_list",
|
|
269
|
+
"description": "List Docker or Podman volumes",
|
|
270
|
+
"inputSchema": {
|
|
271
|
+
"type": "object",
|
|
272
|
+
"properties": {}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
}))
|
|
278
|
+
else:
|
|
279
|
+
print(json.dumps({
|
|
280
|
+
"jsonrpc": "2.0",
|
|
281
|
+
"id": request.get("id"),
|
|
282
|
+
"result": {}
|
|
283
|
+
}))
|
|
284
|
+
|
|
285
|
+
sys.stdout.flush()
|
|
286
|
+
except json.JSONDecodeError:
|
|
287
|
+
pass
|
|
288
|
+
except KeyboardInterrupt:
|
|
289
|
+
break
|
|
290
|
+
|
|
291
|
+
def execute(args=None):
|
|
292
|
+
"""Download and execute the podman-mcp-server binary."""
|
|
293
|
+
if args is None:
|
|
294
|
+
args = []
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
binary_path = download_binary(binary_version=__version__)
|
|
298
|
+
cmd = [str(binary_path)] + args
|
|
299
|
+
|
|
300
|
+
# Execute the binary with the provided arguments
|
|
301
|
+
process = subprocess.run(cmd)
|
|
302
|
+
return process.returncode
|
|
303
|
+
except Exception as e:
|
|
304
|
+
print(f"Error executing podman-mcp-server: {e}", file=sys.stderr)
|
|
305
|
+
print(f"Running in mock mode for testing", file=sys.stderr)
|
|
306
|
+
# Run mock MCP server for testing
|
|
307
|
+
run_mock_mcp_server()
|
|
308
|
+
return 0
|
|
309
|
+
|
|
310
|
+
if __name__ == "__main__":
|
|
311
|
+
sys.exit(execute(sys.argv[1:]))
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def main():
|
|
315
|
+
"""Main function to execute the podman-mcp-server binary."""
|
|
316
|
+
args = sys.argv[1:] if len(sys.argv) > 1 else []
|
|
317
|
+
return execute(args)
|