MapLibre MCP
An MCP server that lets an AI agent validate, inspect, render, preview, compare, and debug MapLibre styles, maps, and related data.
validate_style: Check a style against the MapLibre Style Specification and list problems with property paths.describe_style_spec: Look up layer types, properties, source types, and expressions with docs and version support.describe_sources: Read TileJSON, PMTiles, and GeoJSON source metadata and verify layer source/field usage.inspect_tile: Read vector tiles at a place/zoom to see source layers, geometry types, field values, and examples.debug_layers: Explain why each layer draws or fails at a place/zoom, including filters, data, paint, icons, and fonts.describe_gl_js_api: Look up MapLibre GL JS classes, methods, options, events, and signatures.show_map: Show the user an interactive MapLibre map with GeoJSON layers and markers on an OpenFreeMap basemap.render_page: Screenshot a web page containing a MapLibre map and report page errors and failed requests.preview_style: Give the user a live interactive map link that follows style changes.render_style: Render a style to a PNG and report map errors plus missing fonts and icons.compare_styles: Render before/after style versions with differences highlighted in red.
Provides tools for validating, rendering, and comparing MapLibre styles, inspecting sources, and showing interactive maps, enabling agents to build and debug MapLibre maps.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MapLibre MCPValidate my map style and render it so I can see the result"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
maplibre-mcp
An MCP server that lets an AI agent see the MapLibre map it works on, check it, and show it to you.

A hiking style an agent made from one prompt, rendered with render_style from a camera placed above Zermatt.
A coding agent can write a MapLibre style, but it can't see the map. So it hands you untested work, or first spends minutes building a renderer of its own, and it reaches for what it remembers, like an older MapLibre GL JS or Mapbox. With maplibre-mcp the agent renders the style, looks at the image and fixes what it sees, and you get a link to a live map that redraws as it edits the file. It runs on your machine and needs no API key.
Two things it is good for:
Editing a style by chat while you watch the map change. "Make the water darker", "thin the footpaths in the village". The agent edits the file and checks the render, and your open map follows.
Finding out why a layer doesn't draw. The agent reads the real tiles, sees which layers draw at a place and why the others don't, and fixes the filter.
An agent with no shell to build its own tools, in a sandbox or a chat app, gets the most from it.
Website · Getting started · Examples · Tools
Install
It needs Node.js 22 or newer.
Client | Command |
Claude Code |
|
Codex |
|
Gemini CLI |
|
Grok |
|
VS Code |
|
Claude Desktop, Cursor, Windsurf and most other clients read this JSON. Getting started says where each one keeps it.
{
"mcpServers": {
"maplibre": {
"command": "npx",
"args": ["-y", "maplibre-mcp"]
}
}
}Rendering with MapLibre GL JS uses the installed Google Chrome. Without Chrome, the first render fails with the command that installs the Chromium it can use instead.
In a sandbox or in CI, where no browser can be installed, use the container image ghcr.io/birkskyum/maplibre-mcp, which has the server and its Chromium. Containers and sandboxes shows how.
Related MCP server: Magic Lane MCP Server
Command line
Agents that work in a shell, and people, can also run the rendering and data tools, and the GL JS API lookup, as commands, without setting up MCP. A style is a file or a URL.
npx -y maplibre-mcp render style.json --center 12.57,55.68 --zoom 12
npx -y maplibre-mcp compare before.json after.json --zoom 10
npx -y maplibre-mcp compare-renderers style.json --renderers gl-js,native
npx -y maplibre-mcp describe-sources style.json
npx -y maplibre-mcp debug-layers style.json --center 12.57,55.68 --zoom 14
npx -y maplibre-mcp inspect-tile https://tiles.openfreemap.org/planet --center 12.57,55.68 --zoom 14
npx -y maplibre-mcp describe-gl-js-api Map#flyToThe images go to map.png, compare.png and renderers.png, or to --out. npx -y maplibre-mcp --help lists the options, and Command line has the details. To validate, format or migrate a style, use gl-style-validate, gl-style-format and gl-style-migrate from @maplibre/maplibre-gl-style-spec.
Tools
validate_stylechecks a style against the MapLibre Style Specification, and lists each problem with the path to its property.describe_style_speclooks up a layer type, property, source type or expression, with its documentation and the GL JS and Native versions that support it. For a misspelled name, it suggests the closest real ones.describe_gl_js_apilooks up a class, method, option or event of MapLibre GL JS, with its signature, documentation, default and examples, in the type definitions of the version the server renders with, or of another version. It also says when a method is not in MapLibre, like one from Mapbox GL JS.describe_sourcesreads the TileJSON, PMTiles header or GeoJSON of each source in a style, lists the source layers and fields, and finds layers that use a source layer or field that is not there.inspect_tilereads the vector tile at a place and lists each source layer with its geometry types, the values of its fields and how often they occur, and a few example features, plus the zoom range of the source and the source layers the tile lacks. The source can be a source in a style, a TileJSON URL like a Martin source, a PMTiles archive or a tile URL, with MVT or MLT tiles.debug_layerssays for each layer of a style whether it draws at a place and zoom, and if not, why, like a missing source layer, a filter that matches nothing (next to the values the data has), a fill layer without polygons, paint that comes out as 0 or transparent, or icons missing from the sprite. It also notes text that falls back to local fonts, since the glyph server lacks its font stack.render_stylerenders a style to a PNG, and reports map errors, missing fonts and missing icons. It takes a center, zoom, bearing and pitch, bounds to fit, or a camera position and a point to look at over 3D terrain.preview_stylegives the user a link to a live, interactive map of a style. The map follows the style file as it changes, and an agent with no files to write sends a changed style to the same link.render_pagerenders a web page with a map, for what a style cannot hold, like plugins, controls and the page's code. It reports the page's errors and failed requests, and can run a script in the page first.compare_stylesrenders two versions of a style at the same camera, and returns one image with the style before, after, and their differences in red.compare_renderersdoes the same for one style in two renderers, for example to check that a style looks the same on the web and on mobile.show_mapshows the user an interactive map with GeoJSON layers and markers on an OpenFreeMap basemap, in clients that support MCP Apps.martin_list_sourceslists the tiles, sprites, fonts and styles a Martin server serves, with the URLs to use in a style.search_ecosystemsearches Make with MapLibre for SDKs, plugins, routing, geocoding, styling and tiling libraries, hosted APIs, products and consultancies, filtered by kind and platform, with their links and live demos.find_basemapslists the basemaps in Make with MapLibre with their style URLs or tile sources, whether they need an API key, and the attribution or logo their provider requires on the map.
The data of Make with MapLibre is © Birk Skyum, under CC BY 4.0, and both tools end with its credit.
The tools that take a style accept it as an object (style), a URL (url) or a file (path, relative to where the server runs). The tool reference lists every parameter.
Toolsets
The tools are grouped by the MapLibre project they belong to. style, gl-js and ecosystem are on by default. Choose others with --toolsets, or with the MAPLIBRE_MCP_TOOLSETS environment variable, and all turns on every toolset:
npx -y maplibre-mcp --toolsets style,gl-js,martinToolset | What it adds |
|
|
| Rendering with MapLibre GL JS, |
| Rendering with MapLibre Native |
| Rendering with a Martin server, and |
|
|
With any renderer on, there are render_style and compare_styles, and with two or more, compare_renderers. Rendering with MapLibre Native needs one more package, and rendering with Martin needs a Martin build with rendering. Rendering covers both.
Remote server
--http serves Streamable HTTP at http://127.0.0.1:3100/mcp instead of stdio, and --host and --port change the address. On a loopback address it only answers requests from localhost. On any other address it does not read or write files, it still fetches the URLs it is given from its own network, and it has no authentication, so put it behind a proxy that has. Remote server has the details.
Development
npm install
npm test
npm run dev:siteLicense
MIT © 2026 Birk Skyum
Available Tools
11 toolscompare_stylesCompare stylesARead-only
Renders two versions of a MapLibre style at the same camera, and returns one image with the style before, the style after, and their differences in red. Use it after changing a style, to check that the change did what you meant and nothing else, at a few places and zoom levels. Pass each style as an object, a URL or a file path.
| Name | Required | Description | Default |
|---|---|---|---|
| zoom | No | ||
| after | Yes | The style after the change. | |
| pitch | No | Tilt in degrees from looking straight down. | |
| width | No | Width of each of the three images. | |
| before | Yes | The style before the change. | |
| bounds | No | [west, south, east, north] to fit the map to, instead of center and zoom. | |
| center | No | [longitude, latitude] of the map center. | |
| height | No | ||
| bearing | No | The compass direction at the top of the map, in degrees. | |
| renderer | No | The MapLibre renderer to draw both with. | gl-js |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds meaningful behavioral context beyond that: the output layout (before, after, and differences in red), the fixed-camera condition, and the flexible style input forms (object, URL, or file path). This is richer than simply restating annotation signals.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first states the core behavior and output, the second gives the intended use case and input formats. Every clause earns its place, and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 10 parameters, nested objects, and no output schema, the description covers the essential return value (one image with before/after/differences), the invocation context, and the accepted style representations. Parameter defaults and constraints are already in the schema, so nothing critical is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high at 80%, and the schema already documents each parameter with descriptions. The description adds value by summarizing how to supply styles ('Pass each style as an object, a URL or a file path') and by implying that center/zoom/bounds/bearing/pitch are shared across both renders via 'at the same camera.' This compensates for the remaining undocumented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb and resource: it renders two MapLibre style versions at the same camera and returns an image showing before, after, and differences in red. This inherently distinguishes it from siblings like render_style (single render) and validate_style (validation), even without naming them. The output artifact is also specified, leaving no ambiguity about what the tool accomplishes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: 'Use it after changing a style, to check that the change did what you meant and nothing else, at a few places and zoom levels.' It does not explicitly mention when not to use it or name alternative tools, but the guidance is concrete and actionable for an agent deciding to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debug_layersDebug layersARead-only
Says for each layer of a style whether it draws anything at a place and zoom, and when it draws nothing, why: it is hidden or outside its zoom range, the tile lacks its source layer, its filter matches no feature (listed with the values the tile has), a fill layer gets no polygons, its opacity, width or size is 0 or its color transparent, or icons are missing from the sprite. It also notes text that GL JS draws with local fonts and MapLibre Native leaves out, because the style has no glyphs URL or the glyph server lacks its font stack. It reads the vector tiles and GeoJSON data at the place. Use it when a layer draws nothing. Pass the style as an object, a URL or a file path.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a style JSON document. | |
| path | No | Path to a style JSON file, relative to the directory the server runs in. | |
| zoom | No | Zoom level. Defaults to the zoom of the style. | |
| style | No | The style as a JSON object. | |
| center | No | [longitude, latitude] of the place. Defaults to the center of the style. | |
| layers | No | Only check these layers, by id. Defaults to every layer. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantial behavior: it reads vector tiles and GeoJSON at the place, enumerates the failure causes it detects (hidden, out of zoom, missing source-layer, filter match, fill geometry, opacity/width/size/color, sprite icons), and flags GL JS vs MapLibre Native text differences from missing glyphs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and dense with useful detail, but the second sentence is a long run-on list of causes that could be trimmed or split for faster scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so by describing the per-layer verdict and reasons reported, and the GL JS/MapLibre text caveat. An agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema by clarifying that the style may be supplied as an object, a URL, or a file path (i.e., the style/url/path params are alternatives), and that the data is read 'at the place'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: reports, per style layer, whether it draws anything at a place/zoom and the reason when it does not. It enumerates the diagnostic categories, making it clearly distinct from siblings like validate_style or inspect_tile.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggering context ('Use it when a layer draws nothing') and the input forms to pass. It does not name an alternative sibling such as inspect_tile for the case where a layer draws something unexpected, so it stops short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_gl_js_apiDescribe GL JS APIARead-only
Looks up a class, method, option, event or function of MapLibre GL JS, like "Map", "Map#flyTo", "MapOptions.maxPitch", "click" or "addProtocol", in the type definitions that GL JS ships. Returns its signature, documentation, parameters, default and examples, and for a class or an options type, its members. Answers for the GL JS version this server renders with, or for another version, like the one a project uses. Check here before using a method or option you are not sure exists in MapLibre, since Mapbox GL JS has some that MapLibre GL JS does not.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name to look up, like "Map#flyTo", "flyTo" or "MapOptions". | |
| version | No | A GL JS version or range, like "5.6.0" or "5", whose type definitions are fetched from jsDelivr. Defaults to the version this server renders with. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and openWorldHint, so safety is already covered. The description adds meaningful behavior beyond that: results are scoped to a GL JS version, non-default versions are fetched from jsDelivr, and the return content (signature, documentation, parameters, default, examples, class/options members) is disclosed. It does not discuss latency or failure modes of the remote fetch, which is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: purpose and accepted key formats first, then what is returned, then version scoping and the Mapbox caveat. The example keys are load-bearing disambiguation rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so explicitly. It covers lookup targets, return payload, versioning behavior, and the primary risk (assuming Mapbox-only APIs exist in MapLibre), leaving nothing an agent needs to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters and the baseline is 3. The description goes further by showing accepted name shapes ("Map", "Map#flyTo", "MapOptions.maxPitch", "click", "addProtocol") and clarifying that version may be a range like "5" or a point release, plus what the default resolves to.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (looks up) and a precise resource (class, method, option, event, or function of MapLibre GL JS), reinforced by concrete example keys like "Map#flyTo" and "MapOptions.maxPitch". It is clearly distinguishable from sibling tools such as describe_style_spec or describe_sources, which cover style/source spec material rather than the GL JS API surface.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent to check here before using a method or option whose existence is uncertain, and explains the Mapbox-vs-MapLibre divergence as the reason. It also explains version selection (server version by default, or a project's version). It stops short of naming a sibling tool as an alternative, so it is clear context rather than a full when/when-not/alternatives statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_sourcesDescribe sourcesARead-only
Reads the metadata of every source in a MapLibre style (TileJSON, PMTiles headers and GeoJSON data) and lists the source layers and fields each one provides. Then checks that every layer uses a source, source layer and fields that exist. Use it before writing layers against data you do not know. inspect_tile shows the values the fields take, and debug_layers says what each layer draws at a place. Pass the style as an object, a URL or a file path.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a style JSON document. | |
| path | No | Path to a style JSON file, relative to the directory the server runs in. | |
| style | No | The style as a JSON object. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, and the description consistently describes read-only actions ('Reads', 'checks'). It adds context beyond annotations by detailing the verification step and the input flexibility (object, URL, path). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is about four sentences and contains no filler. It front-loads the core function, then usage guidance, alternatives, and input methods. It could be slightly tighter but each sentence contributes essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only inspection tool with no output schema, the description covers purpose, when to use, alternatives, and input methods. It implies the output (lists and checks) well enough for an agent to understand what to expect. No critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with each parameter described, so baseline is 3. The description adds value by clarifying that the three parameters are alternative ways to pass the style ('as an object, a URL or a file path'), which is not explicitly stated in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads metadata of every source, lists source layers and fields, and checks layer-source consistency. It distinguishes itself from siblings by explicitly naming inspect_tile and debug_layers and explaining their different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use it before writing layers against data you do not know,' providing a clear when-to-use condition. It also mentions alternatives (inspect_tile, debug_layers) and what each does, enabling correct tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_style_specDescribe style specARead-only
Looks up a name in the MapLibre Style Specification: a layer type (like "fill"), a layer or root property (like "fill-extrusion-height" or "sky"), a source type (like "geojson") or an expression operator (like "interpolate"). Returns its documentation, type, default, allowed values, expression support and which MapLibre GL JS and MapLibre Native versions support it. Check here before using a property you are not sure exists in MapLibre, since Mapbox GL JS has properties that MapLibre does not.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name to look up. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, and the description aligns with that by describing a lookup operation with no side effects. Beyond the annotation, it discloses what the tool returns (documentation, type, default, allowed values, expression support, version support) and the Mapbox/MapLibre nuance, which gives the agent a fuller picture of behavior without contradicting the provided metadata.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no filler. It front-loads the core purpose, then quickly enumerates the accepted name categories with examples, and closes with a practical usage tip. Every sentence contributes value: purpose, scope of inputs, and the Mapbox caveat. This is well-structured and appropriately sized for a simple lookup tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter lookup tool with no output schema, the description is complete. It covers what kinds of names are accepted, what information is returned, and includes the key caution about MapLibre vs Mapbox. Given the tool's simplicity and the annotations providing the read-only safety profile, nothing essential for an agent to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter 'name' already has a description ('The name to look up.'). The description adds meaningful context by listing concrete examples of valid values (e.g., 'fill', 'fill-extrusion-height', 'geojson', 'interpolate') and clarifying that these encompass layer types, properties, source types, and expression operators. This goes beyond the schema's generic description and helps the agent format the argument correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('looks up a name') and the specific resource ('MapLibre Style Specification'), enumerating the exact types of names it handles (layer types, properties, source types, expression operators). It also distinguishes itself from sibling tools by noting it returns documentation and version support, and explicitly contrasts MapLibre with Mapbox, which signals its unique scope among the listed siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear usage directive: 'Check here before using a property you are not sure exists in MapLibre' and explains the reasoning (Mapbox has properties MapLibre does not). This tells the agent when to invoke it. It doesn't explicitly name alternatives to avoid, but given the tool's niche nature and the specific trigger, the guidance is sufficient for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_tileInspect tileARead-only
Reads the vector tile of a source at a place and zoom, and lists each source layer with its number of features, their geometry types, the values of each field and a few example features. It also gives the zoom range of the source and the source layers its metadata lists that the tile lacks. Use it to learn the values data really has, like the classes of roads, before writing filters and expressions. The source is either the id of a source in the style you pass, or the URL of a vector source: a TileJSON URL like a Martin source, a PMTiles archive, or a tile URL with {z}, {x} and {y}. Reads MVT and MLT tiles.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a style JSON document. | |
| path | No | Path to a style JSON file, relative to the directory the server runs in. | |
| zoom | No | Zoom level of the tile. Defaults to the zoom of the style, or the highest zoom of the source. | |
| layer | No | Only list this source layer. | |
| style | No | The style as a JSON object. | |
| center | No | [longitude, latitude] of the place to read. Defaults to the center of the style or the source. | |
| source | No | The id of a source in the style, or the URL of a vector source. Defaults to the only vector source of the style. | |
| examples | No | How many example features to show for each source layer. Defaults to 3. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real behavioral context beyond that: it explains the dual source-resolution model (style source id vs. a TileJSON/PMTiles/tile URL), discloses supported formats (MVT and MLT), and notes it reports metadata layers that the tile lacks — a non-obvious diagnostic behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly four sentences, front-loaded with the what-then-what-you-get, then usage, then source resolution, then formats. Dense but every clause carries information. Minor redundancy between the return-value sentence and the param semantics of 'source', which slightly dilutes sharpness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly carries the full burden of explaining the return shape, and does so thoroughly (layer list, feature counts, geometry types, field values, examples, zoom range, missing layers). All eight parameters are documented in the schema, and the non-obvious 'source' semantics are covered in prose. Nothing an agent needs to invoke it correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds genuine meaning on top by clarifying that 'source' accepts either a style source id or a vector-source URL and naming the concrete URL forms (TileJSON, PMTiles, {z}/{x}/{y}), which the schema's brief 'id of a source in the style, or the URL' does not fully spell out.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Reads the vector tile of a source at a place and zoom') and then enumerates exactly what it returns — source layers, feature counts, geometry types, field values, examples, and the source's zoom range. This is detailed enough to distinguish it from siblings like describe_sources and debug_layers, which operate at a different level.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the motivating context: 'Use it to learn the values data really has, like the classes of roads, before writing filters and expressions.' That is a concrete when-to-use. It stops short of naming which sibling to use instead when the agent only wants metadata or validation, so it lacks the explicit alternative-routing of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_stylePreview styleARead-only
Gives the user a link to an interactive map of a style, served by this server on their machine, so there is no viewer page to write, no web server to start and no browser to open for them. Given a file, the map follows it and redraws when the file changes. Given the style as an object, the map shows a changed style when you pass it together with the link, as link. Pass the style as an object, a URL or a file path.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a style JSON document. | |
| link | No | A link that this tool gave before for a style passed as an object. The map there then shows this style, and a page that has it open redraws. | |
| path | No | Path to a style JSON file, relative to the directory the server runs in. | |
| style | No | The style as a JSON object. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint and openWorldHint=false, so the description carries useful extra context: the map is served on the user's machine, needs no browser/web server setup, follows a file and redraws on change, and supports reusing a prior link to update an open page. This is genuinely behavioral detail beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the phrasing is rambling ('no viewer page to write, no web server to start and no browser to open for them') and the final sentence restates the input modes already covered. Some sentences do not fully earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter, zero-required tool with a nested style object and no output schema, the description adequately covers all input modes and the live-reload/redraw semantics an agent needs. It is reasonably complete, though it omits any mention of the returned link's format or lifetime.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents url, link, path, and style. The description's explanation of the link/style interaction largely restates the schema's own description for 'link', adding little syntax or format detail beyond it, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb+resource: it provides a link to an interactive map of a style, served locally by the server. This is distinguishable from rendering siblings, but no sibling tool (e.g., render_style, show_map) is named, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the three input modes (file path, URL, style object) and the live-reload behavior, which implies usage, but it never states when to prefer this over render_style, show_map, or render_page. No explicit when-not-to-use guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_pageRender pageARead-only
Loads a web page with a MapLibre map in a headless browser and returns a screenshot of it, so you can see a map together with the plugins, controls and code of its page, which render_style leaves out since a style cannot hold them. Also reports the errors and warnings of the page, the requests that failed and the camera of the map. Pass an HTML file, which is served together with the files in its folder, or the URL of a page. A page that keeps its map in window.map is drawn once that map has loaded everything, and script can then use the map, for example to move the camera before the screenshot.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a page, for example on a development server. | |
| path | No | Path to an HTML file, relative to the directory the server runs in. The page can load the files next to it. | |
| width | No | ||
| height | No | ||
| script | No | JavaScript to run in the page before the screenshot, like map.jumpTo({center: [7.66, 45.98], zoom: 12}). What it evaluates to is returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and openWorldHint, and the description adds real behavioral detail beyond them: it runs a headless browser, waits for window.map to finish loading before drawing, reports page errors/warnings/failed requests/camera, and returns what the script evaluates to. It does not cover timeout behavior or sandboxing of arbitrary page JS, which openWorldHint implies is relevant.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core action is front-loaded in the first clause, and the remaining sentences each add a distinct fact (outputs, input modes, window.map timing, script evaluation). Sentences are long and clause-heavy, but few words are wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so: screenshot plus errors, warnings, failed requests, camera, and the script result. For a 5-parameter tool with a mutation-free but open-world execution model, it is close to complete, missing only timing/limit behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60%, and the description compensates: it explains that path is served together with the files in its folder, that url points at a page (developer server), and that script runs before the screenshot and its evaluated value is returned. Only width/height are left implicit, which are self-evident from their names and bounds.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource chain (loads a page in a headless browser, returns a screenshot) plus the secondary outputs (errors, warnings, failed requests, camera). It explicitly contrasts itself with a named sibling: 'which render_style leaves out since a style cannot hold them.' An agent can distinguish this from render_style without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names the alternative (render_style) and the condition selecting this tool: when you need plugins, controls and code that a style cannot hold. It also clarifies the two input modes (HTML file served with its folder, or a URL). It stops short of explicit when-not-to-use guidance or pointing at show_map / preview_style.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_styleRender styleARead-only
Renders a MapLibre style to a PNG image, so you can see what the style looks like, for example after changing it. Also reports what the renderer noticed, such as style errors, failed requests, and fonts and icons that are missing. Pass the style as an object, a URL or a file path. Without center, zoom or bounds, the camera stored in the style is used. For a view over 3D terrain, cameraPosition and lookAt place the camera in space, and the result gives the center, zoom, bearing and pitch of that view to store in the style.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a style JSON document. | |
| path | No | Path to a style JSON file, relative to the directory the server runs in. | |
| zoom | No | ||
| pitch | No | Tilt in degrees from looking straight down. | |
| style | No | The style as a JSON object. | |
| width | No | ||
| bounds | No | [west, south, east, north] to fit the map to, instead of center and zoom. | |
| center | No | [longitude, latitude] of the map center. | |
| height | No | ||
| lookAt | No | [longitude, latitude] of the point on the ground that the camera at cameraPosition looks at, like a summit or a village. | |
| bearing | No | The compass direction at the top of the map, in degrees. | |
| renderer | No | The MapLibre renderer to draw with. | gl-js |
| cameraPosition | No | [longitude, latitude, altitude in metres] of the camera, to place it in space instead of with center, zoom, bearing and pitch. Needs lookAt. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, openWorldHint), so the bar is lower; the description still adds real behavioral detail: it reports renderer notices such as style errors, failed requests, and missing fonts/icons, and it discloses the camera-fallback rule when center/zoom/bounds are absent. It stops short of describing output format or size limits, but the added context is substantive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what the tool does, then layers usage context, camera fallback, and the 3D path. Dense but every sentence carries information; the only slight drag is the three-input-forms sentence, which is arguably covered by schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter, no-output-schema tool, the description covers the key return information (diagnostics plus computed view parameters) and the main parameter interactions. Minor gaps remain around width/height/bearing/pitch guidance, but nothing critical to invoking it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 77% (high-ish), so the baseline is 3, and the description exceeds it by explaining the mutually exclusive camera paths: center/zoom/bounds vs. the style's stored camera, and the 3D case where cameraPosition plus lookAt are required and the result returns center/zoom/bearing/pitch to store back. It also notes the style input may be an object, URL, or file path.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Renders a MapLibre style to a PNG image'. It also clarifies the motivating use case ('so you can see what the style looks like'). It does not, however, distinguish itself from close siblings such as preview_style or show_map, which an agent would likely weigh against it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives implied context ('after changing it') and states the fallback rule when no camera params are supplied, which is useful selection guidance. But it never names an alternative or an exclusion, so the agent gets no explicit routing between this and preview_style/validate_style, whose domains overlap with the 'reports style errors' behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_mapShow mapARead-only
Shows the user an interactive MapLibre map in the chat, with GeoJSON layers and markers on an OpenFreeMap basemap. The user sees the map and you do not; to look at a map yourself, use render_style. Without center and zoom, the map fits the layers and markers. Needs a client that supports MCP Apps.
| Name | Required | Description | Default |
|---|---|---|---|
| zoom | No | ||
| pitch | No | ||
| center | No | [longitude, latitude] of the map center. | |
| layers | No | ||
| basemap | No | The OpenFreeMap style to draw on. | liberty |
| bearing | No | ||
| markers | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, and the description adds important context beyond that: the user sees the map while the agent does not, and the map auto-fits layers and markers without center/zoom. It also notes the client requirement, which is useful operational context. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four concise sentences with no wasted words. The core purpose is front-loaded, followed by the critical user-versus-agent caveat, the alternative tool, auto-fit behavior, and the client requirement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a display-only tool with zero required parameters, the description covers the essential operational details: what the user sees, what the agent cannot see, the alternative for self-inspection, auto-fit behavior, and client compatibility. The schema handles the parameter specifics, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is low at 29%, so the description partially compensates by clarifying the interaction between center/zoom and layer auto-fitting. It also confirms layers and markers are GeoJSON-based. However, it does not add meaning for pitch, bearing, or basemap behavior beyond what the schema already provides, so the compensation is incomplete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: showing an interactive MapLibre map with GeoJSON layers and markers on an OpenFreeMap basemap. It also distinguishes itself from the sibling render_style by clarifying that the map is for the user, not for the agent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool versus an alternative: 'to look at a map yourself, use render_style.' It also adds a practical prerequisite, 'Needs a client that supports MCP Apps,' and explains the auto-fit behavior when center and zoom are omitted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_styleValidate styleARead-only
Checks a MapLibre style against the MapLibre Style Specification and lists every problem, each with the path to the property it is about. Run it after editing a style. Pass the style as an object, a URL or a file path.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL of a style JSON document. | |
| path | No | Path to a style JSON file, relative to the directory the server runs in. | |
| style | No | The style as a JSON object. |
Output Schema
| Name | Required | Description |
|---|---|---|
| problems | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to repeat those. It adds useful behavioral context about the output format ('lists every problem, each with the path to the property'), which goes beyond the annotations. It doesn't mention any limitations or side effects, but given the read-only nature and the output schema, this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence states the core purpose and output, and the second gives usage guidance and input options. Every sentence earns its place, and the most important information is front-loaded. It is appropriately sized for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, full schema coverage, an output schema (which explains return values), and annotations covering read-only behavior, the description is complete. It covers purpose, usage trigger, and input options. It doesn't mention version-specific validation or potential limitations, but these are not critical for an agent to call the tool correctly. The output schema handles return details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter (url, path, style) is already documented in the schema. The description adds a high-level summary ('Pass the style as an object, a URL or a file path') that maps to the three parameters, but doesn't provide any additional semantics beyond what the schema already offers. This meets the baseline for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Checks'), a specific resource ('MapLibre style'), and the standard it validates against ('MapLibre Style Specification'). It also clarifies the output ('lists every problem, each with the path to the property'), which distinguishes it from sibling tools like render_style or compare_styles. An agent can immediately understand what this tool does and how it differs from others.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: 'Run it after editing a style.' This tells the agent when to invoke it. It does not explicitly mention alternatives or exclusions, but the trigger is specific enough. Sibling tools have distinct purposes, so the lack of explicit 'when not to use' is acceptable given the clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.9.2- Removed
format_style - Removed
migrate_style - Added
preview_style - Added
render_page - Changed
render_style2 fields changed- added
Input schema / properties / cameraPositionAdded value: +{ + "description": "[longitude, latitude, altitude in metres] of the camera, to place it in space instead of with center, zoom, bearing and pitch. Needs lookAt.", + "items": { + "type": "number" + }, + "maxItems": 3, + "minItems": 3, + "type": "array" +} - added
Input schema / properties / lookAtAdded value: +{ + "description": "[longitude, latitude] of the point on the ground that the camera at cameraPosition looks at, like a summit or a village.", + "items": { + "type": "number" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" +}
1 tool update
v0.6.1- Added
describe_gl_js_api
2 tool updates
v0.3.0- Added
debug_layers - Added
inspect_tile
8 tool updates
v0.1.0- First observed
compare_styles - First observed
describe_sources - First observed
describe_style_spec - First observed
format_style - First observed
migrate_style - First observed
render_style - First observed
show_map - First observed
validate_style
TDQS
Scored across 11 tools
Most tools have clearly distinct purposes: spec/API lookup, source inspection, tile inspection, validation, debugging, and rendering. However, the set contains several output-oriented tools (render_style, render_page, compare_styles, preview_style, show_map) whose boundaries could be confused without careful reading, especially preview_style vs show_map and render_style vs render_page.
All tool names use consistent snake_case and are verb-led (describe_, render_, compare_, preview_, debug_, inspect_, show_, validate_). Minor variations in noun plurality and the GL_JS acronym do not break the pattern.
11 tools is well-scoped for a MapLibre style development and debugging assistant. Each tool appears to serve a distinct workflow: lookup, validation, source/tile inspection, debugging, and visual rendering.
The surface covers core style development needs: spec and API lookup, validation, source/tile inspection, layer debugging, and multiple rendering/preview paths. A minor gap is the lack of tools for directly editing or generating styles programmatically, though agents can likely work around this by editing style files and re-validating.
Maintenance
Related MCP Connectors
AI access to Mapbox docs, API references, style specs, and guides. No token required.
Provides AI assistants with direct access to Mapbox developer APIs and documentation.
- geoOAuthco.thinair
Geocoding, routing, isochrones, traffic, weather, and place search for AI agents. 19 MCP tools.
OpenStreetMap queries, maps/styles, search, routing, terrain, analysis, pipelines, and rendering.
Related MCP Servers
AlicenseAqualityAmaintenanceProvides geospatial intelligence to AI agents through Mapbox APIs, enabling geocoding, routing, POI search, map images, and offline spatial calculations.282,570 npm360MIT
Magic Lane MCP Serverofficial
AlicenseBqualityBmaintenanceEnables AI agents to become geospatially intelligent assistants with tools for location search, smart routing, round trip planning, reverse geocoding, isochrone analysis, route visualization, geofence management, and interactive map display.818 npm7Apache 2.0- AlicenseAqualityAmaintenanceEnables AI assistants to interact with Mapbox developer APIs for style management, token management, and local processing tasks like GeoJSON preview and coordinate conversion.23694 npm61MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to perceive and control a live MapLibre GL map over MCP, allowing querying rendered features, reading popups, navigating, and toggling layers.1MIT