Mcpnertes
Read-only Kubernetes MCP server. Every tool is GET/LIST-only, and every tool
passes through a config-driven policy (config.toml) before it touches the
cluster:
- Namespace allowlist —
namespaces.allowdefaults to["*"](every namespace). Restrict it to an explicit list to scope the server to specific namespaces, and usenamespaces.denyto carve out exceptions. - Resource blocklist —
resources.blockdefaults to["Secret"]. Blocked kinds are refused by every tool, including the genericlist_resource/get_resourcedynamic-client tools, so there's no way to route around the block by asking a different tool.
Both checks happen in a single chokepoint (mcpnertes.config.Policy) before
any Kubernetes API call is made — see src/mcpnertes/config.py.
Install
pip install -e .
Run standalone
mcpnertes
Use from an MCP client (Claude Desktop, Claude Code, etc.)
Add to the client's MCP server config. The policy (namespace allow/deny,
resource block) is set directly in env — no config.toml file needed.
Once published to PyPI, uvx will fetch and run it without a local install:
{
"mcpServers": {
"mcpnertes": {
"command": "uvx",
"args": ["mcpnertes@latest"],
"env": {
"MCPNERTES_NAMESPACE_ALLOW": "*",
"MCPNERTES_NAMESPACE_DENY": "kube-system,cert-manager",
"MCPNERTES_RESOURCE_BLOCK": "Secret"
}
}
}
}
All three env vars are optional and comma-separated. Omit any of them to
fall back to config.toml (if present) or the built-in default (allow all
namespaces, block Secret).
Not yet on PyPI? Point uvx at this checkout instead:
{
"mcpServers": {
"mcpnertes": {
"command": "uvx",
"args": ["--from", "/absolute/path/to/Mcpnertes", "mcpnertes"],
"env": {
"MCPNERTES_NAMESPACE_ALLOW": "*",
"MCPNERTES_NAMESPACE_DENY": "kube-system,cert-manager",
"MCPNERTES_RESOURCE_BLOCK": "Secret"
}
}
}
}
Configuring the policy
Two equivalent ways to set it — pick whichever fits how you're running the server. If both are present, the env vars win field-by-field.
Env vars (for mcpServers configs — no file needed)
| Variable | Format | Default |
|---|---|---|
MCPNERTES_NAMESPACE_ALLOW |
comma-separated, * = all |
* |
MCPNERTES_NAMESPACE_DENY |
comma-separated | (empty) |
MCPNERTES_RESOURCE_BLOCK |
comma-separated, case-insensitive | Secret |
"env": {
"MCPNERTES_NAMESPACE_ALLOW": "default,staging",
"MCPNERTES_NAMESPACE_DENY": "",
"MCPNERTES_RESOURCE_BLOCK": "Secret,ConfigMap,Ingress"
}
config.toml (for standalone runs)
Resolution order (first match wins): $MCPNERTES_CONFIG, ./config.toml
(current working directory), then the config.toml shipped next to the
installed package.
[namespaces]
# "*" = every namespace (default). Replace with an explicit list to scope
# the server to only those namespaces.
allow = ["*"]
# Namespaces to block even if matched by `allow`. `deny` always wins.
deny = []
[resources]
# Resource kinds always refused, regardless of which tool is called
# (including the generic list_resource/get_resource tools). Case-insensitive.
block = ["Secret"]
Scope to specific namespaces:
[namespaces]
allow = ["default", "staging"]
deny = []
Allow everything except a couple of sensitive namespaces:
[namespaces]
allow = ["*"]
deny = ["kube-system", "cert-manager"]
Block additional resource kinds (e.g. also hide ConfigMaps and Ingresses):
[resources]
block = ["Secret", "ConfigMap", "Ingress"]
Tools
| Tool | Description |
|---|---|
list_pods |
List pods in a namespace or across all namespaces |
list_deployments |
List deployments in a namespace or across all namespaces |
get_pod_logs |
Get logs from a specific pod |
list_services |
List services in a namespace or across all namespaces |
list_namespaces |
List namespaces (filtered by the allowlist) |
get_events |
Get cluster events for a namespace or all namespaces |
get_logs |
Get logs from a pod/deployment/job/label selector |
list_nodes |
List cluster nodes |
list_resource |
List any resource kind (including CRDs) via the dynamic client |
get_resource |
Get a single resource of any kind by name |
list_api_resources |
Discover listable resource kinds the cluster exposes |
Testing
pip install -e ".[dev]"
pytest -q
tests/test_config.py unit-tests the Policy allow/deny/block logic in
isolation. tests/test_e2e.py and tests/test_e2e_stdio.py are full
end-to-end tests with no mocks: they seed a real namespace/pod/deployment
/service/secret on whatever cluster your current kubeconfig context points
to, then drive the actual MCP server (in-process and as a real stdio
subprocess) against it. They auto-skip if no cluster is reachable.
License
Apache-2.0 — see LICENSE.
Release files for mcpnertes 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcpnertes-0.1.0.tar.gz | 19.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcpnertes-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.8 kB
Release files / mcpnertes-0.1.0.tar.gz
| Download URL | mcpnertes-0.1.0.tar.gz |
|---|---|
| Size | 19.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
71c59390e3231d2132d5149d8406726ce9c499a208139e4fe682cbd10271f1ac
|
|
BLAKE2b-256 checksum How to use checksums |
aff9ff24ec5199b4f277d6fc5619c3b62c2c0d7ddacb691ebeb9ccaa13472baf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency logRelease files / mcpnertes-0.1.0-py3-none-any.whl
| Download URL | mcpnertes-0.1.0-py3-none-any.whl |
|---|---|
| Size | 25.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
df4b69733fec256eedeacdddb76675a47098ee983b70de9029c6391ad2136d6d
|
|
BLAKE2b-256 checksum How to use checksums |
784c1396fc7f009d627f90d286fe60b1b87cca2144ea3ced78accbecc6bd3bc1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency log