Read-only Exoscale advisor MCP server — docs search plus list-only live catalogue queries, structurally incapable of mutation.
Project description
exoscale-mcp-advisor
A read-only Model Context Protocol server that lets an MCP-capable agent learn about Exoscale: search the verified connector documentation and run list-only live catalogue queries (zones, instance types, templates). It is, by construction, incapable of mutating any cloud resource.
Status: released. Seven read-only tools, the stdio server, and the four-layer test suite (structural no-mutation, mocked-connector, protocol-level, gated live smoke) are in place and green; published to PyPI as
exoscale-mcp-advisor. The full design is indocs/mcp-advisor-design.md; release history is inCHANGELOG.md.
It builds on exoscale-connector:
the knowledge it serves is read from that package's bundled reference, and the
live queries reuse the connector's read-only list clients. Nothing about
Exoscale is hardcoded or duplicated here.
General description
The advisor targets the learning path, not the execution path. An agent can
ask "what instance types exist in at-vie-1 right now?" and "how do I create a
security group with the connector?" — and get live data plus verified docs —
while the server remains structurally unable to create, change, or delete
anything. Infrastructure changes stay the human's job, performed with reviewed,
idempotent code.
Tool surface (see design §3):
| Tool | Credentials | Purpose |
|---|---|---|
search_docs(query) |
— | Ranked sections from the connector's reference bundle. |
get_asset_page(asset_type) |
— | Full reference page for one asset type. |
list_asset_types() |
— | The asset-type index (slug + heading) for discovery. |
list_zones() |
✔ | Live list of zones. |
list_instance_types(zone) |
✔ | Live list of instance types (with derived memory_gib). |
list_templates(zone, visibility) |
✔ | Live list of templates (with derived size_gib). |
list_dbaas_plans(zone=None) |
✔ | Live managed-database (DBaaS) service types and plans. |
The three docs tools need no credentials; the four live tools read Exoscale API credentials from the server's environment (see the User guide). No mutation tools — ever, by design.
User guide
The server runs with no clone or install step:
uvx exoscale-mcp-advisor
Or from a source checkout (for development):
pip install -e .
exoscale-mcp-advisor # or: python -m exoscale_mcp_advisor
It speaks MCP over stdio, so it is configured like any other stdio MCP server in your client. The four live catalogue tools require Exoscale API credentials in the server's launch environment — never on the command line, never read from a file by the app:
EXOSCALE_API_KEY=...
EXOSCALE_API_SECRET=...
EXOSCALE_ZONE=at-vie-1
Getting them into the server's environment, two common ways:
# 1) Pass them to the MCP client as it launches the server (Claude Code shown):
claude mcp add exoscale-advisor \
-e EXOSCALE_API_KEY=... -e EXOSCALE_API_SECRET=... -e EXOSCALE_ZONE=at-vie-1 \
-- uvx exoscale-mcp-advisor
# 2) Inject from a vault at launch, so no secret is typed or stored in config:
claude mcp add exoscale-advisor -- \
infisical run --domain http://localhost:8080 -- uvx exoscale-mcp-advisor
Use a least-privilege, read-only API key (see the Admin guide). The three
docs tools (search_docs, get_asset_page, list_asset_types) need no
credentials; if the live tools run without credentials they return a clear,
actionable error while the docs tools keep working. The catalogue exposes no
pricing — use Exoscale's calculator for
cost estimates.
Example use cases
What the advisor is for, from trivial to advanced. Every example is read-only: the server produces explanations and reviewable code — it never provisions, changes, or deletes anything (design D1). Each rung notes the tools it exercises and whether credentials are needed.
-
Docs lookup — no credentials. "Search the Exoscale docs for how to create a security group, then show me the full security-group reference page." →
search_docs+get_asset_page(discover slugs first withlist_asset_types). Works with zero credentials. -
A single live query — credentials. "What instance types are available in
at-vie-1right now?" or "List the public templates and their default login user." → one live tool (list_instance_types/list_templates).memory_gibandsize_gibcome pre-derived, so no manual byte math. -
Live + docs synthesis — credentials. "Compare the instance types in
at-vie-1and recommend the cheapest one suitable as an SKS worker, citing the sizing constraints." → a live tool +get_asset_page+ reasoning. The advisor cites the verified docs; it has no pricing data, so cost questions defer to Exoscale's calculator. -
Multi-asset design, read-only — credentials. "Design an HA web-app stack in
at-vie-1(load balancer + web tier + managed database), cite the docs for each asset, and don't provision anything." → manyget_asset_page(+list_dbaas_plans,list_zones) with trade-off reasoning. You get a design and citations, never a side effect. -
Reviewable code generation — credentials. "Generate an
exoscale-connectorscript that provisions the stack above, with secrets side-loaded from the environment — but I'll run it." → the advisor, not operator pattern: read-only advice plus a script you review and run. The server stays structurally unable to apply changes.
The jump from rung 1 to rung 5 is the whole point: a low-friction, credential-free entry for learning, and an aspirational ceiling where the advisor designs and writes the infrastructure code while a human keeps the keys and the final apply.
Admin guide
Least-privilege credentials (defense in depth). Although the server can only
issue list calls, the API key it runs with should also be restricted to
read-only operations, so the key itself cannot mutate anything. Build the IAM
policy with the connector's own iam_expr / IAMPolicy helpers (default-deny,
then allow only list/get catalogue operations) — see the connector's IAM
policy cookbook and design §7.
Credential injection. Credentials come from the environment, injected at
startup by a vault CLI (e.g. infisical run -- uvx exoscale-mcp-advisor in
development; a production vault agent in production). The application never reads
secrets from files and is not coupled to any specific vault provider.
Security model. Read-only is enforced on two independent layers: the code registers only read-only tools (a CI test fails the build if a mutation tool is ever added), and the credentials are scoped to read-only operations. See design §6–§7.
Developer guide
Setup
python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
Requires Python ≥3.10 (the mcp SDK floor).
Checks
ruff check src tests # lint
mypy src # type-check
pytest tests/unit -q # unit tests
The gated live smoke test (under tests/integration) talks to a real account
using only list, and is opt-in behind EXOSCALE_RUN_LIVE_TESTS=1 — default-
skipped, and never run in CI. Run it with credentials injected from the
environment (never hardcoded):
EXOSCALE_RUN_LIVE_TESTS=1 \
infisical run --domain http://localhost:8080 -- \
pytest tests/integration -q
It is read-only, so safe to run against any account.
Architecture & contribution. Read
docs/mcp-advisor-design.md first — it defines the
tool surface, the zero-duplication knowledge source, the read-only-by-
construction guarantee, and the four-layer test strategy. Conventional commits;
keep this README current with behavior changes in the same commit; no untested
code lands.
License
MIT © 2026 Raphael Lang
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file exoscale_mcp_advisor-0.2.0.tar.gz.
File metadata
- Download URL: exoscale_mcp_advisor-0.2.0.tar.gz
- Upload date:
- Size: 29.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfe4110dd4f1dcac28530c5b1b62d515a95e4f38ab34b1abe90f059773d3b368
|
|
| MD5 |
ff1cbf63298326337f8f9e4b10f41835
|
|
| BLAKE2b-256 |
0ac386906e455338f21126a2aef6ce1ac1aac9ba8e6a07e810448ef53926dafa
|
Provenance
The following attestation bundles were made for exoscale_mcp_advisor-0.2.0.tar.gz:
Publisher:
release.yml on ralle-lang/exoscale-mcp-advisor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
exoscale_mcp_advisor-0.2.0.tar.gz -
Subject digest:
bfe4110dd4f1dcac28530c5b1b62d515a95e4f38ab34b1abe90f059773d3b368 - Sigstore transparency entry: 1800156238
- Sigstore integration time:
-
Permalink:
ralle-lang/exoscale-mcp-advisor@12ea237bbf5531ab477ac722f1fba2b071a2bce2 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ralle-lang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@12ea237bbf5531ab477ac722f1fba2b071a2bce2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file exoscale_mcp_advisor-0.2.0-py3-none-any.whl.
File metadata
- Download URL: exoscale_mcp_advisor-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d997306f98a7edb4d4071ee139cdb03d61169bc9ff193bdd6fbbcc2c58c3fbd7
|
|
| MD5 |
2aa715bcb730b17d1a8e802cef8be218
|
|
| BLAKE2b-256 |
679d5945e4df932766253fcdf96903b2446dc88d66b862c0d4ecf0164ea49937
|
Provenance
The following attestation bundles were made for exoscale_mcp_advisor-0.2.0-py3-none-any.whl:
Publisher:
release.yml on ralle-lang/exoscale-mcp-advisor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
exoscale_mcp_advisor-0.2.0-py3-none-any.whl -
Subject digest:
d997306f98a7edb4d4071ee139cdb03d61169bc9ff193bdd6fbbcc2c58c3fbd7 - Sigstore transparency entry: 1800156355
- Sigstore integration time:
-
Permalink:
ralle-lang/exoscale-mcp-advisor@12ea237bbf5531ab477ac722f1fba2b071a2bce2 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ralle-lang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@12ea237bbf5531ab477ac722f1fba2b071a2bce2 -
Trigger Event:
release
-
Statement type: