Skip to main content
Glama
PengLx
by PengLx

TiledMCP

一个面向 Tiled Map Editor 的安全优先 Tilemap MCP 服务器。目标是让支持 MCP 的模型安全地检查、创建、编辑、验证和预览 Tiled 资产,并逐步扩展到格式转换、AutoMapping 与 Wang 地形等官方自动化能力。

项目状态

核心里程碑:初期设计已实质全部落地,接口以 0.0.x Draft 发布、尚未冻结。

当前注册 52 个不依赖 Tiled CLI 的核心工具,另有最多 3 个按本机探测注册的可选 工具(tiled_render_map / tiled_preview_export / tiled_preview_terrain), 合计 55 个;1400+ 测试在 pnpm run verifypnpm run verify:tiled-1.12.2 双门禁下全绿。能力域概览:

  • 安全地基:项目根沙箱与 symlink 拒绝、raw bytes 权威 + SHA-256 revision CAS、source-preserving JSON patch、原子替换、内容寻址 checkpoint 与启动对账、 跨文件崩溃可恢复事务。除 tiled_create_maptiled_create_checkpoint 两个明确例外,一切写入都走 preview → 批准 → apply。

  • 读取与分析:四种投影(正交/等距/staggered/hexagonal)的摘要、region、 usage 分析;atlas 与 image-collection tileset 详情、Wang 语义展开、复杂属性 投影、对象与模板展开读取、TMX/XML 只读核心(自研零依赖受限解析器)、JSON world 读取与 pattern 展开、连通性分析、无状态选区(含魔棒/多边形/组合)。

  • 编辑:18 种 mapEdit operation(tile/对象/图层/地图/引用结构),等距地图 全线放行;Wang 写入与官方地形笔刷、项目 class/enum 定义 CRUD、语义 tile 命名 注册表、悬空 gid 机械修复。

  • 程序化生成:确定性 shape/noise/cellular/dungeon/scatter/prefab(多层+ 翻转)/参考图导入,全部产出普通 mapEdit change set,绝不使用 Math.random。

  • 视觉闭环:native tile-layer preview(含高亮/对象调试 overlay)、四投影 原生渲染、tileset sheet 与稀疏选集渲染、像素级 render diff;可选 tmxrasterizer 整图渲染。

  • 格式与导出:TMX/TSX/TX 原生字节级写出(对照官方 writer 金标准,含 class 属性经 .tiled-project 定义的无损序列化);可选官方 CLI 导出面。

逐刀演进记录与历史行为叙述见 docs/07-devlog.md。当前运行 能力以 tiled_get_capabilitiestools/list 与 resource discovery 为准。

Related MCP server: DevServer MCP

文档索引

文档

内容

docs/01-tiled-research.md

Tiled 软件调研:核心数据模型、文件格式、自动化生态、现有同类 MCP 分析

docs/02-mcp-spec.md

MCP 功能规格草案:Tools / Resources / Prompts 清单与分期计划

docs/03-architecture.md

技术架构:技术选型、读写策略、关键实现要点与坑

docs/04-security.md

Frozen v1 direct filesystem 威胁模型与部署要求

docs/05-cross-file-wal-design.md

跨文件 WAL 事务设计与决策记录(S1–S3 已实施)

docs/06-infinite-edit-design.md

无限地图编辑设计定稿:Tiled 1.12.2 chunk 语义考证、规范化写回决策与实施切片

docs/07-devlog.md

逐刀能力演进记录与历史行为叙述(各刀提交时的快照,计数不代表现状)

contracts/mcp-contract.v1.json

从真实 MCP discovery 生成的双 profile 完整机器契约

contracts/application-errors.v1.json

当前 104 个 v1 application code 及其兼容性、fallback 和排除边界

docs/generated/mcp-reference.md

自动生成的全部工具 schema、annotations 与调用参考

docs/examples/safe-workflows.md

revision 传递、批准边界、创建例外与错误处理工作流

examples/mcp-calls.v1.json

每个已注册工具恰好一个、由公开 input schema 校验的调用示例

一句话定位

TMJ/TSJ(JSON)无损读写为地基、官方 Tiled 1.12.2 源码语义为对照标准 的安全优先 Tilemap MCP 服务器:一切有界、未定义语义 fail closed 不近似、写入经 preview/批准/apply 两阶段提交并全程可恢复;在此之上提供四投影读写渲染、确定性 程序化生成与字节级 XML 写出,把视觉闭环(选料 → 编辑 → 渲染自查 → 对比确认) 做成一等能力。

快速开始

要求 Node.js 20.19+、pnpm 11。tileset sheet、显式 tile 选集与有限正交 tile-layer region preview 都是内建核心能力,不依赖 GUI。复杂地图的高保真整图 PNG 预览仍需要本机安装 Tiled / tmxrasterizer

pnpm install --frozen-lockfile
pnpm build
node dist/index.js --project-dir /absolute/path/to/your/tiled-project

本机安装精确的 Tiled 1.12.2 与随附 tmxrasterizer 后,可运行不可跳过的真实集成门:

pnpm run verify:tiled-1.12.2

该门校验版本、运行时导出格式、checked-in fixture 的 JSON round-trip 与 PNG rasterization,并确认 tiled_create_map 产物可由目标版本重新导出。普通 pnpm test 仍不把可选 Tiled CLI 变成核心 direct-JSON 能力的运行依赖。

服务使用 stdio transport;stdout 只承载 MCP 协议,诊断写入 stderr。项目根目录是必填 的 fail-closed 安全边界,也可以通过 TILED_PROJECT_DIR 设置。checkpoint retained storage 默认配额为 1 GiB,可用 --checkpoint-bytesTILEDMCP_CHECKPOINT_BYTES 设置规范十进制 [1-9][0-9]* bytes,范围 1..9007199254740991;运行时精确值以 checkpointCapabilities.storagePolicy 为准。可选 --checkpoint-retain-per-target N / TILEDMCP_CHECKPOINT_RETAIN_PER_TARGET=N 显式启用每目标 rolling retention,范围 2..10000,默认关闭;运行策略以 checkpointCapabilities.retention 为准。两类配置同时 提供时都由 CLI 优先于环境变量。一个通用的客户端配置为:

{
  "mcpServers": {
    "tiled": {
      "command": "node",
      "args": [
        "/absolute/path/to/TiledMCP/dist/index.js",
        "--project-dir",
        "/absolute/path/to/your/tiled-project"
      ]
    }
  }
}

当前注册 52 个不依赖 Tiled CLI 的核心工具;本机探测到 tmxrasterizer 时再注册 可选的 tiled_render_map,探测到 Tiled CLI 时再注册可选的 tiled_preview_exporttiled_preview_terrain(合计最多 55 个)。下文各刀叙事段落中的"仍为 N core" 计数为当刀历史快照,以本段与契约(contracts/mcp-contract.v1.json)为准:

工具

作用

tiled_get_capabilities

查看实现边界、限额和本机 Tiled CLI 能力

tiled_list_files

列出项目内 Tiled 资产

tiled_list_world_maps

只读列出一个 JSON world 的显式地图成员(坐标、声明尺寸、逐成员存在性与 revision pin);pattern 成员只计数

tiled_preview_world_edits

预览 world 成员的 add/move/remove(按当前数组 index 定位、world revision pin);被引用地图文件绝不改动

tiled_list_checkpoints

有界列出恢复 checkpoint,并隔离报告损坏 manifest

tiled_create_checkpoint

对 1..32 个项目文件的当前 bytes 建显式 committed 快照(不改任何资产),配合 restore 逐字节回滚

tiled_preview_prepared_checkpoint_discard

仅在目标仍精确等于写前状态时,固定 prepared manifest 与目标证据并生成 destructive discard change set

tiled_preview_prepared_checkpoint_commit

仅对 prepared create 的 exact-after 来源含混状态,固定完整 manifest/目标证据并生成内部状态 commit change set

tiled_preview_prepared_checkpoint_abandon

对机器无法自动处理的 prepared 冲突固定完整证据并生成永久删除恢复点、但不修改项目资产的 abandon change set

tiled_preview_checkpoint_prune

固定 committed manifest revision 并生成 destructive prune change set;不直接删除

tiled_preview_checkpoint_prune_batch

固定 2..32 个显式 committed checkpoint 的完整 manifest pins,按 canonical ID 顺序生成可部分提交的 destructive batch prune change set;不直接删除

tiled_preview_checkpoint_restore

校验单文件 checkpoint 并生成 destructive 恢复 change set;不直接写盘

tiled_get_map_summary

读取 revision、根显示/元数据、图层树和 tileset asset id

tiled_analyze_usage

只读统计整张地图的 tile 使用、图层密度、变换位和未使用 local ID

tiled_check_connectivity

只读四向连通性分析:显式可通行定义(空 cell 或列举 tile 集)、连通分量统计与 from/to 可达判定

tiled_render_diff

只读像素级地图 diff:同 region 两次 native 渲染逐像素对比(差异红色高亮、cell 粒度聚合),双侧可各选图层

tiled_get_tileset

按 map + asset id(或内嵌条目的 embeddedIndex)读取有界 atlas/稀疏 tile metadata(含 per-tile 标量属性值)/Wang 语义展开

tiled_find_tiles

按 map + asset id 精确检索显式 class/property metadata,返回分页 TileRef

tiled_get_region

TileRef 读取有界矩形区域

tiled_render_tileset_sheet

tilesetAssetId 返回带 local ID 的分页 PNG sheet

tiled_render_tiles

