Quick start with a desktop client¶
3.1 Try it in a terminal first¶
Before wiring a client, check that the layer loads your data. --dataset takes
NAME=PATH or a bare PATH, where the path is an inventory-map.json, its directory, a findings.json
report or native scanner output.
{
"active_dataset": "prod",
"datasets": [
{
"name": "prod",
"kind": "inventory",
"source": ".../docest/inventory/inventory-map.json",
"loaded_at": "2026-10-08T14:11:27+00:00",
"version": 0,
"providers": ["aws", "azure", "gcp"],
"assets": 44,
"edges": 56,
"findings": 12,
"compliance_results": 8,
"cached": {"graph": false, "dependency_graph": false, "ontology": false,
"centrality": false, "rag_entity": false}
}
],
"allowed_roots": [".../docest", ".../docest/reports"],
"output_dir": ".../docest/reports",
"providers_configured": ["aws"]
}
(Reformatted: the real output prints one value per line.) A second call with arguments:
cloudg mcp call find_assets --dataset prod=inventory/inventory-map.json \
--args '{"internet_exposed": true, "limit": 3, "fields": ["name","type","account_id","arn"]}'
{
"dataset": "prod",
"total": 6,
"offset": 0,
"returned": 3,
"next_cursor": "c3.d1894090b2cc",
"truncated": true,
"items": [
{"id": "bastion", "name": "bastion", "type": "EC2", "account_id": "111111111111",
"arn": "arn:aws:ec2:us-east-1:111111111111:instance/i-0bast"},
{"id": "az-vm", "name": "jump-vm", "type": "VIRTUAL_MACHINE", ...},
{"id": "logs-bucket", "name": "prod-logs", "type": "S3_BUCKET", ...}
]
}
3.2 Generate the client configuration¶
cloudg mcp config prints a JSON snippet for the client you name. It finds the launch
command itself, in this order: a cloudg-mcp executable on PATH, then cloudg, then the
current Python interpreter with -m cloudg.mcp. The snippet goes to stdout and a one-line
hint about where to paste it goes to stderr.
The outputs below came from a virtualenv where neither script was on PATH, so the
interpreter fallback was used. On a normal install the command is the cloudg-mcp script and
the arguments start with serve.
Claude Desktop (cloudg mcp config --client claude-desktop, the default):
{
"mcpServers": {
"cloudg": {
"command": "/run/media/morpheuslord/Personal_Files/Projects/cloudg/.venv/bin/python",
"args": ["-m", "cloudg.mcp", "serve"]
}
}
}
Hint printed to stderr: merge it into claude_desktop_config.json (Settings, Developer, Edit
Config), then restart Claude Desktop.
Claude Code (--client claude-code):
{
"mcpServers": {
"cloudg": {
"type": "stdio",
"command": "/run/media/morpheuslord/Personal_Files/Projects/cloudg/.venv/bin/python",
"args": ["-m", "cloudg.mcp", "serve"],
"env": {}
}
}
}
Save it as .mcp.json in the project root, or pass the inner entry to
claude mcp add-json cloudg '<entry JSON>'.
Cursor (--client cursor) produces the same shape as Claude Desktop. Merge it into
~/.cursor/mcp.json (global) or .cursor/mcp.json (project).
VS Code (--client vscode) uses a servers key and an explicit type:
{
"servers": {
"cloudg": {
"type": "stdio",
"command": "/run/media/morpheuslord/Personal_Files/Projects/cloudg/.venv/bin/python",
"args": ["-m", "cloudg.mcp", "serve"]
}
}
}
Save it as .vscode/mcp.json. The hint on stderr also offers the other place VS Code reads:
add the entry under "mcp" in settings.json.
To bake options into the launch command, pass them to config. Dataset paths are resolved
to absolute paths, because the client starts the server from a working directory you do not
control:
cloudg mcp config --client claude-desktop --policy strict \
--dataset prod=./reports/inventory-map.json --read-only
{
"mcpServers": {
"cloudg": {
"command": "/run/media/morpheuslord/Personal_Files/Projects/cloudg/.venv/bin/python",
"args": [
"-m", "cloudg.mcp", "serve",
"--policy", "strict",
"--dataset", "prod=/run/media/morpheuslord/Personal_Files/Projects/cloudg/reports/inventory-map.json",
"--read-only"
]
}
}
}
3.3 Connecting to a running HTTP server¶
With --transport http the snippet points at a URL instead of launching a process.
--token-env VAR adds a bearer header that reads the token from an environment variable, in
the syntax each client expands. --policy, --dataset and --read-only are ignored in this
mode, since the server is already running.
{
"mcpServers": {
"cloudg": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp",
"headers": {"Authorization": "Bearer ${CLOUDG_MCP_TOKEN}"}
}
}
}
Cursor gets "Bearer ${env:CLOUDG_MCP_TOKEN}" and no type; VS Code gets servers,
"type": "http" and ${env:...}. Claude Desktop's config file only launches local
commands, so cloudg bridges to the URL with mcp-remote:
{
"mcpServers": {
"cloudg": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://127.0.0.1:8765/mcp",
"--header", "Authorization:Bearer ${CLOUDG_MCP_TOKEN}"]
}
}
}
The generated Claude Desktop entry has no env block. Whether ${CLOUDG_MCP_TOKEN} gets a
value depends on the environment Claude Desktop passes to npx, which I did not test. If the
header arrives empty, add "env": {"CLOUDG_MCP_TOKEN": "..."} to the entry by hand.
3.4 First conversation¶
The server sends instructions on initialize that tell the model to start with
workspace_status. If no dataset was preloaded, ask the assistant to load one: "Load
/abs/path/to/reports/inventory-map.json and show me the internet-exposed assets with HIGH
findings." The path must sit inside an allowed root (section 11.3), so either preload with
--dataset or set CLOUDG_MCP_ALLOWED_ROOTS in the client's env block.