Skip to main content

CNG MCP Server

Model Context Protocol (MCP) server for CNG Sandbox. Exposes datasets, stories, connections, and validation as composable tools for agents.

What is MCP?

MCP is a protocol that lets applications (agents, CLI tools, SDKs) discover and interact with tools and resources in a standardized way. This server makes the CNG Sandbox accessible to any MCP-compatible client.

Installation

pip install cngstorytelling-mcp

This installs the cng-mcp command. To run against your own instance, see the self-hosting guide.

Quick Start

1. Start the Server

# Default API URL (http://localhost:8086)
cng-mcp --workspace-id <8-char-id>

# Custom API URL
cng-mcp --api-url http://your-sandbox.com --workspace-id <8-char-id>

The server communicates over stdio. Connect with any MCP client.

The ingestion API requires an X-Workspace-Id header on workspace-listing endpoints (/api/datasets, /api/connections, /api/stories). Pass --workspace-id (or set SANDBOX_WORKSPACE_ID) so the server can forward it — without it, listing endpoints return 400.

2. Use with Claude Desktop / Code

Add to your MCP client config:

{
  "mcpServers": {
    "cng-sandbox": {
      "command": "cng-mcp",
      "args": ["--api-url", "http://localhost:8086", "--workspace-id", "abcd1234"]
    }
  }
}

Tools

read_datasets

List all datasets in your workspace with IDs, types, and bounds.

read_story

Get a story's metadata and chapters. Input: story_id (string)

create_story

Create a new story. Input:

  • title (string)
  • description (string)
  • chapters (array): each with title, narrative, map_state, and layer_config (containing dataset_id or connection_id)
    • map_state: { center: [lng, lat], zoom, bearing, pitch, basemap } plus optional 3D fields:
      • terrain: { enabled: bool, exaggeration: number } — 3D terrain relief. Ignored when the chapter has a bound data layer (data can't drape on terrain in v1); use terrain on scene-setting chapters only.
      • globe: bool — globe projection with atmosphere; works with data layers.
      • buildings: bool — extruded 3D buildings (OpenFreeMap).
      • Omit these for a flat 2D map. Portable/archival HTML exports ignore 3D fields and render flat.
  • Chapter type may be "flyover": a scroll-scrubbed 3D camera flight. Flyover chapters add:
    • keyframes (array, >= 2 to fly): { center: [lng, lat], zoom, bearing, pitch, caption? } — the camera path, interpolated smoothly in reader scroll order. caption is markdown shown as the camera passes that keyframe.
    • scroll_length (number, default 1): scroll distance multiplier (~one viewport height per keyframe segment at 1).
    • layer_config is optional; as with other chapters, terrain is ignored when a data layer is bound. The best flyovers are terrain/buildings scene-setters with no data layer.
    • map_state pose fields are ignored — keyframe 0 is the entry camera. Compute keyframes from dataset bounds for an easy orbit: fix center/zoom/pitch, sweep bearing across ~180° in 5 steps.

update_story

Modify an existing story. Input: story_id, updates (object with changed fields)

read_connections

List external tile source connections.

create_connection

Create a new external tile source connection. Input:

  • name (string)
  • url (string)
  • connection_type (string): one of zarr, cog, pmtiles, xyz_raster, xyz_vector, geoparquet, copc
  • bounds (array, optional): [west, south, east, north]
  • min_zoom / max_zoom (integer, optional)
  • tile_type (string, optional): tile image format (e.g. png, webp)
  • band_count (integer, optional)
  • rescale (string, optional): range as "min,max"
  • config (object, optional): additional tiler config
  • geozarr_attrs (object, optional): GeoZarr-spec attributes

validate_layer_config

Check if a layer configuration is valid before creating a chapter. Input: dataset_id, optional colormap, rescale_min/rescale_max, and color_mode (elevation/intensity/classification/rgb) for point-cloud (copc) layers. Provide either a colormap (raster) or a color_mode (copc).

Ingestion & export

get_job_status

Get the status of a conversion job by job ID (pending/converting/ready/failed). Input: job_id (string)

ingest_url

Ingest a remote geospatial file (GeoTIFF, GeoJSON, Shapefile .zip, NetCDF, HDF5) into a dataset. Waits for conversion to finish and returns the dataset ID. Input: url (string); optional wait (boolean, default true), timeout (number, default 600)

discover_remote

List geospatial files at a remote URL or S3 prefix before connecting them. Input: url (string)

connect_remote_temporal

Register remote COGs as a temporal (date-stepped, time-slider) or mosaic dataset. Discovers files at the URL if an explicit file list is not given; waits for the job to finish. Input: url (string); optional mode (temporal or mosaic, default temporal), files (array of {url, filename}), timeout (number)

upload_story_asset

Upload a local image or CSV file as a story asset (for image chapters and CSV chart chapters). Returns the asset ID and URL. Input: file_path (string), kind (image or csv); optional story_id (string)

update_connection_colormap

Set the preferred colormap for a raster connection (cog/xyz_raster/raster pmtiles). Input: connection_id (string), colormap (string); optional reversed (boolean)

update_connection_categories

Update category labels/colors for a categorical connection. Input: connection_id (string), categories (array of {value:int, label?:str, color?:'#RRGGBB'})

delete_connection

Delete an external tile source connection by ID. Input: connection_id (string)

export_story_interactive

Build and download a story's self-contained interactive HTML bundle (.zip) to a local path. Stories with zarr layers, flyover chapters, or scrolly chapters needing snapshots return an error. Input: story_id (string), output_path (string)

Resources

  • cng://datasets — Catalog of available datasets
  • cng://story-templates — Pre-built templates agents can reference
  • cng://colormaps — Valid colormap names

Development

cd mcp
uv sync --extra dev
uv run pytest tests/ -v

See CONTRIBUTING.md and ARCHITECTURE.md.

Troubleshooting

"Connection refused" on localhost:8086

Verify sandbox stack is running: docker compose ps. If not, start it: docker compose up -d.

"Unknown colormap" validation error

List valid colormaps via the cng://colormaps resource and pick one.

Server doesn't discover tools

Run with debug logging: cng-mcp --log-level DEBUG. Check for tool registration messages.

"ModuleNotFoundError: No module named 'cng_mcp'"

Install in editable mode from the mcp/ directory: pip install -e mcp/.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cngstorytelling_mcp-2.12.0.tar.gz (81.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cngstorytelling_mcp-2.12.0-py3-none-any.whl (24.1 kB view details)

Uploaded Python 3

File details

Details for the file cngstorytelling_mcp-2.12.0.tar.gz.

File metadata

  • Download URL: cngstorytelling_mcp-2.12.0.tar.gz
  • Upload date:
  • Size: 81.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cngstorytelling_mcp-2.12.0.tar.gz
Algorithm Hash digest
SHA256 a7beed93863702720ba474c8de174a033e4e14000072908492e51c07ec370039
MD5 8b820576ef51b6522ac28753226ddf58
BLAKE2b-256 bcf40b0bb06aa28b530b8bdde1675caaa64bd2e9a27931fb8e59f9e5df8102bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for cngstorytelling_mcp-2.12.0.tar.gz:

Publisher: publish-mcp.yml on aboydnw/cng-sandbox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cngstorytelling_mcp-2.12.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cngstorytelling_mcp-2.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5bf421761615bf99e3d011b55b54634ee2b6ac306d3912a64ff317c4962b265b
MD5 c6b1301c1ae144edc8a8bfac2e0625ad
BLAKE2b-256 f41c5682343c5da9952492d5e3dd52c2e61f7aca807dd17bcbde0ae79883154a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cngstorytelling_mcp-2.12.0-py3-none-any.whl:

Publisher: publish-mcp.yml on aboydnw/cng-sandbox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2.15.0

2 files

2.14.0

2 files

2.13.0

2 files

This release

2.12.0 This release

2 files

2.11.0

2 files

2.10.0

2 files

2.9.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page