按输入顺序放大并标注 1–64 个显式、稀疏的 atlas local IDs

tiled_render_preview

内建渲染有限正交 tile layer,可选 region、图层、网格、坐标、有界矩形高亮和显式对象几何调试叠层

tiled_list_objects

有界列出全部或指定 object layer 的对象

tiled_get_object

按全图唯一 object ID 读取一个有界、严格判别的可编辑对象详情,并按文档序回读标量自定义属性(复杂/超长条目以 valueOmitted 标记)

tiled_validate

只读结构与 MVP profile 校验

tiled_create_map

新建有限正交 TMJ,已有文件绝不覆盖

tiled_create_tileset

预览从项目图片新建 external atlas TSJ;不直接写盘,apply 绝不覆盖已有文件

tiled_delete_file

预览删除一个 TMJ/TSJ;引用扫描 fail closed,apply 先提交 checkpoint 再删除(可恢复)

tiled_add_tileset_to_map

预览把已有 external atlas TSJ 挂到 map;不直接写盘

tiled_update_tile

预览单个已引用 TSJ 的 per-tile probability/class/动画/标量属性/碰撞形状元数据更新与 collection 条目创建/删除;不直接写盘

tiled_update_wangsets

预览单个已引用 atlas TSJ 的 Wang 编辑:新建 wang set/追加颜色/按 setWangId 语义批量分配 wangtile;不直接写盘

tiled_create_layer

预览创建一个空 tile/object/image/group 图层;不直接写盘

tiled_preview_edits

校验 map/tile/object/layer/tileset-reference 编辑并生成有 TTL 的 change set

tiled_preview_shape

确定性几何画笔:Bresenham 线段/矩形描边与填充/中点椭圆,产出普通 setTiles change set;出界与超 10,000 cell fail closed

tiled_preview_generate

确定性 seed 程序化生成:value noise/细胞自动机洞穴/rooms-and-corridors 地牢(地板全连通)+ 区间映射 tile,产出普通 setTiles change set;同 seed 同输出、绝不用 Math.random

tiled_preview_scatter

确定性密度散布:坐标 hash 逐格判定 + 加权 tile 选择(可跳过已占用格、null 选择为擦除),产出普通 setTiles change set;同 seed 同输出、平移稳定

tiled_preview_import_image

参考图导入:图片重采样到格网(alpha 加权块平均)+ 最近 palette 色映射 tile,产出普通 setTiles change set;全透明块跳过、null 色为擦除、纯整数确定性

tiled_preview_prefab

预制件盖章:把源地图一块区域(tile 连区域内锚定的 object)在规划期物化为普通 setTiles+createObject 操作盖到目标位置;extraTileLayers 一次盖多层对、flipHorizontal 按官方 TileLayer::flip 位语义水平镜像(仅 tile 层,与 objects 同用 fail closed);apply 不回读源

tiled_preview_template

以 Tiled 最小序列化形态({id, template, x, y})放置一个 JSON .tj 模板实例;模板经与读取相同的 fail-closed profile 校验并 pin revision,apply 复核 pin 与相对引用解析

tiled_list_property_types

读取 .tiled-project 的 class/enum 定义——复杂属性类型注解的权威来源

tiled_preview_property_types

预览项目 class/enum 定义的 upsert/delete(id 分配对照官方 ++mNextId;被定义间引用的类型删除 fail closed)

tiled_render_isometric

等距地图原生渲染:按官方 IsometricRenderer 坐标变换把区域画成菱形 PNG(对角线扫描序、tile 底左锚定);collection/透明色/反对角翻转/image/group 层 fail closed,object 层跳过并披露

tiled_render_hexagonal

staggered/hexagonal 原生渲染:官方 HexagonalRenderer 变换(staggered 为 hexSideLength=0 退化情形),行序合成;hex 旋转位 fail closed

tiled_preview_write_tmx

原生受限 TMX 写出:把 .tmj 序列化为与 Tiled 1.12.2 官方 writer 字节级一致的 .tmx 新文件(同目录、no-replace、无需 CLI);自定义属性支持 string/int/float/bool/color/file/object(官方 writeProperties 字节序;TSX 的 tileset 级属性同样放行),class 型属性经可选 projectFilePath 无损写出(propertytype+嵌套成员按 project 定义定型、revision pin 至 apply、--project 金标准对拍),缺 project 时与 enum 注解、其余 profile 外结构、丢精度浮点 fail closed

tiled_preview_write_tsx

原生受限 TSX 写出:把 .tsj atlas 序列化为与官方 writer 字节级一致的 .tsx 新文件;声明网格必须与图片尺寸自洽(官方会重算),per-tile 元数据/wang/属性 fail closed

tiled_select

无状态选区:按 tile 集合/空/非空/魔棒(种子四向泛洪同 baseGid 连通区)/像素多边形(cell 中心偶奇规则)/compose(≤8 步并/交/差组合)谓词扫描有界区域,sampleLimit 可升到 10,000(对齐 setTiles cell 预算,选区全量直喂编辑),返回精确计数+紧包围盒+有界坐标采样;无 selectionId 无服务端状态

tiled_list_tile_names

读服务端自有 .tiledmcp/tile-names.json 语义命名注册表:name → {tileset, localId},逐 tileset pin revision,缺文件读作空

tiled_preview_tile_names

预览语义命名注册表的 upsert/delete(专用 tileNameEdit change set):pin 注册表 revision(或其缺失)、upsert 校验 tileset 存在、apply 按批准内容 hash 重放;绝不碰 Tiled 资产。注册名可在 shape/generate/scatter/select 的 tile 位直接以 {"name": ...} 引用,服务端经 map binding 解析并 fail closed

tiled_preview_validation_fixes

机械校验修复:把所有悬空 gid cell 汇成可审批的 setTiles 擦除 change set;零问题或 >10,000 cell fail closed,悬空 tile object 只报告不代删

tiled_preview_write_tx

原生受限 TX 写出:把 .tj 模板序列化为对照 writeObjectTemplate 的 .tx 新文件(基对象不写 id/x/y);tile/嵌套模板 fail closed

tiled_preview_transaction

把 2..16 个已批准、目标路径两两不同的文档提交类 change set 组合成一个原子事务 change set,并锁定成员禁止单独 apply

tiled_apply_change_set

以对应 revision guard 提交已批准的 map edit、跨文件事务、checkpoint restore、prepared-checkpoint discard/commit/abandon、单项或 batch committed-checkpoint prune

tiled_render_map

可选;本机有 tmxrasterizer 时返回带 map/TSJ/output/renderer 可追溯元数据的 PNG

tiled_preview_export

可选;本机有 Tiled CLI 时经官方 --export-map/--export-tileset 在服务端 staging 转换项目 .tmj/.tsj,返回携带输出内容 hash 的 fileExport change set,apply 重放导出并逐字节验证后以 no-replace 创建落盘

tiled_preview_terrain

可选;经受控 tiled --evaluate 调用官方 TileLayer.wangEdit() 地形笔刷匹配器于 staging 副本,diff 后返回普通 mapEdit change set(精确 setTiles),apply 不重跑 CLI

tiled_render_map 的成功结果使用 pre-Frozen clean break,不再返回 mapPathbyteswidthheight aliases。必填字段是 mimeTypepixelSizebyteLengthsha256mapdependencyRevisionsrendereroptionssnapshotConsistencytruncatedpixelSizebyteLengthsha256 与 MCP image content 都来自同一个不超过 8 MiB 的 PNG buffer;renderer 固定报告 tmxrasterizer、启动时探测的版本与 tmxrasterizer-png-v1 profile,options 返回实际 生效的 sizeignoreVisibility

渲染前后会复核 map 与全部 external TSJ revisions,dependencyRevisions 仍只覆盖这些 TSJ。root atlas、per-tile image 和 image-layer 引用按规范化项目路径统一去重:最多 64 张, 原始 bytes 合计最多 64 MiB、解码像素合计最多 16,000,000,任一图片单边最多 8192 px。 服务端在渲染前后分别读取这些图片的一致单文件 snapshot,并比较内部的完整路径/revision 集合;这些图片 revision 有意不出现在公开结果中。tmxrasterizer 仍直接读取 live files, 而且 pre/post 相等不能排除渲染期间发生又恢复的 ABA。因此结果固定标记 snapshotConsistency: "non-atomic-read-set",不能把它解释为 map、TSJ 与图片的原子快照。

所有已注册工具都公布自己的精确、封闭 output schema。正常 handler 结果的统一外层是 {"result": <该工具的成功结果>};合法输入触发的领域/应用错误设置 isError: true,并 返回 {"result":{"ok":false,"error":{"code":"…","message":"…","details":{}}}}。 应用错误码的精确 wire 位置是 structuredContent.result.error.code。当前 v1 注册表包含 104 个 application code;机器 artifact 是 contracts/application-errors.v1.json,运行时 同一内容可从 direct Resource tiled://application-errors 读取,并由 tiled_get_capabilities.applicationErrorContract 公布 URI、revision、size、fallback 和 兼容策略。INTERNAL_ERROR 是未预期 handler 失败的安全 fallback。v1 中既有标识符及其 含义保持稳定,但未来 server 可以新增 code;客户端遇到未知 code 时应按通用应用错误安全 处理并刷新 discovery,不得把它误判为成功。

控制流只能依赖已发现的 error.code,不能匹配人类可读的 message,也不能假设 details 存在任何稳定字段。该 application registry 不包括 MCP SDK input error、 cli.*.issues[].code capability-probe 诊断、startup fatal error、tiled_validate diagnostics、checkpoint reconciliation diagnostics 或原始 OS error code;这些表面各自 遵循独立契约。

查询/渲染结果、map-edit preview、checkpoint-restore preview、tiled_create_map 的 commit 结果以及 tiled_apply_change_set 的 apply 结果是不同的类型,不能把它们当成同一 MutationResult。输入在进入 handler 前被 MCP SDK schema 拒绝时只有 text error,不带 structuredContent

进入 handler 后的成功与应用错误还会返回一个最大 1024-byte 的 compact one-line JSON text summary。v1 success summary 只给 kindversionok 和完整 structuredContent 的 UTF-8 JSON byte count;图片工具另给图片的 mimeType 与实际 inline image bytes。error summary 给稳定 code、有界单行 message、可选 messageTruncated 和 structured byte count,不复制错误 details。客户端不得从摘要 恢复字段;tiled_get_capabilities.textContentContract 公布当前版本、编码、限额和完整 结果位置。SDK 在 handler 前产生的 input-schema error 仍是 SDK-owned text-only 响应, 不使用这套应用层摘要 envelope。

当前 direct Resource:

URI

类型

作用

tiled://guide

text/markdown

串联能力发现、sheet/preview 检查、change set 客户端批准、提交与提交后复核;内容带 SHA-256 revision 和 UTF-8 byte size

tiled://application-errors

application/json

当前 104 个 v1 application code,以及 wire location、INTERNAL_ERROR fallback、兼容策略和排除边界

资产、schema 和 render Resource Templates 尚未注册;应以 resources/list / resources/templates/list 的实际响应为准。

仓库带有可由 Tiled 1.12.2 打开和渲染的 fixtures/mvp/basic.tmj 示例;其外部 TSJ 还包含 tile class(通过 type 保存)、property、collision objectgroup 与 Wang-set,用于锁定详情 读取和 tile 检索契约。

安全编辑的调用顺序是:

  1. 用 summary/region 读取 revisiondependencyRevisions 和 tileset assetId

  2. 把这两个 revision 前提连同封闭 operations 传给 tiled_preview_edits

  3. 客户端把有界摘要展示给用户批准;

  4. 用返回的 changeSetIdexpectedRevision 调用 tiled_apply_change_set

TileRef 使用 {"tileset":{"kind":"external","assetId":"…"},"localId":0},调用方不接触裸 GID。preview 在 map 或任一已固定的现有/待加入依赖 revision 已变化时都会拒绝签发。

需要盘点地图用料时,调用只读的 tiled_analyze_usage,输入为 {mapPath, topTileLimit?, expectedMapRevision?, expectedDependencyRevisions?}。它递归 扫描整张有限正交地图的所有 tile layer cell 和 object layer 中的 tile object,忽略 visibility,因此隐藏 layer/Group 也会计入。tile 频率按 tileset assetId + localId 的基础 tile 聚合,不会把翻转/对角变换拆成不同 tile;完整 raw flag 组合另在 transform 摘要中计数。

结果只返回有界摘要:按密度从低到高的 layer、未使用优先的 tileset(含未使用 local ID 数量与样本)以及按总引用数从高到低的 top tiles。单次最多扫描 1,000,000 个 tile cell 与 object、聚合 100,000 个 distinct tile;layer/tileset 摘要各最多 64 项, topTileLimit 默认 64、最多 128,序列化结果最多 256 KiB。两个 revision pin 必须同时 省略或同时提供;提供时 expectedDependencyRevisions 必须是该 map 的完整精确依赖集合。 返回的 snapshotConsistency 仍是 non-atomic-read-set,不能把多文件复核宣称为原子 快照。

需要在一个 tile layer 中批量替换时,使用 tiled_preview_editsreplaceTiles operation: {type, layerId, mappings: [{from, to}], region?}from 必须是非空 TileRefto 是完整的目标 TileRef 或用于清空的 null;匹配比较完整 encoded GID, 包括 transform/raw flags,省略 transform 表示 identity,并不是通配符。一个 operation 只扫描一次原始格子,所以 A→B, B→C 不会把原始 A 级联成 C,swap/cycle 也可预测。 region 是绝对 tile 坐标 {x,y,width,height},省略时使用该 layer 自身的完整 bounds。 每个 operation 最多 128 组映射;一个 change set 的 replacement、flood fill 与 copyRegion 合计最多执行 1,000,000 次实际 GID 读取,实际发生的替换与其他 tile operation 合计最多写 100,000 个格子。 没有命中是合法 no-op,preview 会报告 0 次替换,apply 不会改写文件。

对象编辑继续通过通用 tiled_preview_editscreateObjectupdateObjectdeleteObjects operations 提供;另有只读 tiled_get_object 用于在替换/删除 path 对象或覆盖 text 内容前取得完整、有界的语义投影,所以 registry 为 不新增注册工具。createObject.object 是按 shape 判别且拒绝额外 key 的 strict union:

  • rectangle 保持现有可选 width / height 契约;

  • point 不接受尺寸;

  • ellipse 与 Tiled 1.12 capsulewidth / height 都可省略,省略时按 Tiled 语义写为 0;显式值必须有限、非负且不超过 1,000,000,000

  • polygon 要求 3–256 个、polyline 要求 2–256 个 strict {x,y} points。 点是相对 object x/y anchor 的本地像素坐标,每轴必须为 [-1,000,000,000,1,000,000,000] 内有限数,并原序保存;polygon 隐式闭合, polyline 保持开放。这两类 wire 禁止 width / height,TMJ 中规范化写为 0。

  • text 要求扁平 text 字符串,允许空串;可选 fontFamilypixelSizecolorbolditalicunderlinestrikeoutkerningwraphorizontalAlignmentverticalAlignment 与尺寸。内容最多 4,096 个 Unicode scalar / 16,384 UTF-8 bytes,只允许 TAB/LF/CR 三种控制字符;字体族为 1–256 scalars / 1,024 bytes 且不允许控制字符,二者都拒绝未配对 surrogate。

创建后,ellipse/capsule 分别在 TMJ object 中序列化唯一的 ellipse:true / capsule:true marker,path 则只写对应的 polygonpolyline 数组;text wire 则映射为唯一的 nested text:{text,...},并按 TMJ 默认值稀疏省略 样式字段。七类对象都能继续使用现有 updateObjectdeleteObjects;update 不提供 shape 字段,不能把一种形状变成另一种。 polygon/polyline 的 patch.points 会整体替换当前路径数组,并允许与 common fields 同批出现;它不支持 append、splice 或按 index 修改,仍拒绝 width/height update。 object-update preview 的 changedFields 是 patch key 的去重字典序精确列表,表示请求 字段而非语义 diff;即使 points 与现值相同,仍会列出 points,最终 apply 才折叠为 exact-byte no-op;若同一 change set 没有其他实际变化,则返回 changed:false。 text 可局部更新内容、样式和尺寸,text-specific patch 命中其他形状会拒绝。ellipse/capsule 的尺寸更新继续接受 0,但拒绝负数、非有限数和超限值。 updateObject.patch.properties 对对象自定义属性做有界标量 set/remove,与 tiled_update_tile 共享同一写入 profile:每次最多 32 set + 32 remove、可写 string/int/float/bool/color/file、编辑后单对象最多 128 条、按 name 字典序插入 (存量非升序则插入 fail closed);class/enum/list/object 目标 fail closed, 未触碰的复杂条目逐字保留,清空后的 properties 成员整体删除;单 change set 的属性写入合计 ≤256 KiB canonical JSON UTF-8(objectPropertyUpdateCapabilities 公布全部策略)。preview/apply 继续固定 map 与完整 dependency revisions,只重写目标 object layer 的 objects member;创建时另推进 nextobjectidtiled_get_capabilities.objectShapeCapabilities 明确公布可创建形状、path 点数/ 坐标/闭合与完整数组替换语义、禁止 shape mutation、text 字段/默认值/Unicode 与 payload 预算,以及局部 patch 范围。每个 path create 或 points replacement 都按完整 payload 逐项计入共享预算:单 change set 最多 8,192 点,pending registry 合计最多 65,536 点; 相同值 no-op、later-wins 或后续 delete 均不抵扣。单 change set 的所有 text-specific flat fields 以 canonical compact JSON UTF-8 计费,最多 256 KiB; pending registry 合计最多 2 MiB。

内建 tiled_render_preview 的基础画面仍只绘制 tile layers;它会报告但不完整绘制 object layers。需要核对受支持对象的锚点与几何时,可在 overlays.objectIds 显式传入 1–64 个全图唯一 object ID;这不会受 object/layer visibility 或 opacity 影响。 rectangle、point、polygon 与 polyline 使用固定 cyan 单像素轮廓和 5px 原点十字, text 只画旋转后的 layout box,不渲染 glyph,因此不能用于确认字体、换行或对齐。 ellipse 与 Tiled 1.12 capsule 也使用同一轮廓样式,并按 output-space chord error 自适应细分。tile object 以 tile-frame-only 画 Tiled 1.12.2 的 object outline 矩形与锚点十字:alignment 取 tileset objectalignment(缺省在正交地图解析为 bottom-left)、tileoffset 按 objectSize/tileSize 缩放、缺省尺寸默认为 tile 尺寸, flip 位不改变轮廓(与 Tiled 自己的 outline 一致);不渲染 tile 图像, dangling GID 与非法 alignment/tileoffset fail closed。再传 overlays.tileObjectCollision:true(必须与 objectIds 同用)可按 Tiled "Show Tile Collision Shapes" 的同一 fragment 变换叠加所选 tile 的碰撞形状轮廓: 缩放、H/V/D flip、90° 旋转与缩放后 tileoffset 与图像完全一致,碰撞对象自身 x/y/rotation 先于 tile 变换应用,visible:false 也照画;entry 变为 tile-frame-and-collision 并回显 collisionObjectCount。碰撞对象含 gid/template、marker 冲突或 tileset 非默认 fillmode 一律 fail closed。 template 对象继续 fail closed。需要完整 object-layer、字体、tile 图像视觉语义时, 仍应使用实际 discovery 到的可选 tiled_render_map 或 Tiled 1.12.2。

修改已有图层的通用显示/元数据字段时,在同一个 tiled_preview_edits 中使用第 7 种 operation: {type:"updateLayer", layerId, patch}。它支持 tilelayerobjectgroupimagelayergroup,patch 必须非空且只能包含 nameclassNamevisibleopacityoffsetXoffsetYparallaxXparallaxYtintColorlockedblendMode。这些 wire 字段分别写入 TMJ 的 nameclassvisibleopacityoffsetxoffsetyparallaxxparallaxytintcolorlockedmode

tintColor:null 删除 tintcolor;删除一个本来就缺失的 tint 或写入完全相同的 JSON 值是 no-op。反之,即使 Tiled 在字段缺失时采用相同默认值,显式插入该字段仍算 change。 locked 只是 advisory metadata,不会阻止同批 tile/object 编辑。preview 的每项 layer update 会回显 requestedFieldschangedFieldswouldChangeaffectsDescendants;Group 中实际改变的公共渲染属性可能影响后代,因此才会明确标记。

字符串最多 1024 个字符,opacity 限 0..1,offset/parallax 必须是 -1,000,000,000..1,000,000,000 内的有限数;tint 只接受 #RRGGBB#AARRGGBBnull。blend mode 是 13 项封闭枚举:normaladdmultiplyscreenoverlaydarkenlightencolor-dodgecolor-burnhard-lightsoft-lightdifferenceexclusion。 它不是新的 standalone MCP tool,不改变注册工具数。

删除已有图层使用 generic union 的第 8 种 operation: {type:"deleteLayer", layerId, deleteDescendants?}。它必须是 change set 中唯一的 operation,不能与 tile、object 或 layer update 混批。普通 leaf 和空 Group 可直接删除; 非空 Group 必须显式传 deleteDescendants:true,随后整个 Group subtree 与其中的 tile data、image-layer 引用、objects 一起从 TMJ 删除,但不会删除外部图片或 TSJ 文件。 children 不会提升到父级,也不会顺便清空或删除祖先。

删除含对象的 subtree 前,服务端会检查仍然存活的完整 map。直接 object property 或 Tiled 1.12 list 内的 object reference 指向待删对象时拒绝;存活的 class property 可能隐藏 typed object reference,因此 fail closed。被删 subtree 内部的引用会与其目标 一起消失,不构成 dangling reference。locked 仍只是 advisory metadata:不会阻止删除, 但 preview 会报告 lockedLayerCount 并给出醒目 warning。

destructive preview 回显选中 layer 的类型/名称/父 Group/index,以及完整 deletedLayerCountdescendantLayerCountobjectCountlockedLayerCount;layer 和 object ID 各只采样最多 32 个,并用 omitted count 明示截断。apply 不降低 nextlayeridnextobjectid,不会复用历史 ID;写回只从直接父层的 layers 数组删除 一个 element,保留所有未触及 sibling、祖先和其他 source bytes。它仍通过正常的 revision-pinned preview/批准/apply 流程,不新增 standalone tool,工具数保持 注册工具数不变。

移动已有图层使用 generic union 的第 9 种 operation: {type:"moveLayer", layerId, parentGroupId?, index}。它必须独占 change set,不能与 tile、object、updateLayerdeleteLayer 或其他 move 混批。省略 parentGroupId 明确表示 map 根级;null 不是 root 的别名,会被严格 schema 拒绝。index 是移动完成后 目标 layers JSON 数组中的最终 0-based index:同父数组原有 n 个 sibling 时范围为 0..n-1,跨父移动到原有 m 个 child 的目标数组时范围为 0..m。调用方无需为向后移动 自行补偿删除造成的偏移;目标就是当前位置时是合法 no-op,apply 保持文件 bytes 完全不变。

选择 Group 会把它的完整 subtree 作为一个 element 搬移,不提升或拆散 children。Group 不能移入自身或任一后代,移动后的最大图层深度不能超过 64。locked 仍只是 advisory metadata,不会阻止移动;preview 会报告直接 source/target parent 的锁状态,以及 subtree 移动前后的 effective-locked layer 数量,并在任一侧存在 effective lock 时给出 warning。

move summary 回显 sourceParentGroupId / targetParentGroupId(根级为 null)、 sourceIndex / targetIndexsubtreeLayerCountdescendantLayerCount、最多 32 个 layerIdSampleomittedLayerCountobjectCountlockedLayerCount,以及 sourceParentLockedtargetParentLockedeffectivelyLockedLayerCountBefore / effectivelyLockedLayerCountAfterwouldChangerenderOrderMayChangerenderContextMayChangeaffectsDescendants。apply 不改变 nextlayeridnextobjectid。source-preserving 写回使用 JsonArrayMove,以修改前 source snapshot 中的 source/target container path 定位数组并搬移原 element 的精确 bytes;即使移除较早的 root layer 让后方目标 Group 的 运行时 path 前移,也不会错取目标。除数组接缝所需文本外,未触及 sibling/ancestor、 BOM、CRLF、缩进、键序、数字/字符串词法与未知字段均保持原 bytes。

move 仍走 revision-pinned preview → 客户端批准 → apply:change set 固定 operation、 map revision 与完整 dependency revisions,apply 重验摘要并在锁内执行 revision guard (对合作写者构成 CAS);实际写入前照常创建内容寻址 checkpoint。它没有 tiled_move_layer standalone tool,不改变注册工具数。

复制已有图层使用 generic union 的第 10 种 operation: {type:"duplicateLayer", layerId, destination?, name?}。它也必须独占 change set,且 没有 tiled_duplicate_layer standalone tool,不改变注册工具数。 destination 是以下三个 strict 分支之一:

  • {kind:"sameParent", index?}:目标为原直接父;省略 index 时插在原 sourceIndex + 1

  • {kind:"root", index?}:目标为 map 根 layers;省略 index 时 append;

  • {kind:"group", parentGroupId, index?}:目标为指定 Group;省略 index 时 append。

整个 destination 省略时等价于无 index 的 sameParent。显式 index 是插入完成后的 最终 0-based JSON sibling index,范围为 0..目标数组原长度,不做 clamp。Group 会复制 完整 subtree;不能复制到自身或任一 descendant 内,结果深度不能超过 64。可选 name 最多 1024 characters(允许空字符串),只覆盖副本 subtree root 的名称,不改后代或 source。

新 layer ID 从原 nextlayerid 起、新 object ID 从原 nextobjectid 起,均按 subtree preorder 连续分配;计数器推进到新的高水位,不填历史 gap。副本没有 object 时 nextobjectid 保持原 bytes 不变。typed object property 以及 Tiled 1.12 可嵌套 list 中的 object item:指向副本内部对象时重连到新 ID,指向 source subtree 外仍存在的 对象或 0 时原值保留,dangling ID 则拒绝。普通 integer property 不会被猜成 layer/object reference;非标准 typed layer reference、class property 与 object template 均 fail closed。image-layer imagefile property 继续共享原外部文件,不复制文件;tile object 的 GID 会按现有 tileset binding 校验,包含 transform flags 的原值保留。

locked 仍只是 advisory metadata,不阻止复制。preview 会按目标祖先 Group 计算 effectivelyLockedLayerCount,并给出 warning。duplicatedLayers 的每项精确回显 operationIndexsourceLayerIdcreatedRootLayerIdlayerTypenamenameTruncatedsourceParentGroupIdtargetParentGroupIdsourceIndextargetIndexcopiedLayerCountdescendantLayerCountcopiedObjectCountallocatedCellCountserializedDuplicateByteslayerIdMappingSampleomittedLayerMappingCountobjectIdMappingSampleomittedObjectMappingCountremappedInternalObjectReferenceCountretainedExternalObjectReferenceCountfileReferenceCounttileObjectCountlockedLayerCounteffectivelyLockedLayerCountrenderOrderMayChangerenderContextMayChangeaffectsDescendants。两种 ID mapping sample 各最多 32 项,必须结合 omitted count 理解。

复制后全图最多 10,000 layers、100,000 objects;单次最多复制 10,000 objects 和 100,000 个有限未压缩 tile cells,最终深度最多 64。新副本的紧凑 JSON 最多 16 MiB, 预估写回后的 TMJ 仍须不超过 64 MiB。source writer 只插入一个紧凑的新 JSON element, 并对实际变化的 nextlayerid / nextobjectid 做 value-local counter patch;原 source subtree、既有 siblings、未知字段、BOM、CRLF、键序与数字/字符串词法保持原 bytes。 apply 会重算目标、分配、引用和摘要,校验 change-set digest 与 map/dependency revision, 随后在正常锁内执行 raw-byte revision guard(对合作写者构成 CAS)、创建 checkpoint 并 原子替换。

盖章写入使用 generic union 的第 11 种 operation: {type:"stampPattern", layerId, x, y, pattern:(TileRef|null)[][]}。它没有 tiled_stamp_pattern standalone tool,不改变注册工具数。 pattern 必须是非空、稠密、矩形、row-major 的二维数组:每行非空且等宽, 不能有 sparse hole/undefined。每条边最多 256 格,总格数最多 16,384。

x/y 是图案左上角的绝对 tile 坐标。完整目标矩形必须落在目标有限 tile layer 的 bounds 内;服务端不会裁剪。矩阵中的每一项都是一次明确写入:TileRef 写入完整 encoded GID, null 写入 GID 0、明确清空该格,不表示透明或跳过;当前没有 transparent/skip sentinel。 一个 change set 按 operation 顺序执行,后面的 operation 看到前面的结果;重叠时后写者 获胜,包括 stamp 与 setTilesfillRegionreplaceTiles 或其他 stamp 的组合。

每个 pattern cell 都计入所有 tile operations 共用的 100,000-cell change-set 写入预算, 即使目标当前已经是相同值。preview 的 sample 只按 row-major 返回前 8 格的绝对 {x,y,tile}(包括 tile:null),并以 omittedCellCount 表示其余格数;完整影响范围应以 规范化 regioncellCount 和各项 count 为准。写回只局部替换目标 layer 的 data; 若所有编码后的 GID 都与原数据相同,则是语义 no-op,apply 返回 changed:false,revision 与文件 bytes 完全不变。整块清空仍直接使用 fillRegiontile:null,不需要独立 clearRegion operation。

油漆桶填充使用 generic union 的第 12 种 operation: {type:"floodFill", layerId, x, y, tile:TileRef|null}。它没有 tiled_flood_fill standalone tool,不改变注册工具数。 x/y 是目标有限 tile layer 中的绝对 seed 坐标;连通性固定为四向,不接受对角连接或 connectivity 参数。

source 在执行到该 operation 时从 seed cell 推导,并按完整 unsigned encoded GID 精确 匹配,包含 transform/raw flags;同一 base tile 的不同翻转不会混入。tile:null 可清空 相连区域,空 seed 也能用非空 TileRef 填充。若 source 与 target 编码相同,planner 只读取并验证 seed 后立即报告 no-op,不扫描整个区域。

flood fill 与同一 change set 中的其他 operation 按顺序执行:它会看到前序 set/fill/stamp/replace/flood/copy 的结果,后序 operation 则可覆盖本次填充。扫描中的 每次实际 GID 读取都计入 replace + flood + copy 共用的 1,000,000-read 上限;同一个已填 cell 或边界邻格 可能因四向遍历被重复观察,所以 scannedCellCount 是实际读取次数,不是 distinct cell 数。所有被观察 GID 都会完整反向解析,malformed、带 flags 的空 GID 或未绑定值会 fail closed。实际改变的 cell 计入共享 100,000-cell 写预算。

preview 只回显 canonical sourceTile / targetTilescannedCellCountchangedCellCount、固定的 connectivity:"four-way"、绝对 seed 和 affectedBounds;bounds 是变化区域的外接矩形,不是完整 cell 列表,无变化时为 null。写回只局部替换目标 layer 的 data;若整个 plan 最终没有净变化,apply 保持 revision 与文件 bytes 完全不变。

修改 map 根级显示/元数据字段时,使用 generic union 的第 13 种 operation: {type:"updateMap", patch}。它不注册 tiled_update_map standalone tool,所以 registry 不改变注册工具数。operation 与 patch 都拒绝额外 key,patch 必须非空, 且只能包含:

  • renderOrderright-downright-upleft-downleft-up 之一,写入 renderorder

  • backgroundColor#RRGGBB#AARRGGBBnullnull 删除 backgroundcolor

  • className:最多 1024 个 Unicode code points 的字符串,写入 class

tiled_get_map_summary 始终返回规范化 renderOrder(缺失时为 Tiled 默认 right-down),并在序列化成员存在时返回 backgroundColorclassName。 已有 class 超过 1024 个 Unicode code points 时安全截断并设置 classNameTruncated:true;无效的 render order、背景色或非字符串 class 会 fail closed,不产生伪摘要。

operations 严格依序作用于同一工作副本,后面的 updateMap 会看到并覆盖前面的结果; 与其他可混批 operation 重叠时同样 later wins。summary 的 mapUpdates 项以 operationIndex 关联;operation preview 以数组位置关联。二者都回显 requestedFieldschangedFieldswouldChangerenderingMayChange; 只有实际改变 renderOrderbackgroundColor 才提示可能改变渲染,class-only update 不置位。

change detection 以根对象 member 的实际存在性和值为准:写入相同值、删除原本缺失的 backgroundcolor 都是 no-op;缺失字段即使等于 Tiled 默认值,显式插入仍算 change。 apply 只对实际变化的根对象 member 做 insertion/replacement/deletion,不重排完整 TMJ; 顺序 operation 最终还原原始根对象时是 exact-byte net no-op,不改变 revision。

移除 map 中一个当前 external atlas binding 时,使用 generic union 的第 14 种 operation: {type:"removeTilesetFromMap", tilesetAssetId}。operation 是拒绝额外 key 的 strict object,并且必须独占 change set;它不注册 standalone tool,所以 registry 仍为 不改变注册工具数。tilesetAssetId 必须精确匹配当前 map summary 返回的 opaque asset ID,不能用路径、名称或自行推导的 ID 代替。

planner 会递归扫描全图每个有限 tile layer cell 和每个 object layer object,包括隐藏、 锁定及任意 Group 后代;带 gid 的 tile object 与 tile cell 都按完整 encoded GID 反向解析。tile cells 与 objects 合计最多扫描 1,000,000 项。目标 binding 只要有一次 引用就以 TILESET_IN_USE 拒绝整个 proposal,不清空 cell、不删除 tile object,也不把 引用重映射到其他 tileset。对象只要带 template member 就会以 UNSUPPORTED_TILESET_REMOVAL_TEMPLATE fail closed,因为未固定的外部模板可能隐藏 tile object/GID。

成功 plan 的 summary.removedTilesets[] 以扁平字段固定 operationIndexassetIdtilesetPathsourcetilesetRevisionnamenameTruncated、原 tilesets array indextileCountgidSpanfirstGidlastGidscannedCellCountscannedObjectCount。对应 operation preview 不含 operationIndex,而是按 operations 数组位置关联;其完整 shape 是顶层 type / destructive / warning / source / index,以及 tileset:{kind,assetId,path,revision,name,nameTruncated?,tileCount,gidSpan}gidRange:{first,last}scanned:{tileCells,objects}。其中 tileset.nameTruncated 只在值为 true 时出现。apply 从 pinned map 重新加载并复核 移除前的完整 dependencyRevisions,重做解析、零引用检查、扫描预算和摘要;提交只从 TMJ 的 tilesets array 删除目标 element,其他 binding 的 firstgid 与 source bytes 不变。 它不会删除 TSJ、atlas 图片或其他文件。

在同一 map 的有限 numeric tile layers 之间复制矩形时,使用 generic union 的第 15 种 operation: {type:"copyRegion",source:{layerId,x,y,width,height},destination:{layerId,x,y}}。 operation、sourcedestination 都是拒绝额外 key 的 strict object;source 和 destination layer 必须是 finite、orthogonal、未压缩 numeric-array tile layer。 坐标均为 layer 空间中的绝对 tile 坐标,完整 source 与由相同 width/height 推导出的 destination 矩形都必须落在各自 bounds 内。服务端不会 clipping、wrap、透明跳过或 部分复制。

planner 在 operation 开始时先快照完整 source 与 destination,再执行任何写入。因此同一 layer 内的重叠复制固定为 snapshot-source memmove 语义,不会因 row-major 写回把已覆盖值 继续传播。source 中每个 GID(包括 0)都会原样覆盖对应 destination:GID 0 会明确清空 目标格,不是 skip sentinel;非零值连同 H/V/D 和 raw flags 的完整 unsigned encoded GID 精确复制。source 和 destination 的每个 observed GID 都先按当前 binding 完整反向解析, malformed、flag-only empty、gap 或未绑定值均 fail closed。

copyRegion 可与其他 generic operations 混批。它在开始时看到所有前序 operation 的 结果,后序 operation 可覆盖 copy 的 destination,统一采用 sequential change-set-order/later-wins。每个 copy 的 scannedCellCount = 2 * cellCount,source 和 destination 两次读取都计入 replace/flood/copy 共用的 1,000,000-read scan budget; 完整 cellCount(包括写入相同 GID 的位置)计入所有 tile operations 共用的 100,000-cell write budget。

plan 的 summary.tileCopies[] 固定字段为 operationIndexsource:{layerId,x,y,width,height}destination:{layerId,x,y,width,height}scannedCellCountcellCountsourceNonEmptyCellCountchangedCellCountoverwrittenNonEmptyCellCountclearedCellCountoverlapsSourcewouldChange。operation preview 使用同样字段但不重复 operationIndex,另含 type:"copyRegion"destructive:truewarning,且不返回 cell list/sample。 sourceNonEmptyCellCount 是 source snapshot 的非零 GID 数; overwrittenNonEmptyCellCount 是 operation-start destination snapshot 的全部非零 GID 数,无论对应格最终是否变化;changedCellCount 只统计 source/destination 值不同的格子, clearedCellCount 则统计其中由 source GID 0 实际清空的非零 destination。 destination.width/height 是由 source 规范化补齐的尺寸。即使最终所有 GID 已相同,完整 copy intent 仍计入 scan/write budget,但 changedCellCount:0wouldChange:false;整个 plan 无其他净变化时保持 exact bytes。

