Metadata-Version: 2.4
Name: greenode-mcp-server
Version: 0.4.1
Summary: GreenNode MCP Server — AI assistant tools for all VNG Cloud products
Author: Green Node
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/vngcloud/greennode-mcp
Project-URL: Source, https://github.com/vngcloud/greennode-mcp
Project-URL: Bug Tracker, https://github.com/vngcloud/greennode-mcp/issues
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: mcp>=1.0.0
Requires-Dist: httpx<1.0,>=0.27.0
Requires-Dist: kubernetes<36.0,>=28.0.0
Requires-Dist: pyyaml<7.0,>=6.0
Requires-Dist: cachetools<6.0,>=5.3.0
Requires-Dist: pydantic<3.0,>=2.0.0
Provides-Extra: http
Requires-Dist: uvicorn>=0.30.0; extra == "http"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
Requires-Dist: respx>=0.22.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: uvicorn>=0.30.0; extra == "dev"
Dynamic: license-file

# GreenNode MCP Server

MCP (Model Context Protocol) Server for VNG Cloud. Provides AI assistants with tools to manage all VNG Cloud services from natural language.

## Key Features

- **Dynamic API Call** — Two tools (`search_api` + `call_api`) cover all VNG Cloud REST APIs
- **Live spec registry** — Specs fetched from VNG Cloud's docs portal at startup; new products appear automatically without a server release
- **Kubernetes Resources** — List pods/deployments/services, get logs, apply YAML manifests
- **Safety Controls** — Read-only by default, write operations require explicit opt-in
- **Streamable HTTP** — Remote hosting via `--transport streamable-http`

## Prerequisites

- Python 3.10 or later
- [uv](https://docs.astral.sh/uv/) package manager (recommended) or pip
- GreenNode credentials — via environment variables or credentials file

### Credential setup

**Option A: Environment variables**

```bash
export GRN_ACCESS_KEY_ID=your-client-id
export GRN_SECRET_ACCESS_KEY=your-client-secret
export GRN_DEFAULT_REGION=HCM-3
export GRN_DEFAULT_PROJECT_ID=pro-xxxxxxxx   # substituted into {projectId} paths
```

**Option B: GreenNode CLI (recommended)**

```bash
grn configure
```

The wizard auto-detects and saves your `project_id` alongside credentials:

- `~/.greenode/credentials` — `client_id`, `client_secret`
- `~/.greenode/config` — `region`, `project_id`, `output`

See [greenode-cli](https://github.com/vngcloud/greennode-cli) for install instructions.

### Profiles

Both the credentials and config files support profile sections. Select one via `GRN_PROFILE=<name>`. Each profile gets its own region and `project_id`, so switching profile switches every identity detail in one move.

## Quickstart

```bash
uvx greenode-mcp-server
```

### Claude Desktop / Cursor configuration

```json
{
  "mcpServers": {
    "greennode": {
      "command": "uvx",
      "args": ["greenode-mcp-server", "--allow-write"]
    }
  }
}
```

## Tools

### `search_api`

Search VNG Cloud API endpoints by keyword. Use this to discover which endpoint to call.

```
search_api(query="create cluster")
search_api(query="list load balancers", product="vlb")
```

### `call_api`

Execute any VNG Cloud REST API call. IAM auth token is injected automatically.

```
call_api(method="GET", path="/v1/clusters")
call_api(method="POST", path="/v1/clusters", body={"name": "my-cluster", ...})
```

**Path placeholders:** Leave `{projectId}` / `{project_id}` in the path — the server
substitutes your project UUID from `~/.greenode/config` (set by `grn configure`) or
`GRN_DEFAULT_PROJECT_ID`.

```
call_api(method="GET", path="/v2/{projectId}/networks", product="vserver")
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `method` | `str` | `GET`, `POST`, `PUT`, `PATCH`, `DELETE` |
| `path` | `str` | API path, e.g. `/v1/clusters` |
| `product` | `str?` | `vks`, `vlb`, `vserver`, ... (helps resolve the base URL) |
| `region` | `str?` | `HCM-3` or `HAN` (default: from config) |
| `params` | `dict?` | Query params (pagination is 1-based: `page=1` is first page) |
| `body` | `dict?` | JSON body for POST/PUT/PATCH |
| `raw` | `bool` | `True` returns full JSON; default formats list → markdown table (first 6 columns, top 100 rows) |

Response size is capped at 800 KB — if the API returns more, `call_api` asks you to paginate.

### Kubernetes Resource Management

Requires kubeconfig from VKS API.

| Tool | Description |
|------|-------------|
| `list_k8s_resources` | List K8s resources (Pods, Services, Deployments, etc.) |
| `get_pod_logs` | View pod logs |
| `get_k8s_events` | View resource events |
| `list_api_versions` | List available API versions |
| `manage_k8s_resource` | CRUD single K8s resource |
| `apply_yaml` | Apply YAML manifest |

## CLI Flags

| Flag | Default | Description |
|------|---------|-------------|
| `--allow-write` | `false` | Enable write operations (POST, PUT, PATCH, DELETE) |
| `--allow-sensitive-data-access` | `false` | Enable reading K8s Secrets |
| `--transport` | `stdio` | `stdio` or `streamable-http` |
| `--host` | `127.0.0.1` | Bind host for HTTP transport |
| `--port` | `8000` | Bind port for HTTP transport |
| `--api-key` | — | Bearer token for HTTP endpoint (env: `GRN_MCP_API_KEY`) |
| `--refresh-specs` | — | Bypass cached specs; force re-download from registry |
| `--offline` | — | Skip registry fetch; use cached specs only |

## Spec Registry

Specs are fetched from VNG Cloud's public docs portal at server start and cached locally at `~/.greenode/mcp-specs/`.

- **First run** requires internet access to `docs.api.vngcloud.vn`
- **Subsequent runs** reuse the cache; refresh is automatic once per 24 hours (or on `--refresh-specs`)
- **Offline mode** (`--offline`) works once the cache has been populated by at least one successful run

### Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `Cannot reach spec source` on first run | No network to `docs.api.vngcloud.vn` | Restore network; or populate cache offline from another machine |
| `search_api` returns empty for a known product | Product's docs page changed format | Run with `--refresh-specs` to re-fetch; report if persists |
| Stale spec despite product update | Cache TTL has not expired (24 h) | Run with `--refresh-specs` to force re-download |

## Supported Products

Products are sourced dynamically from the VNG Cloud docs portal — any product published there becomes available on the next server restart. At time of writing, the portal documents VKS, vServer, vLB, vDB, vMonitor and more. New products require no server release.

## Security

- **Read-only by default** — Write operations require `--allow-write`
- **Sensitive data protection** — K8s Secrets require `--allow-sensitive-data-access`
- **Path validation** — Rejects `../` and non-path strings before any HTTP call
- **Token injection** — IAM token managed by server, never exposed to AI model
- **Tokens in memory only** — Never written to disk or logged
- **HTTP auth** — Streamable HTTP protected via `--api-key` with constant-time comparison
- **Request timeout** — 30s for all HTTP requests

## License

Apache License 2.0 — see [LICENSE](LICENSE).
