chore: mcp-proxmox README and index updates
Made-with: Cursor
This commit is contained in:
@@ -80,7 +80,7 @@ Before starting, ensure you have:
|
||||
3. Add your Proxmox configuration to `.env`:
|
||||
```bash
|
||||
# Proxmox Configuration (REQUIRED)
|
||||
PROXMOX_HOST=your-proxmox-ip-or-hostname
|
||||
PROXMOX_HOST=proxmox-api.d-bis.org
|
||||
PROXMOX_USER=root@pam
|
||||
PROXMOX_TOKEN_NAME=your-token-name
|
||||
PROXMOX_TOKEN_VALUE=your-token-secret-here
|
||||
@@ -101,6 +101,7 @@ Before starting, ensure you have:
|
||||
- `PROXMOX_TOKEN_VALUE` is REQUIRED - there is no default value
|
||||
- `PROXMOX_HOST` defaults to `192.168.6.247` if not specified (change this!)
|
||||
- `PROXMOX_TOKEN_NAME` defaults to `mcpserver` if not specified
|
||||
- `PROXMOX_TOKEN_NAME` may be either the bare token name or the full token id (`user@realm!token-name`); the server handles both
|
||||
|
||||
**⚠️ Security Warning**:
|
||||
- `PROXMOX_ALLOW_ELEVATED=false` is the SAFE default - only read operations allowed
|
||||
@@ -164,9 +165,11 @@ Before starting, ensure you have:
|
||||
- **Privilege Separation**: Uncheck for full access or leave checked for limited permissions
|
||||
- Click **Add**
|
||||
4. **Important**: Copy both the **Token ID** and **Secret** immediately (secret is only shown once)
|
||||
- Use Token ID as `PROXMOX_TOKEN_NAME`
|
||||
- Use the bare Token ID as `PROXMOX_TOKEN_NAME`
|
||||
- Use Secret as `PROXMOX_TOKEN_VALUE`
|
||||
|
||||
If your secret store already holds the full token id (for example `root@pam!mcp-server`) in `PROXMOX_TOKEN_NAME`, the server will normalize it automatically.
|
||||
|
||||
**Permission Requirements:**
|
||||
- **Basic Mode**: Minimal permissions (usually default user permissions work)
|
||||
- **Elevated Mode**: Add permissions for `Sys.Audit`, `VM.Monitor`, `VM.Console` to the user/token
|
||||
|
||||
15
index.js
15
index.js
@@ -48,6 +48,13 @@ if (!loadEnvFile(envPath)) {
|
||||
}
|
||||
}
|
||||
|
||||
function formatProxmoxAuthHeader(user, tokenName, tokenValue) {
|
||||
if (tokenName.includes('!')) {
|
||||
return `PVEAPIToken=${tokenName}=${tokenValue}`;
|
||||
}
|
||||
return `PVEAPIToken=${user}!${tokenName}=${tokenValue}`;
|
||||
}
|
||||
|
||||
class ProxmoxServer {
|
||||
constructor() {
|
||||
this.server = new Server(
|
||||
@@ -139,7 +146,11 @@ class ProxmoxServer {
|
||||
const url = `${baseUrl}${endpoint}`;
|
||||
|
||||
const headers = {
|
||||
'Authorization': `PVEAPIToken=${this.proxmoxUser}!${this.proxmoxTokenName}=${this.proxmoxTokenValue}`,
|
||||
'Authorization': formatProxmoxAuthHeader(
|
||||
this.proxmoxUser,
|
||||
this.proxmoxTokenName,
|
||||
this.proxmoxTokenValue
|
||||
),
|
||||
'Content-Type': 'application/json'
|
||||
};
|
||||
|
||||
@@ -3159,4 +3170,4 @@ class ProxmoxServer {
|
||||
}
|
||||
|
||||
const server = new ProxmoxServer();
|
||||
server.run().catch(console.error);
|
||||
server.run().catch(console.error);
|
||||
|
||||
@@ -13,6 +13,27 @@ class ProxmoxAuth(BaseModel):
|
||||
token_name: str
|
||||
token_value: str
|
||||
|
||||
|
||||
def normalize_token_name(user: str, token_name: str) -> str:
|
||||
"""
|
||||
Normalize a Proxmox token identifier to the bare token name.
|
||||
|
||||
Accepts either:
|
||||
- bare token name: ``devin-codex``
|
||||
- full token id: ``user@realm!devin-codex``
|
||||
"""
|
||||
if "!" not in token_name:
|
||||
return token_name
|
||||
|
||||
token_user, bare_token_name = token_name.split("!", 1)
|
||||
if not bare_token_name:
|
||||
raise ValueError("Invalid PROXMOX_TOKEN_NAME: token id is missing the token name after '!'")
|
||||
if token_user != user:
|
||||
raise ValueError(
|
||||
"PROXMOX_TOKEN_NAME contains a full token id for a different user than PROXMOX_USER"
|
||||
)
|
||||
return bare_token_name
|
||||
|
||||
def load_auth_from_env() -> ProxmoxAuth:
|
||||
"""
|
||||
Load Proxmox authentication details from environment variables.
|
||||
@@ -44,7 +65,7 @@ def load_auth_from_env() -> ProxmoxAuth:
|
||||
|
||||
return ProxmoxAuth(
|
||||
user=user,
|
||||
token_name=token_name,
|
||||
token_name=normalize_token_name(user, token_name),
|
||||
token_value=token_value,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user