tiled_get_capabilities.tileCopyCapabilities 将该契约固定为 coordinates:"absolute-tile-coordinates"clipping:falseoverlap:"snapshot-source-memmove"emptySource:"overwrites-and-clears"gidCopy:"exact-encoded-gid"observedGidValidation:"source-and-destination-fail-closed"operationOrdering:"sequential-change-set-order-last-write-wins"scanBudget:"shared-with-replaceTiles-and-floodFill-per-change-set"sourcePatch:"destination-tile-layer-data-member-local"。apply 从 pinned map 重算 快照、GID 校验、预算和摘要;copy 执行时实际发生变化的 destination tile layer 才进入 data-member-local source patch 候选。若后序 operation 恢复原值,最终 source diff 仍折叠为 exact-byte no-op。该 operation 不注册 standalone tool,不改变注册工具数。

更新单个已引用 TSJ 的 per-tile 元数据时,使用专用 preview 工具 tiled_update_tile(首个 TSJ 写入面):以 mapPath + tilesetAssetId 定位、同时 pin expectedMapRevisionexpectedTilesetRevision,传入 1..64 个唯一 tileIdupdates。字段语义与 Tiled 1.12.2 逐条对齐:probability 设为 null/1 即 移除成员;className 更新已有 class 成员、否则写 canonical type(两者并存 fail closed),null 移除;animation{tileId, durationMs} 帧数组全量替换 (每 tile ≤256 帧、帧 id 必须在 tilecount 内),序列化为 Tiled 的 [{tileid, duration}]。无条目的 tile 按升序插入新条目、仅剩 {id} 的条目删除、 tiles 根成员按需插入/移除——与 Tiled 的省略语义一致;创建或删除条目的更新必须 独占整个 change setproperties 另支持有界标量 set/remove(string/int/float/ bool/color/file,与搜索侧可比较类型对称;class/enum/list/object 目标 fail closed,未触碰的复杂条目保留;新属性按名字典序插入)。collision 以 1..128 个 有界基础形状(六类几何,polygon/polyline 每形状 ≤256 点、单 change set 合计 ≤8,192 点)整体替换 tile 的 objectgroup.objectsnull 整体移除该成员——语义 对齐 Tiled 1.12.2 碰撞编辑器:新对象 id 从既有最大 id 之后连续分配、既有容器其余 成员逐字保留、新容器写 canonical draworder:"index";整体替换会丢弃旧对象携带的 自定义属性。返回的 tilesetEdit change set 以 TSJ revision 作为 expectedRevision,apply 只提交 TSJ;map 不被改写,但 pin 旧 tileset revision 的 待批 map change set 会随之冲突。未触及的条目、未知成员与 version 戳保持原 bytes。

新建 tileset 用 tiled_create_tileset(preview→apply,direct 创建特例条款保持仅 tiled_create_map):从项目内已有图集图片规划一个新 external .tsj,按 Tiled 1.12.2 的单边 margin 整除公式算 columns/rows/tilecount(不足一个 tile fail closed,右/下余量在 summary 回显),成员按 Tiled QJson 字母序落盘并带冻结的 version:"1.10"/tiledversion:"1.12.2" 戳。返回的 tilesetCreate change set 以域分隔 digest 签名并 pin 图片 path+revision;expectedRevision批准的 prospective TSJ bytes 的 SHA-256(无既有文件可 pin)。apply 重读图片、重放构建、 要求内容与 summary 完全一致后,走与 create_map 相同的 hard-link no-replace 创建: 已有目标(含字节相同)一律 FILE_ALREADY_EXISTS,结果 beforeRevision:null 并附 before.existed:false 的 checkpoint。新文件随后用 tiled_add_tileset_to_map 挂载;tilesetCreationCapabilities 公布全部策略。

删除 TMJ/TSJ 用 tiled_delete_file(preview→apply,destructive):有界 fail-closed 引用扫描覆盖 TMJ maps(tilesets[].source)、JSON worlds(maps[].fileName)与 JSON templates(tileset.source),候选 ≤2,000 个 / 64 MiB;存在 XML 资产或 pattern-based world 时以 UNSUPPORTED_REFERENCE_SCAN 拒绝,命中引用返回 FILE_IN_USE(含样本)。apply 重放扫描并 CAS 当前 revision,先提交当前字节的 committed checkpoint 再 unlink——任何崩溃窗口要么留下完整文件、要么留下可恢复 的 checkpoint。恢复走 tiled_preview_checkpoint_restore 的缺失目标扩展: expectedRevision 即恢复内容的 SHA-256,批准后以 no-replace 方式字节精确重建; 该扩展同样适用于被外部工具误删的文件。fileDeletionCapabilities 公布全部策略。

调整地图尺寸时,使用 generic union 的第 16 种、必须独占 change set 的 operation: {type:"resizeMap",width,height,offsetX?,offsetY?}。语义按 Tiled 1.12.2 官方源码 核实:offsetX/offsetY 单位为 tile,表示旧内容在新地图中的位置(缩小/向左上 裁剪用负值,省略视为 0,幅值上限 100,000);目标格 (x,y) 取自源格 (x−offsetX,y−offsetY),新增格子填空 tile。所有 tile layer 必须与当前地图 bounds 完全对齐(零 origin、同尺寸),否则整个操作以 UNSUPPORTED_RESIZE_LAYER_BOUNDS fail closed——Tiled 对非对齐 layer 的 resize 行为本身留有未定义 TODO,本项目不做 近似。每个被扫描的源格(包括将被裁剪的)都按完整 encoded GID fail-closed 校验, 裁剪不能掩盖坏数据。

对象固定采用 Tiled "remove objects" 关闭时的语义:像素偏移 (offsetX×tilewidth,offsetY×tileheight) 非零时所有对象仅平移锚点,polygon/polyline points 相对锚点自动跟随,从不删除;越界对象原样保留,摘要按"平移后锚点是否落在 闭区间像素边界外"回显 objectsOutsideNewBounds。含 template 的对象在需要平移时以 UNSUPPORTED_RESIZE_TEMPLATE fail closed。image layer 只平移发生变化的 offsetx/offsety member;group layer 自身不动;nextlayerid/nextobjectid 不变。重写目标格计入 100,000-cell write budget,源格扫描上限 1,000,000,平移对象 计入 10,000 object-mutation budget。plan 的 summary.mapResizes[] 与恒为 destructive:true 的 operation preview 回显新旧 bounds、offset、preserved/cropped 非零格计数、最多 16 项 croppedCellSample 与受影响 layer 计数。同尺寸零偏移且无 实际变化时是 exact-byte no-op。该 operation 不注册 standalone tool,不改变注册工具数。

挂载一个尚未被 map 引用的现有 TSJ 时,先从最新 map summary 取得 map revision 与完整 dependencyRevisions,再调用 tiled_add_tileset_to_map,传入 mapPathtilesetPathexpectedMapRevisionexpectedDependencyRevisions,以及可选的 expectedTilesetRevision。这个工具只验证目标 atlas、分配 firstgid 并返回 changeSetId,不会修改 TMJ/TSJ/图片等项目资产,也不写任何 .tiledmcp 内部状态 (asset identity contract v2 起,read/preview 路径的身份解析无锁且零副作用, 持久化只发生在 apply)。客户端批准后仍须调用 tiled_apply_change_set。提交成功后 重新调用 tiled_get_map_summary,从响应取得新挂载 tileset 的 opaque assetId,不要从 路径自行推导。该流程只增加 tileset 引用,不创建图层。

创建图层时,从最新 map summary 取得相同的 map revision 与完整 dependencyRevisions,再调用 tiled_create_layertype 可取 tilelayerobjectgroupimagelayergroup;省略 parentGroupId 表示根级,index 是目标同级数组中从 0 开始的插入位置,省略时追加到最上层。工具使用当前 nextlayerid 分配全图唯一 ID,只返回待批准 change set;批准后仍由 tiled_apply_change_set 写入。有限 tile layer 初始化为空 GID 数组,最多分配 100,000 个 cell。image layer 还必须提供项目内 imagePath,可带 expectedImageRevision;实际图片 revision、尺寸和 map-relative source 会作为 prospective dependency 固化进 change set,并在 apply 前再次检查。

恢复时先用 tiled_list_checkpoints 选择 manifest,并从目标文档的最新读取结果取得精确 revision;再调用 tiled_preview_checkpoint_restore(checkpointId, expectedRevision)。 preview 会验证 manifest、内容寻址 blob、原始 JSON bytes 和当前目标 revision,只返回 带 TTL 的 destructive proposal;客户端批准后仍由 tiled_apply_change_set 写盘。恢复 只替换该 checkpoint 对应的一个既有 JSON 文档,不会连带恢复其引用的 TSJ、图片或其他 文件,也不会用“创建文件前”的 checkpoint 删除文件。只有 wouldChange:true 的恢复才会 在替换前为当前版本再建 checkpoint;它的后续可恢复性还要求 checkpoint 完整且 filesystemThreatModelContract.operationalRequirements 成立。no-op 恢复不替换文件, 也不创建新 checkpoint。

