Purl MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_projectA | Get the current Purl project structure from the live editor. Returns cells, objects, and settings. |
| list_objectsA | List all objects in the current project or a specific cell. Returns names, types, tags, and key properties. |
| get_objectA | Get full details of a single object — all properties, dynamics config, states, children, scripts. Use this when you need to inspect or debug a specific object. |
| get_scriptB | Get the script code for an object or cell in the current project. |
| search_scriptsA | Search every script in the project (all cell-script tabs and all object-level scripts, templates included) for a substring. Returns one entry per matching line with target/scriptName/lineNumber/line so the result is directly actionable. Pass contextLines: N to also return the N lines above and below each match — usually enough to skip a follow-up get_script call. Use this whenever you need to answer "where is X used / set / played / spawned / destroyed / handled" before making changes — the only reliable way to enumerate distributed Purl logic. |
| read_project_scriptsA | Dump every script in the project (cell scripts + object scripts, all tabs) in one call. Use this for whole-project audits, refactors, or "find every place X is wired" questions where you need the surrounding code, not just matching lines (use search_scripts when you only need matching lines). Returns a flat array of {target, scriptName, code, lineCount}, sorted scene-order. Skips empty scripts by default. Soft byte cap (default 50000) bounds the response — if exceeded, returns what fits plus a truncation marker; refine via cellName or targets. |
| get_script_historyA | Get the MCP edit history of a specific script — all past versions written via update_script, most recent last. Use this to recover code that was accidentally wiped by a previous edit. Each entry shows the timestamp, the user prompt that triggered the edit, and the full code snapshot. |
| validate_scriptA | Validate Purl DSL script syntax using the full parser. Returns detailed error messages with line/column numbers, or confirms valid syntax with a summary of detected events and actions. |
| dsl_referenceA | Get reference documentation for the Purl DSL scripting language. Query by category (events, actions, functions, variables, operators, properties, transitions, concepts) or get the full syntax reference. The "concepts" category covers object variables, component child access, message parameters, spawn parameters, and variable scopes. |
| update_scriptA | Full-replace a script: writes the supplied code as the new content. Use for genuine rewrites or to create a new script slot. For incremental edits to an existing script, prefer edit_script — its anchor matching catches stale baselines that update_script would silently overwrite. If you must full-replace an existing script, pass expectedVersion (from get_script or read_project_scripts) so a stale write fails loudly instead of stomping concurrent changes. |
| edit_scriptA | Edit an existing script via a list of find/replace anchors — the safe way to change part of a script without overwriting unrelated lines. Each edit's "old" string must match exactly once in the current content (or set replaceAll: true to replace every occurrence). Edits are applied sequentially in the order supplied; each later edit operates on the result of the previous. Atomic: if any anchor fails to match (zero or multiple), the whole call is rejected with line numbers — nothing is written. Use this for targeted changes; use update_script only for full rewrites or brand-new scripts. Stale baselines fail loudly because the anchor either matches today's content (safe) or doesn't (rejected). |
| set_propertyA | Set properties on an object. Merges the given properties into the object. Use for position (x, y), size (width, height), visibility, tags, content (for text), dynamics settings, etc. For nested-shape properties (arrays/maps) the call is guarded: |
| add_objectA | Add a new object (prime or component) to a cell. Optionally adds the object as a child of an existing component via parentName. Returns the created object summary. |
| remove_objectA | Remove an object from a cell. If the object is a component, its children are also removed. |
| move_objectA | Reparent an existing object within the same cell. Use |
| update_cellC | Set cell-level properties like gravity, wind, windAngle, size, or label. |
| get_statesA | Get presets/states for a component. Returns child list, preset names with per-child property overrides, reference snapshot, and state groups. Only works on components. |
| clone_objectA | Deep-clone an object (with all children, presets, states, scripts) into the same or a different cell. Generates new unique IDs and renames children to avoid name collisions. Optionally lands the clone as a child of an existing component via parentName. |
| bulk_cloneA | Deep-clone one source object into many copies in a single call — the batch counterpart to clone_object. Names come from either an explicit |
| bulk_set_propertyA | Set properties on multiple objects in a single call. Useful for mass-editing children of a component (e.g., changing colors). Each entry specifies an object name and properties to set. Same nested-write guards as set_property apply per entry: pass |
| push_valueA | Append a value to an array at a nested path. Additive — only the target array is touched; siblings and unrelated entries stay intact. Errors if the target isn't an array. Use this instead of |
| set_value_at_pathA | Set a single nested value at the given path. Auto-creates intermediate objects/arrays where needed. Siblings stay intact. Use this instead of |
| remove_value_at_pathA | Remove a single value at the given path. For arrays, removes the element at the bracket index and shifts subsequent elements down. For maps, deletes the keyed entry. Errors if the path doesn't exist (no silent no-ops). |
| get_debug_logsA | Read recent debug log entries from the running play session. Useful for verifying what the engine saw after a test action (input received? error fired? audio playing?). Only entries for currently-enabled domains exist in the buffer — call set_debug_domains first to enable categories. |
| set_debug_domainsA | Enable a specific set of debug chips on the running play session. Replaces the current set (pass empty array to disable all). Valid domains: collision, movement, follow, dodge, physics, zone, camera, mask, input, audio, errors, log. |
| clear_debug_logsA | Empty the debug log buffer. Use before triggering a test action so the subsequent get_debug_logs call only contains entries from that action. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/ykovenskiy-hub/purl-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server