清理一个当前目标仍可验证为写前状态的 prepared checkpoint 时,调用 tiled_preview_prepared_checkpoint_discard(checkpointId)。existing-file checkpoint 只有在当前普通文件的 raw revision 与 size 都精确等于 manifest 的 before 状态时才 符合条件;create checkpoint 只有在目标仍严格缺失时才符合条件。existing-file 的 before.revision === afterRevision 无法区分 no-op 与已落地,目标等于 after、目标缺失、 无关内容、create 目标已存在、symlink/非普通文件以及其他不安全状态也全部返回 CHECKPOINT_STATE_CONFLICT,不会删除 manifest。preview 不读取 stored-before blob, 只固定 raw manifest SHA-256/size、完整 metadata 与目标状态证据;因此该 checkpoint 自己的 blob 已缺失或损坏不会阻止安全 discard。批准后仍通过 tiled_apply_change_set 提交;apply 按 target → checkpoint-store 锁序重验目标证据和 raw manifest CAS,再以 manifest unlink 为不可逆提交点,随后 fsync checkpoint 目录确认 耐久性并运行同一套 fail-closed orphan GC。它永久删除恢复点但不修改项目资产,不提供 operator-forced commit、force-abandon 参数或自动删除;含混状态必须改走下面两个职责分离的裁决工具。

含混 prepared checkpoint 的人工裁决没有通用 force 开关。客户端必须先按当前 conflict 选择一个独立 preview,再展示完整证据并取得针对该 proposal 的批准:

当前 prepared 状态

允许的路径

create 目标缺失

机器可证明写入未落地;使用现有 tiled_preview_prepared_checkpoint_discard

existing 目标精确等于 before

机器可证明写入未落地;使用现有 discard

existing 目标精确等于 after

重启服务触发启动对账并自动推进为 committed

create 目标精确等于 after

tiled_preview_prepared_checkpoint_committiled_preview_prepared_checkpoint_abandon,由操作者判断来源

create 目标存在但内容无关

tiled_preview_prepared_checkpoint_abandon

existing 目标缺失或内容无关

tiled_preview_prepared_checkpoint_abandon

symlink、非普通文件、越界/内部路径、超限、不可读或读取竞态

全部拒绝,先修复不安全状态

两个裁决 preview 都固定 manifest 的 version/retention 等完整 metadata、raw SHA-256/size、 目标的严格缺失证据或 raw revision/size,以及冲突分类;各自动作域隔离的 expectedRevision 防止把 commit 批准重用于 abandon。apply 按 target mutex → target file lock → checkpoint-store lock 重验全部 pins,任一漂移都在 内部状态 mutation 前返回冲突。commit 只接受 before.existed:false 且当前安全普通目标 精确等于 afterRevision,提交点是 prepared manifest 原子替换为 committed;它不修改 项目资产、不运行 GC。该 committed manifest 只是保留内部审计记录;由于 before 表示目标 原本不存在,现有 restore 工具不能把它恢复成“删除目标”。rename 后的目录 fsync 或锁释放故障返回 manifestCommitted:truedurability:"unconfirmed" 的有界成功,不能盲目重试。 abandon 永久 unlink prepared manifest、保留当前项目文件,并在目录 fsync 后运行 fail-closed GC;unlink 后的故障同样仍返回 manifestDeleted:true。成功结果只在原 change set 内精确缓存重放,不会续跑,也不是长期授权。

显式删除恢复点时,调用 tiled_preview_checkpoint_prune(checkpointId);它只接受 committed checkpoint, 不读取或校验对应 blob,而是把原始 manifest bytes 的 SHA-256 revision 固定进 change set。客户端展示永久删除恢复点的 destructive 警告并批准后,用预览返回的 changeSetIdexpectedRevision 调用 tiled_apply_change_set。apply 先按 target → checkpoint-store 的固定锁序重新检查 raw manifest CAS,再以“unlink manifest + fsync checkpoint 目录”为提交点。提交后运行 fail-closed 全局 orphan GC: 完整 inventory 时只清理无引用 checkpoint objects 和私有 crash temp;存在 blocker 时零删除并在成功 prune 结果中报告。提交点后的 GC/fsync 诊断不会把已经删除 manifest 伪装成可重试失败。prepared checkpoint 必须先对账;满足 exact-before 条件时走 独立 discard,只有上述含混分类才能走明确的 commit/abandon 裁决。

显式清理 retention backlog 时,可调用 tiled_preview_checkpoint_prune_batch({checkpointIds})。调用方必须先从当前 checkpoint 列表中明确选择 2..32 个互不重复的 committed UUID;工具不会按 retention ordinal、时间、 label 或容量压力自动挑选 victim。计划按 canonical checkpoint ID 排序并公开执行顺序, 把每项 raw manifest revision/size/metadata 固定进 change set;聚合 expectedRevision 覆盖有序 {id,manifestRevision,manifestSize} pins。 apply 先按 canonical target path 顺序取得全部去重后的 target locks,再取唯一 checkpoint-store lock;在首次 unlink 前权威重读并完整 pin 全部成员,任一 missing、 status/path/bytes 漂移都使该批次零删除。该预检不读取 stored-before blobs,也不要求全局 inventory/object 完整,因为操作者批准的是精确 manifest 集;全局完整性只约束后续 GC。

batch prune 不是跨 manifest 原子事务:它按 canonical ID 顺序逐项 unlink,并在每项后立即 fsync checkpoint 目录,遇到首个故障即停止。首次 unlink 前失败可作为零删除错误重新预览; 一旦任一 manifest 已删除,结果就是有界 partialcompleted success,并缓存为该 change set 的最终结果;重放只返回同一结果,绝不继续删除 not-attempted 成员。只有全部 manifest 都删除且逐项目录 durability 已确认后才运行一次 fail-closed GC;若中途停止则不 运行 GC,留下的孤儿对象可由 后续安全 GC 回收。要继续清理剩余项必须重新列举、重新 preview 并再次批准。 prune/discard/abandon 都不留 tombstone,之后查询与从未存在的 ID 一样返回 not found。

长期编辑可在启动时显式设置 --checkpoint-retain-per-target NTILEDMCP_CHECKPOINT_RETAIN_PER_TARGET=N;CLI 覆盖环境变量,N 的范围是 2..10000,未设置即完全关闭。这份启动配置是自动删除 v2 rolling checkpoint 的 standing approval,不会追溯改造 legacy manifest,也不会把 label 当作 pin 或顺序依据。启用后, existing-file 的新 checkpoint 会从 checkpoint-store lock 串行保护的 durable sequence 取得唯一正整数 ordinal;create checkpoint 明确标记为 protected。成功写入目标且新 checkpoint 已 durable 标记为 committed 后,仍在同一 target lock 内按 target → checkpoint-store 锁序执行一次有界 retention:完整重扫、校验所有 recovery root 的 content object、确认当前目标等于最新 rolling checkpoint 的 afterRevision, 然后按 ordinal 保留最新 N 个并至多删除最老一个。createdAt、mtime、UUID 与 label 只用于展示,绝不参与删除排序。

任一 prepared、损坏/未知/symlink/非普通 entry、缺失或 hash/size 不匹配的 object、 sequence 重复、低于 live ordinal 的可观测回退、目标漂移或 inventory 截断都会在首次 manifest unlink 前令本次 retention 零删除。manifest unlink 是删除提交点,随后 checkpoint 目录 fsync 确认 耐久性;之后的 GC 或 checkpoint-store lock-release 故障通过成功 mutation 的 checkpointRetention 结果和固定 warning 报告, 不会把已经完成的项目写入伪装成可安全重试的失败。retention 不在 ensureCapacity 中 运行,也不会在 quota pressure 下先删恢复点:系统必须先容纳新 checkpoint,容量不足仍在 目标 promotion 前返回 CHECKPOINT_QUOTA_EXCEEDED。一次 retention 最多删一个,因此降低 N 或一次 blocker 形成的超额 rolling 历史不会被后续“一次新增、一次删除”追平;正常稳态 会维持 N;既有超额必须由操作者显式选择 victim,并使用单项或 2..32 项 batch prune 有界追赶,自动 retention 不会代替操作者挑选 backlog 成员。

tiled_preview_transaction 提供跨文件原子提交,wire 形态是组合而不是新语言: 先用既有 preview 工具分别取得 2..16 个 map edit / tileset edit / tileset create / file delete change set(目标路径两两不同),再把它们的 id 交给事务 preview。返回的 kind:"transaction" change set 逐成员列出 transactionMember operation(计划类型、replace/create/delete 目标、路径与 revision pin;删除成员标记 destructive),expectedRevision 是有序目标 pin 集 的聚合 SHA-256。preview 即锁定所有成员:在事务 pending 期间单独 apply 任何成员 返回 CHANGE_SET_OWNED,事务过期自动释放;pending 事务同时最多 4 个。apply 仍 走 tiled_apply_change_set:每个成员计划按当前项目状态重放为精确字节,全部 pin 在 canonical 路径全序加锁下复核,然后经 .tiledmcp/transactions/ 的 redo journal 提交——manifest 原子改写为 committed 是唯一提交点,之前崩溃启动 对账整体回滚、之后前滚(内容寻址 staged 对象使重放幂等);崩溃窗口内被外部写者 改动的单个目标降级为披露 conflict,其余照常前滚,与威胁模型的非合作写者边界一 致。每个目标仍建立各自的 before-state checkpoint,成员变更保持可单独恢复;结果 的 results 数组逐成员采用其单独 apply 的完全相同 wire 形状,成员 change set 重放返回事务内结果而非二次提交。staged 总量 ≤ 64 MiB;12 项存储层崩溃注入测试 与 wire 层端到端测试覆盖每个协议步骤。策略字符串冻结于 transactionCapabilities

成员对另一成员目标的 pin 与该成员 base revision 不一致的组合在事务 preview 即被拒绝;一致(全体成员共享同一 pre-state)则放行——"编辑 tileset + 同步更 新依赖它的地图"可以原子提交。attach 尚不存在的 tileset 走 create+attachtiled_add_tileset_to_map 接受可 选 createChangeSetId,用 pending tiled_create_tileset 计划重放出的 prospective TSJ 内容顶替尚不存在的文件——挂载计划 pin 的正是 create 计划的 prospective 内容 revision,prospective assetId 也是确定性路径哈希、与文件落盘 后的首次真实分配一致。这对组合既可以顺序单独 apply(先 create 后 attach),也 可以放进同一个事务原子提交:事务 prepare 时 create 成员先重放,其内容直接充当 attach 成员的依赖来源,绕开磁盘读取而不放松任何 digest 校验。

开发与验证

pnpm typecheck
pnpm contract:check
pnpm test
pnpm build

pnpm contract:generate 从两个固定 capability profile 的真实 MCP tools/listresources/listresources/templates/listresources/read 响应重建两份 machine contracts(discovery 与 application errors)和 reference;它不会探测 PATH 或启动本机 Tiled。pnpm contract:check 比较这两份 contract 与 reference 的生成结果和已提交 artifact,并重新用公开 input schema 校验全部 30 个示例。pnpm test 会先执行该 drift gate、构建 dist/,并包含真实 production stdio smoke; pnpm test:watch 为避免使用 stale build 而排除该单项,可随时用 pnpm test:stdio 单独重建并复跑;pnpm verify 串联 typecheck、build、契约检查和完整 测试。

测试覆盖路径沙箱、JSON 词法保真、revision 冲突、原子提交、checkpoint 启动对账、 全部 GID flag 组合、tile set/fill/精确 replace、稠密矩形 stamp、四向 flood fill、 矩形 tile copy、独占 map resize(offset 方向、裁剪计数与样本、layer bounds/模板/坏 GID fail-closed、image offset 局部平移、identity no-op、预算边界与 Tiled 往返)与 rectangle/point/ellipse/capsule/polygon/polyline/text object 编辑闭环 (含单对象详情读取、path/text 单项、change-set aggregate、pending registry 与 closed output 预算), 以及 atlas 几何、SVG 安全预检、图片预算和 native preview 的图层选择、H/V/D、opacity、region/grid/coordinate/highlight overlay、 tile-union、ellipse/capsule 曲线与退化边界、对象裁线/细分预算,以及 MCP image wire contract;TSJ 详情另覆盖稀疏分页、Tiled 1.12 tile type、动画采样、 collision/Wang 计数、严格 rendering 枚举、聚合扫描/256 KiB 输出预算和非法 atlas; tile 检索覆盖 class 兼容规则、all/any、标量 property 精确比较、稀疏分页、 revision pin、扫描/查询/结果预算和 malformed metadata; usage analysis 覆盖递归 cell/tile-object 统计、隐藏层、base-tile/变换位聚合、 密度/未使用/top 排序截断、exact read-set pin 和扫描/distinct/结果预算; common layer update 覆盖 4 种 layer、字段映射与边界、默认字段显式插入、tint 删除、 13 种 blend mode、mixed batch、member-local source patch、no-op 与 revision conflict; layer deletion 覆盖 leaf/nested/recursive Group、独占 plan、存活 object/list/class reference policy、locked warning、bounded subtree summary、ID 高水位、element-local source patch、tamper/stale revision 与 Tiled round trip; layer move 覆盖同父 forward/backward/first/last 的最终 index 语义、根/Group 间跨父与 空目标、同位置 exact-byte no-op、Group subtree/cycle/depth 64、parent/type/index 边界、 locked/effective-locked warning、32-ID 有界摘要与 render flags、ID 高水位、 source-snapshot JsonArrayMove(含 BOM/CRLF/未知词法及目标 path 偏移)、 tamper/stale revision 和 Tiled 1.12 round trip; tile stamp 覆盖非零 layer origin、null 清空、变换 GID、稠密矩形/边长/格数边界、 mixed-operation later-wins、8 格有界 preview、exact-byte no-op、局部 source patch、 tamper/stale dependency 与 Tiled 1.12 round trip; tile flood fill 覆盖绝对/非零 layer origin、四向边界、完整 encoded GID 与 transform 隔离、null source/target、source=target 单 seed no-op、mixed-operation later-wins、 replace/flood/copy 共享实际读取预算、100,000-cell 写预算、observed malformed GID fail-closed、无 cell list 的有界 preview、data-local source patch、tamper/stale dependency 与 Tiled 1.12 round trip; tile copy 覆盖 strict source/destination shape、跨层与同层非零 origin、完整 bounds 拒绝/no clipping、0 清空、完整 transform/raw flags、source/destination malformed GID fail-closed、同层四方向重叠 memmove、operation-start 双矩形 snapshot、mixed batch 前序可见与后序 later-wins、2*cellCount 共享 scan 和完整 cellCount 写预算、 无 cell list 的 destructive bounded preview、destination data-member-local patch、 exact-byte no-op、tamper/stale dependency 与 Tiled 1.12 round trip; map update 覆盖 strict/nonempty patch、4 种 render order、背景色写入/删除、 1024-code-point class 边界与安全摘要截断、顺序 later-wins、mapUpdates 摘要与渲染影响标记、 root-member-local source patch、exact-byte net no-op、tamper/stale revision 与 Tiled 1.12 round trip; tileset reference removal 覆盖 strict/exclusive operation、opaque asset-id 定位、 隐藏/锁定/嵌套 layer 的 cell/tile-object 全图扫描、TILESET_IN_USE、1,000,000-entry 预算、非目标 malformed/flagged GID fail-closed、template object 拒绝、乱序 binding 原 index、destructive bounded preview、旧 dependency-set pin、plan/summary tamper、 array-element-local 删除、firstgid 保持、外部 TSJ 不删除、stale revision 与 Tiled 1.12 round trip; layer duplicate 的 37+1 项专项/集成 cases 覆盖 destination 三分支、默认/最终 insertion index、root-only name override、完整 subtree 的 preorder layer/object ID、direct 与 nested-list object reference 重连、外部/零/dangling reference、class/template fail closed、GID/lock、layer/object/cell/depth/size 限制、compact source insertion、 value-local counters、BOM/CRLF/未知词法、tamper/stale revision 与 Tiled 1.12 round trip; tileset 挂载覆盖 map/现有依赖/prospective TSJ revision pin、自动 firstgid、重复引用、 GID 上限和局部 source patch;图层创建覆盖 4 种类型、根/Group 插入、nextlayerid、 tile cell 预算、prospective image pin 与单元素 source insertion; checkpoint 覆盖 exact-byte round trip、manifest/blob 篡改、prepared 状态机、目标 revision 冲突、restore/prune/batch-prune/safe-discard preview/apply/replay、恢复前二次 checkpoint、batch 全成员零删除预检、逐项 fsync、stop-on-first/cached-partial/no-resume、 raw manifest CAS、exact-before 目标证据、共享 blob 引用保留、精确 byte/entry 配额边界、共享 blob 去重、writer/GC 串行化、并发 writer 防超卖,以及 inventory 不完整时零删除的 fail-closed GC; 文档 fd 读取覆盖并发覆写/增长/截断检测。tiled://guidetiled://application-errors 另有 list/read、空 templates、内容 revision/size 和未知 URI 契约测试;生产入口另通过真实 stdio client 覆盖配置、启动 checkpoint 扫描、tools/list、summary、tile search 和 checkpoint restore。架构与 roadmap 文档中未注册的工具或 Resources 仍是候选设计,不代表已经实现。

当前已知边界

  • 写回范围:tile 编辑只重写受影响图层的 data,对象编辑只重写 objects (创建时另改 nextobjectid);范围之外的 BOM、换行、缩进、键序与词法按 bytes 保留。被明确替换的数组会重新排版。

  • 投影:oblique 全面拒绝;staggered/hexagonal 为 summary/region/usage/ select/渲染只读,编辑 fail closed;等距已全线放行(编辑与全部程序化 planner)。

  • TMX/XML:读取为只读核心(TMX 绝不进入编辑 planner);写出为受限 profile 的新文件创建(同目录、no-replace),enum 注解成员与 profile 外结构 fail closed,class 属性需显式 projectFilePath

  • 模板:JSON .tj 模板支持读取展开与实例化写入;tile 模板、XML 模板与嵌套 模板 fail closed。

  • 选区:无状态纯数据(无 selectionId、无服务端选区状态);sampleLimit 上限 10,000 对齐 setTiles cell 预算。

  • 语义命名.tiledmcp/tile-names.json 是弱元数据——读取逐 tileset pin revision,但 localId 逐字披露不复核 tileset 内容。

  • 一致性披露:一切多文件读取结果固定标记 snapshotConsistency: "non-atomic-read-set",不构成原子快照声明; locked:true 不构成写保护。

  • 明确不支持:官方 AutoMapping(1.12.2 无头 evaluate 实测不可行,铁证见 spec)、修改/删除项目资产的"强制恢复"与通用 force 入口、prefab 持久化库与 按名匹配(spec 记录为后续)。

各刀的详细行为契约与历史边界叙述见 docs/07-devlog.md; 精确 schema 与限额以 docs/generated/mcp-reference.md 与 capabilities 为准。

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PengLx/TiledMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server