Roblox Executor MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ROBLOX_MCP_HOST | No | Bind address. | 127.0.0.1 |
| ROBLOX_MCP_PORT | No | Bridge + dashboard port. | 16384 |
| ROBLOX_MCP_LOG_LEVEL | No | trace through fatal. | info |
| ROBLOX_MCP_LOG_PRETTY | No | 1 for human-readable logs. | off |
| ROBLOX_MCP_RUNTIME_DIR | No | Directory for per-port launcher locks. | ~/.executor-mcp |
| ROBLOX_MCP_SCRIPT_DIRS | No | Extra folders execute-file may read. | |
| ROBLOX_MCP_BRIDGE_TOKEN | No | When set, the bridge AND dashboard require this token. Connector reads getgenv().BridgeToken. | |
| ROBLOX_MCP_SESSION_LABEL | No | Friendly name for this process. | generated |
| ROBLOX_MCP_EMBEDDINGS_URL | No | Embeddings endpoint for semantic search (Ollama / OpenAI-compatible). | local |
| ROBLOX_MCP_LAUNCHER_DEBUG | No | 1 to log owner discovery, lock, startup, and proxy transitions. | off |
| ROBLOX_MCP_EMBEDDINGS_MODEL | No | Model name passed to the embeddings endpoint. | embeddinggemma |
| ROBLOX_MCP_MAX_QUEUED_EVALS | No | Bounded waiting evals per client; overflow returns retryable BRIDGE_OVERLOADED. | 128 |
| ROBLOX_MCP_MAX_RPC_BATCH_CALLS | No | Calls accepted from one RPC batch before later entries receive a bounded error. | 128 |
| ROBLOX_MCP_MAX_CONCURRENT_EVALS | No | Active eval lanes per Roblox client; one lane is reserved for nested mcp.* work. | 2 |
| ROBLOX_MCP_MAX_QUEUED_RPC_FRAMES | No | Waiting inbound script RPC frames per client. | 32 |
| ROBLOX_MCP_RPC_BATCH_CONCURRENCY | No | Host workers used inside one in-script RPC batch. | 8 |
| ROBLOX_MCP_MAX_QUEUED_SOURCE_BYTES | No | Total queued Luau source bytes per client. | 4194304 |
| ROBLOX_MCP_LAUNCHER_READY_TIMEOUT_MS | No | Maximum time to wait for a newly spawned owner to expose health + MCP. | 15000 |
| ROBLOX_MCP_MAX_CONCURRENT_RPC_FRAMES | No | Inbound script RPC frames processed per client. | 2 |
| ROBLOX_MCP_LAUNCHER_MAX_START_ATTEMPTS | No | Startup retries after a bind/process race. | 4 |
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 | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list-clientsA | List every connected Roblox executor client with its clientId, account, place, and executor. Also reports which client THIS session currently resolves to (after applying its selection). Call this before select-client when more than one client is connected or the target is unknown. Signature: {}. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| select-clientA | Bind a connected Roblox client to THIS session so your tool calls target that game. Select by clientId OR by username — selecting by username is recommended because it is account-sticky: a client gets a new clientId every reconnect, but a username binding follows the account across rejoins without re-selecting. Each session keeps its own selection, so two sessions can drive two games at once. If several agents SHARE one session, don't fight over this binding — instead pass |
| clear-selectionA | Drop THIS session's client binding so it no longer pins a specific client or account. Afterwards tools auto-resolve: with exactly one client connected they use it; with several different accounts you must select-client again. Use this to reset routing before re-selecting, or to hand control back to auto-resolution. Signature: {}. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-active-clientA | Report which live Roblox client THIS session currently resolves to (read-only), including its current selection and whether resolution is ambiguous or offline. Use it to confirm routing before running code, especially when multiple games are connected or after a rejoin. Signature: {}. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-playersA | Enumerate the live roster of the running game by calling game:GetService("Players"):GetPlayers() inside the client and reporting one record per Player. Use this to answer 'who is in this server right now?', to find a specific player's UserId/DisplayName for use in other tools, to see team assignments, or to spot the local player among everyone else. This is a pure read — it does NOT mutate game state and fires no remotes. Each player record contains, every field independently pcall-guarded so one bad property never fails the whole scan: Name, UserId, DisplayName, Team (the Team's Name, or nil when the player is on no team), AccountAge (days), and isLocal (true for the one player equal to Players.LocalPlayer). Requires only the base Roblox API (game:GetService) — no special executor capabilities. Returns { ok, count, localPlayer, players } where localPlayer is the LocalPlayer's Name (or nil), or { error } if the Players service cannot be read. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-local-player-infoA | Capture a single, comprehensive read-only snapshot of THIS client's own player (Players.LocalPlayer), the character model it currently controls, and that character's Humanoid. Use this as the first call when debugging anything about 'me' — health/death state, movement (WalkSpeed/JumpPower), spawn position, rig type, or simply to confirm the LocalPlayer's Name/UserId/Team before targeting other tools. It is a pure read: it mutates nothing and fires no remotes. Every field is independently pcall-guarded and reported as nil when absent (e.g. while dead/respawning the character or humanoid may be missing), so a partial state never errors the whole call. Returns { ok, player, character } where: player = { Name, UserId, DisplayName, AccountAge, Team } (Team is the Team's Name or nil). character = { Name, Health, MaxHealth, WalkSpeed, JumpPower, JumpHeight, MoveMagnitude (magnitude of Humanoid.MoveDirection), RigType (tostring of Humanoid.RigType), Position ({x,y,z} of the HumanoidRootPart) } — any of which may be nil. Requires only the base Roblox API; no special executor capabilities. Returns { error } only if the Players service itself cannot be read. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| discover-characterA | Find the active player's character even when Players.LocalPlayer.Character, Humanoid, or HumanoidRootPart is missing or custom-named. Checks the normal hierarchy first, then performs a bounded Workspace model search for Humanoids and likely root parts. Use this after get-local-player-info reports a missing character; consume the returned resolved paths instead of assuming game.Players.LocalPlayer.Character.HumanoidRootPart. Signature: { playerName: string?, scanWorkspace: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-place-detailsA | Read identifying and runtime details about the place and server this client is connected to. Use this to capture the exact place/universe/server you are testing in (so a finding can be reproduced), to grab the PlaceId/GameId/JobId for cross-referencing, to check the player count against MaxPlayers, or to confirm whether StreamingEnabled is on (which affects whether parts may be unloaded). It is a pure read: it mutates nothing and fires no remotes. Every field is independently pcall-guarded and reported as nil when unavailable, so a single unreadable property never fails the whole call. Returns { ok, ... } with: PlaceId, GameId, JobId, PlaceVersion, CreatorId, CreatorType (tostring of game.CreatorType), MaxPlayers (Players.MaxPlayers), PlayerCount (#Players:GetPlayers()), DistributedGameTime (workspace.DistributedGameTime, the server clock in seconds), and StreamingEnabled (workspace.StreamingEnabled). Requires only the base Roblox API; no special executor capabilities. Returns { error } only if the game/DataModel itself cannot be accessed. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| run-luauA | Execute arbitrary Luau in the active Roblox client and return its first returned value (decoded from JSON). This is the core PURE-LUAU execution tool — no access to this server's other tools from inside the script. If you want to use any other tool's data (get-players, search-instances, discover-player-values, anything from list-tools) inside your Luau, STOP and use the |
| eval-expressionA | Evaluate ONE Luau expression on the active client and return its typeof plus an encoded value. Convenience wrapper over run-luau for quick reads like 'workspace.Gravity', '#game.Players:GetPlayers()', or 'game.PlaceId'. The expression is pcall-guarded, so a runtime error is reported as { ok = false, error } instead of failing the call. Pass an expression, not statements (no 'return', no ';'). Note: this is PURE Luau — to compose with other server tools (e.g. |
| executeA | Execute Luau in the active Roblox client WITHOUT waiting for it to finish. The code is COMPILED FIRST via loadstring (a syntax error is returned cleanly as { error } and nothing runs), then handed to task.spawn so it runs on its own thread; this tool returns { scheduled = true } the moment the thread is started — it does NOT wait for completion and does NOT return the code's output, return value, or runtime errors. Use this for fire-and-forget side effects. When you need the value(s) your code produces, use run-luau or execute-and-wait instead. Requires loadstring and the task library (both guarded). Returns { scheduled = true } or { error }. Signature: { code: string, client: string?, agent: string?, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, validated-source. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| execute-and-waitA | Run Luau in the active Roblox client and WAIT for what happened, returning a structured result: { ok, returnValue, output, error? }. Unlike the fire-and-forget 'execute' tool, this reports success/failure, any error message, the FIRST value your code returns (encoded so Instances/Vector3/etc. survive), and the print()/warn() output it emitted. Output capture connects game:GetService("LogService").MessageOut to a buffer for the duration of the run, then disconnects — so it sees logs even when an executor routes print() to the Roblox console rather than swapping the global. The code is COMPILED FIRST via loadstring (a syntax error is reported as { ok = false, error } and nothing runs), then executed under pcall; a runtime error is reported in |
| batch-executeA | Run several independent Luau snippets in sequence in a single round trip, collecting every result without paying a separate tool call per snippet. Each snippet is COMPILED with loadstring and run under its own pcall, in input order; a compile or runtime error in one snippet is recorded for that snippet only and never aborts the others. For each snippet you get { index, ok, value? , error? } — |
| profile-codeA | Micro-benchmark a Luau snippet by running it |
| measure-memoryA | Measure how much Lua heap memory a snippet allocates: read gcinfo() (the live Lua heap size in KB) immediately before running your code, run it once (compiled via loadstring, executed inside a pcall), then read gcinfo() again and report the delta. Use this to spot leaks or unexpectedly heavy allocations — e.g. confirm a function frees what it creates, see how big a table a constructor builds, or detect a snippet that balloons the heap. Caveats: gcinfo reports the WHOLE Lua heap, so concurrent game activity and garbage collection between the two samples add noise; a negative deltaKB means a GC cycle ran (it does NOT mean your code freed memory). For a cleaner reading, allocate enough to dwarf the noise or run a tight loop inside |
| run-loopA | Run a Luau snippet |
| run-deferredA | Schedule a Luau snippet to run on its OWN thread and return immediately WITHOUT waiting for it to finish. Use this to start something that runs in the background while you keep issuing other tool calls — e.g. kick off a long watcher loop, an auto-farm, a background poller, or any snippet you want to run later or off the current thread so it cannot block the round trip. The code is COMPILED FIRST via loadstring; a syntax error is returned cleanly as { error } and nothing is scheduled. On success the compiled function is handed to the chosen scheduler and the tool returns at once. Modes (Luau task library): - 'spawn' -> task.spawn(fn): start running on a fresh thread immediately. - 'defer' -> task.defer(fn): run on a fresh thread at the end of the current resumption cycle. - 'delay' -> task.delay(delaySec, fn): run on a fresh thread after delaySec seconds. IMPORTANT: because this does not wait, you will NOT see the snippet's return value, errors, or print output here — the scheduled thread runs independently and any error inside it is swallowed by task. If the snippet installs state or a loop, YOU are responsible for stopping it (e.g. have it watch a getgenv() flag). Requires loadstring and the task library (both guarded). Returns { scheduled = true, mode, delaySec? } or { error }. Signature: { code: string, mode: any?, delaySec: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, validated-source. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| run-with-timeoutA | Run a Luau snippet under a WATCHDOG: it executes on its own thread and this tool polls a done flag against an os.clock() deadline, so a snippet that hangs on a YIELD (a yield that never resumes, a :Wait() on a signal that never fires) cannot block the round trip forever — after timeoutSec you get a clean { timedOut = true } instead of waiting out the whole connector timeout. Use this any time you are about to run code that MIGHT hang or take an unknown amount of time. The snippet is COMPILED FIRST via loadstring (a syntax error returns { error } and nothing runs), then started with task.spawn; the watchdog waits with task.wait until either the thread sets its done flag or the deadline passes. LIMITATION: Luau is cooperatively scheduled, so the watchdog can only fire when the snippet YIELDS. A snippet that never yields (e.g. |
| execute-fileA | Read a Luau script from the SERVER host filesystem and execute its contents on the active Roblox client, returning the first value the script returns (decoded automatically — |
| scriptA | Run a Luau program in the active Roblox client that can ALSO call any other tool inline through a live |
| script-fanoutA | Run ONE Luau program across multiple connected clients in parallel and return per-client results. Targets are chosen by either passing |
| vm-resetA | Wipe the persistent VM environment used by the |
| playbook-saveB | Persist a named, optionally parameterized Luau snippet to ~/.executor-mcp/playbooks/.json so it can be re-run later via |
| playbook-listA | List every persisted playbook in ~/.executor-mcp/playbooks/, optionally filtered to one tag. Returns summary metadata only (name, description, tags, params, timestamps) — fetch the source via |
| playbook-runA | Load a saved playbook from ~/.executor-mcp/playbooks/.json, replace any ${param} placeholders with the values from |
| playbook-deleteA | Remove a persisted playbook from ~/.executor-mcp/playbooks/. Returns { ok: true, removed: true } when the file was deleted, or { ok: true, removed: false } when it didn't exist. Does not touch any running scripts that loaded this playbook earlier. Signature: { name: string }. Phase: orchestrate; cost=low; idempotency=contextual-write. Requires: explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; changes server-side persisted/session state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-executor-infoA | In-game probe that reports WHICH executor is hosting the connector and a small capability map. Calls identifyexecutor() (guarded — it may return a name and/or version, or nothing) with getexecutorname()/getexecutorinfo() fallbacks, then flags a handful of marquee functions (getgc, hookfunction, getnilinstances, getactors, …) true/false. Call this first on a new client to confirm you are on a full-featured executor before reaching for reflection/hooking tools. Signature: {}. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-game-infoA | Read identifying metadata for the game the active client is in: PlaceId, GameId (universe), JobId (server instance), PlaceVersion, the place/universe name where readable, and the current player count. Every read is pcall-guarded, so a restricted field is reported as null rather than failing the call. Use this to confirm which game/server you are attached to before running place-specific code. Signature: {}. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| test-capabilitiesA | In-game capability matrix: probes a curated executor/runtime function list and reports which are present (callable) versus missing. For each name it checks the global environment (getgenv() first, then the thread's environment / _G) and, for dotted names like 'debug.getinfo', walks the parent table — classifying the leaf as available only when it is type=='function'. The probe NEVER calls the functions, so it is completely safe and side-effect-free. Covers reflection/closures (getgc, constants/upvalues/protos, clone/wrapper/type/hook/hash functions), script access (getscriptbytecode/closure/caller/hash, getscripts, getrunningscripts, getloadedmodules, getsenv/getfenv), instance/actor discovery (getactors, Actor Lua-state execution, communication channels, getnilinstances, getinstances), environments (getgenv, getrenv, getreg), hooking (hookfunction, hookmetamethod, restorefunction, newcclosure), metatables (getrawmetatable, setrawmetatable, setreadonly, isreadonly), namecall/signals (getnamecallmethod, getconnections, firesignal, replicatesignal, getcallbackvalue, getsignalarguments), threads (setthreadidentity, getthreadidentity), and IO/misc (loadstring, fireproximityprompt, fireclickdetector, firetouchinterest, virtual-input globals, getcustomasset, request/http_request). Use this to decide up-front whether a workflow is supported, or to compare two executors. Returns { total, availableCount, missingCount, available[], missing[] } (both lists sorted) or { error }. Signature: { threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Produces: diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-anticheat-surfacesA | Fast, lightweight defensive recon that summarizes the most common anti-cheat surfaces WITHOUT a heavy GC walk (complements, and does not duplicate, the deeper scan-hook-surfaces tool). It checks: (1) how many connections are attached to RunService's Heartbeat, Stepped, and RenderStepped — the signals anti-cheats most often use for per-frame validation loops — via getconnections; (2) whether game's raw metatable is locked (isreadonly on getrawmetatable(game)), which gates __index/__namecall hooking; (3) the count of nil-parented instances (getnilinstances), where detached watchdog scripts/objects often hide; and (4) any getgenv() global names that look anti-cheat-related (matching detect/ban/kick/anticheat/flag/cheat, case-insensitive), which can reveal an exploit's own loader or a leaked server-side guard name. Use this only as lightweight ambient context after |
| execution-footprint-auditA | READ-ONLY, one-shot Luau auditor for local execution exposure. It resolves an optional script and/or closure without invoking it; inventories virtual-input globals and VirtualInputManager/VirtualUser references; distinguishes direct Instance references from cloneref-like alternate references when compareinstances exists; compares input functions with retained MCP closure handles; audits bounded getsenv/getfenv key-name leaks; classifies closure origin/hash/hook state; scans bounded source/constants for input, environment, debug, and hook indicators; and returns findings, unknown checks, confidence, risk score, privacy-safe evidence, and truncation telemetry. It never sends input, calls the target closure, walks getgc/descendants, installs hooks, or writes to game objects or script values. A clean result does NOT prove that server-side or external detection did not occur, and cloneref/clone matches are provenance only—not an undetectability guarantee. Signature: { scriptPath: string?, functionPath: string?, includeSourceScan: any?, includeStackEnvironments: any?, maxStackFrames: any?, maxEvidence: any?, maxEnvironmentKeys: any?, maxSourceChars: any?, maxConstants: any?, maxUpvalues: any?, threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-instance-countsA | In-game shape/size profile. Walks game:GetDescendants() once (pcall-guarded, capped) and tallies every Instance by its ClassName, returning the heaviest classes first. This is the quickest way to understand how big and how 'shaped' a place is — e.g. tens of thousands of Parts, a forest of UI Frames, a swarm of scripts, or an unusual pile of a single odd class. The descendant walk is capped (maxScan, default 200000) and sets truncated=true if it hits the cap (the counts then reflect only what was scanned). The returned class list is capped to topN entries. Requires nothing beyond a live game; everything is guarded. Returns { totalInstances, scanned, truncated, distinctClasses, topClasses: [{ class, count }] } (sorted by count desc) or { error }. Signature: { topN: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-memory-statsA | In-game memory health probe. Reports the Lua VM's current heap usage via gcinfo() (in KB, guarded) and takes a census of the garbage collector by walking getgc(true) and counting objects by type — function, table, thread, userdata, and other. Optionally adds engine-level memory from game:GetService('Stats') (GetTotalMemoryUsageMb and a few notable categories) when available. Use this to gauge how heavy the client is, to spot a runaway table/closure leak (an unusually large gcObjectCount or byType.table), or to take a baseline before/after running an exploit. The GC walk is capped (maxScan, default 200000) and sets truncated=true if it hits the cap. Requires getgc for the census (reports gcObjectCount=nil if absent); gcinfo and Stats are optional. Returns { luaMemoryKB, gcObjectCount, truncated, byType, engineMemory } or { error }. Signature: { maxScan: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Produces: structured-observation, diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-render-statsA | In-game performance/runtime snapshot taken at the instant of the call. Reports: the physics frame rate from workspace:GetRealPhysicsFPS(); engine timing from game:GetService('Stats') when available (FrameTime in seconds and HeartbeatTimeMs); the current camera's world position (from its CFrame) and FieldOfView; the live player count from #Players:GetPlayers(); and workspace.DistributedGameTime (server-synchronized clock). Use this for a one-shot health read while debugging (is the client dropping frames? where is the camera? how many players are present?), or to capture a baseline before/after an exploit to see its perf impact. Every field is independently pcall-guarded and reported as null when unavailable, so the tool always returns a partial snapshot rather than failing. Requires nothing beyond a live game. Returns { physicsFPS, frameTimeSeconds, heartbeatTimeMs, camera: { position, fieldOfView }, playerCount, distributedGameTime } or { error }. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| bridge-statusA | Report the bridge/session state as seen from this MCP session, WITHOUT touching any game. Shows: this session's { id, label, selection }; which client this session currently resolves to after applying its selection (the active client, or why none resolves); and the full roster of connected Roblox executor clients (clientId, username, userId, placeId, executor). Use this to debug multi-session routing — e.g. to confirm that your session and another session are pointed at different games, or to see whether any client is connected at all. Includes live per-client queue/concurrency pressure and rejected-overload counts when the transport exposes them. Returns { session, active, bridgeLoad, clients } and never runs Luau. Signature: {}. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-connector-diagnosticsA | Probe the live connector/runtime from inside the Roblox client and return a self-report describing the execution environment. Every read is pcall-guarded, so an unavailable function is reported as null rather than failing the call. Returns { threadIdentity, executor={ name, version }, hasWebSocket, gcInfoKB, genvKeyCount, hasReg, hasRenv, capabilities={ getgc, hookfunction, getnilinstances, getactors, getluastate, run_on_actor, clonefunction, newcclosure, cloneref, compareinstances, getcallingscript, getscriptclosure, getsenv, getfenv, mouse1click, keypress, getcallbackvalue, firesignal, getconnections } }. Use this to confirm what the connector can do before relying on reflection/hooking tools, or to diagnose why a client is behaving unexpectedly. Signature: { threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, created-handle, diagnostic-report. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| session-listA | Enumerate every recorded session in ~/.executor-mcp/sessions/.jsonl. Each entry shows sessionId, sessionLabel (e.g. 'live'), startedAt, endedAt, the number of recorded calls, and file size. Newest-first. Use the returned sessionId with |
| session-showA | Read a window of recorded tool calls from one session's JSONL trace. Pass |
| session-replayA | Read one session's recorded trace and (by default) return a structured plan; pass |
| get-instance-treeA | Return a nested { name, class, children } tree under an instance resolved from a dotted path (default 'game'), capped by maxDepth and maxChildren so large containers don't overwhelm the output. Each node lists how many children were truncated. Use this for broad structure exploration; use get-instance-properties to read one instance's values. The path is pcall-resolved, so a bad path returns { error } rather than failing. Signature: { path: string?, maxDepth: number?, maxChildren: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client, resolved-target. Produces: bounded-candidates, structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-instance-propertiesA | Resolve a single instance from a dotted path (e.g. 'game.Workspace.Part') and read a useful core set of its properties plus all of its attributes. Each property is pcall-read independently, so ones that don't exist on the class are simply omitted rather than failing the call. Returns { path, fullName, className, properties, attributes } with each property as { type, value }, or { error } if the path does not resolve. For listing many instances use get-instance-tree instead. Signature: { path: string }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-script-contentA | Get decompiled source for a Roblox script by path or getter code. Use startLine/endLine for a focused range when the full script is large. Signature: { scriptGetterSource: string?, scriptPath: string?, startLine: number?, endLine: number?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: decompile. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-console-outputB | Read recent Roblox developer console logs from the active client. Use limit and logsOrder to control volume and ordering. Signature: { limit: any?, logsOrder: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| search-instancesB | Search Roblox instances with QueryDescendants selector syntax. Use for class, name, tag, property, and attribute queries against a chosen root. Signature: { selector: string, root: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| script-grepA | Search decompiled Roblox scripts for a pattern, line by line, with surrounding context. Enumerates every client-readable LuaSourceContainer reachable from the active client (via QueryDescendants plus nil-parented scripts), decompiles each, and reports matching lines grouped per script. Matching uses Luau string.find: with literal=true the query is matched as a plain substring; otherwise it is treated as a Luau string pattern (note: Luau patterns, not JavaScript regex). Use exact identifiers or simple patterns; use semantic-search-scripts when behavior is known but names are not. Decompilation is best-effort and can be slow on large places, so the scan is capped by maxScripts. Signature: { query: string, root: any?, limit: any?, contextLines: any?, maxMatchesPerScript: any?, maxScripts: any?, literal: any?, caseSensitive: any?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-attributesA | Walk the descendants of a root instance and collect every unique custom attribute name (via GetAttributes()), with its observed value type, a sample value, and how many instances carry it. Use this when debugging gameplay data that is stored as instance attributes (e.g. QuestId, Health, OwnerUserId) and you want to discover which attribute keys exist in a place without grepping scripts. Returns [{ Name, ValueType, SampleValue, InstanceCount }] sorted by frequency. Work is capped at |
| verify-path-existsA | Cheaply check whether a dotted instance path currently resolves to a real Instance, without reading any properties. Use this as a pre-flight check before click-button / type-text-box / get-instance-properties so you fail fast with a clear message instead of acting on a stale or wrong path (UI gets created/destroyed dynamically). Returns { exists, className?, fullName? } — when exists is false, className/fullName are omitted. Signature: { path: string, threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| watch-instance-propertyA | Poll a single property of an instance at a fixed interval for a bounded duration and record every sampled value plus whether it changed since the previous sample. Use this to debug timing/animation/state issues — e.g. confirm a Frame's Visible actually toggles when you click, watch a Humanoid's Health drop, or see whether a Value object updates. Returns { Path, Property, Samples = [{ t, value, changed }], changeCount }. The call blocks for roughly |
| list-instance-signalsA | Enumerate the RBXScriptSignal members (events) of a Roblox Instance and report how many connections each has. Connection counts require an executor exposing getconnections(signal); if it is unavailable the signals are still listed but ConnectionCount is reported as null with a note. Returns { Instance, GetConnectionsAvailable, Signals: [{ SignalName, ConnectionCount, Note? }] } or { error } when the instance cannot be resolved. Signature: { instancePath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| trace-connection-functionA | Inspect a single connection on an Instance's RBXScriptSignal and return debug metadata about the connected Luau function. Uses getconnections(inst[signalName]) to enumerate connections and debug.info/debug.getinfo to resolve the function's name, source, line and parameter count. REQUIRES an executor exposing getconnections and debug.info (or debug.getinfo); if either capability is missing, or the signal/connection/function cannot be resolved, returns a clear { error } describing the missing capability. Returns { Signal, ConnectionIndex, ConnectionCount, Function: { Name, Source, ShortSource, LineDefined, NumParams, IsVararg, What, Pointer } }. Signature: { instancePath: string, signalName: string, connectionIndex: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: bounded-event-snapshot, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| diff-instance-snapshotA | Answer 'what did clicking this button / firing this remote / opening this menu actually change in the game tree?' by snapshotting an instance subtree, performing the action in-game, then diffing the before/after. Workflow: (1) call action='snapshot' on a root (default game.Workspace) to capture a baseline; (2) do the thing in-game (click, fire a remote, walk somewhere, wait for a wave to spawn); (3) call action='compare' with the SAME name to see exactly which instances were ADDED, REMOVED, or CHANGED. How it works: it walks root:GetDescendants() (capped at maxInstances) and builds a per-instance signature from a handful of cheap properties (ClassName, Name, Parent, and whichever of Position/Transparency/Value/Text/Visible/Anchored/Health/Enabled exist). 'changed' entries report the before and after signatures so you can see precisely which property moved (a part teleported, a value bumped, a label retexted, a GUI shown). State is stored CLIENT-SIDE in getgenv().__mcp_snapshots[name], so baselines persist across tool calls and are naturally isolated per game / per session. Use distinct names to keep several independent baselines. snapshot returns: { action='snapshot', name, root, captured, truncated }. compare returns: { action='compare', name, root, counts={ added, removed, changed }, added=[paths], removed=[paths], changed=[{ path, before, after }], truncated=bool }. Non-mutating and fully pcall-guarded (locked/destroyed instances are skipped, never aborting the scan). Each detail list is capped at 200 entries; the exact counts are always reported. Signature: { action: "snapshot" | "compare", root: any?, name: any?, maxInstances: any?, threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| discover-player-valuesA | Auto-discovery for 'where's the money/score/XP path?'. Walks LocalPlayer (esp. leaderstats), PlayerGui, ReplicatedStorage and ReplicatedFirst for IntValue/NumberValue/StringValue/BoolValue/Folder-of-values, scores each by name keywords (money/coin/cash/gold/score/xp/level/exp/kills/wins/...), container weight (leaderstats >> everything else), kind (numeric > string > bool), and magnitude. Returns a single ranked list of { path, class, name, value, score, reasons[] } so the AI doesn't have to grind through the tree. Pure read; no remotes fired, no state mutated. Use this as the first probe on any unfamiliar game. Signature: { limit: number?, minScore: number?, extraRoots: {string}? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-signal-connectionsA | Enumerate every connection on an RBXScriptSignal and, for each, report its full Connection metadata: Index, Enabled, LuaConnection, ForeignState, whether it has a Function/Thread, and (for Lua connections) the connected function's Source script, Name, LineDefined and NumParams. This is the main tool for answering "what is listening to this event and where is each handler defined?". Requires getconnections; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, ConnectionCount, Connections: [...] }. Signature: { instancePath: string, signalName: any?, includeFunctionInfo: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: bounded-candidates, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-connection-infoA | Return the full Connection metadata for ONE connection on an RBXScriptSignal, selected by zero-based index. Reports Index, Enabled, LuaConnection, ForeignState, whether it has a Function/Thread, the connected thread's status (when present), and — for Lua connections — the handler function's Source script, Name, LineDefined, NumParams, IsVararg and What. Use this to zoom in on a specific listener after list-signal-connections shows you the index of interest. Requires getconnections; degrades with a clear { error } if unavailable or if the index is out of range. Returns { Signal, Instance?, ConnectionCount, Connection: {...} }. Signature: { instancePath: string, signalName: any?, connectionIndex: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: structured-observation, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-signal-argumentsA | Report the value TYPES that an RBXScriptSignal fires its connected handlers with, using the executor's getsignalarguments. This answers "what shape is the payload of this event?" without having to connect a handler and wait for a fire — invaluable when reverse-engineering a remote-driven or engine signal so you know how to construct a fire-signal / replicate-signal call. Pass the instance that owns the signal plus the signal member name (or leave signalName empty if instancePath already resolves to the signal). Requires the getsignalarguments executor function; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, Arguments } where Arguments is the type/scalar info mapped through a safe serializer. Signature: { instancePath: string, signalName: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| count-signal-connectionsA | Resolve an RBXScriptSignal and return a fast numeric breakdown of everything connected to it: Total connections, how many are Lua vs Foreign (engine/C-side), how many are currently Enabled vs Disabled, and how many carry a Lua Function. Use this as a lightweight first pass before list-signal-connections when you only need counts (e.g. "how many handlers are on this RemoteEvent?", "are any of this signal's connections disabled?"). Does NOT describe each function, so it is much cheaper than the full listing. Requires the executor's getconnections; degrades to a clear { error } if unavailable. Returns { Signal, Instance?, Total, Lua, Foreign, Enabled, Disabled, WithFunction }. Signature: { instancePath: string, signalName: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-connection-constantsA | Disassemble the Lua function bound to ONE connection on an RBXScriptSignal (selected by zero-based index) and return its constant pool via debug.getconstants. Constants include the literal strings, numbers and referenced globals/methods baked into the closure — invaluable for reverse-engineering what a hidden event handler does (e.g. which RemoteEvent names or HTTP endpoints it touches). Each constant is passed through a value encoder so tables/functions/instances render as readable descriptors instead of raw pointers. Requires getconnections and debug.getconstants; returns a clear { error } if either is missing or the connection has no Lua Function. Returns { Signal, Instance?, ConnectionIndex, Function, Constants: [...], Count }. Signature: { instancePath: string, signalName: any?, connectionIndex: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives, getconnections. Produces: structured-observation, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-signal-arguments-infoA | Report RICH, per-argument metadata about what an RBXScriptSignal fires with, using the executor's getsignalargumentsinfo. This is the more detailed companion to get-signal-arguments: where that tool reports just the argument types/values, this returns the executor's fuller per-argument descriptor table (e.g. type tags, optionality, and per-entry detail) so you can precisely reconstruct a signal's payload when crafting a fire-signal / replicate-signal call. Pass the instance that owns the signal plus the signal member name (or leave signalName empty if instancePath already resolves to the signal). Requires the getsignalargumentsinfo executor function; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, ArgumentsInfo } with nested values mapped through a safe serializer. Signature: { instancePath: string, signalName: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| replicate-signalA | MUTATES SERVER STATE — DANGEROUS. Invokes replicatesignal(signal, ...) to fire the event with full network REPLICATION, so the event is delivered to the SERVER and can have real, authoritative server-side effects (unlike fire-signal, which is local only). Only some signals are replicable; this tool first checks cansignalreplicate(signal) and refuses to fire if it returns false. Use this ONLY for authorized testing of a game you own/control — firing replicated signals on other games may violate their rules. Requires the executor's replicatesignal; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, Replicated, ArgCount } or { error }. Signature: { instancePath: string, signalName: any?, args: {{ kind: "string" | "number" | "boolean" | "nil" | "instance" | "raw", value: string | number | boolean? }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getconnections, firesignal. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-instances-with-connectionsA | Walk every descendant of a root instance and report which ones have an active handler on a specific signal. For each descendant it reads inst[signalName]; if that member is an RBXScriptSignal with at least one connection (per getconnections), it records { Path, ClassName, ConnectionCount }. Results are sorted by ConnectionCount descending. This answers questions like "which Parts in Workspace have a Touched handler?", "which GuiButtons are wired to Activated?", or "who is listening to Changed under this model?". Requires the executor's getconnections; degrades to a clear { error } if unavailable. Scanning is capped at |
| get-connection-upvaluesA | Read the captured upvalues of the Lua function bound to ONE connection on an RBXScriptSignal (selected by zero-based index) via debug.getupvalues. Upvalues are the variables a closure captured from its enclosing scope — typically shared state, config tables, cached services or other functions — so this reveals the live context a hidden event handler operates on. Each upvalue is reported with its typeof and a readable encoded value (instances become full names, tables/functions become descriptors). Requires getconnections and debug.getupvalues; returns a clear { error } if either is missing or the connection has no Lua Function. Returns { Signal, Instance?, ConnectionIndex, Function, Upvalues: [...], Count }. Signature: { instancePath: string, signalName: any?, connectionIndex: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives, getconnections. Produces: structured-observation, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| can-signal-replicateA | Query whether an RBXScriptSignal is one the Roblox engine permits to be replicated to the server, using the executor's cansignalreplicate. When CanReplicate is true, the replicate-signal tool can fire this signal so the server receives it as if the game client raised it natively — the basis for driving server-side logic that is normally gated behind engine-internal signals. When false, replicate-signal will be rejected and you must use a different vector. Use this to pre-flight a signal before attempting replication. Pass the instance that owns the signal plus the signal member name (or leave signalName empty if instancePath already resolves to the signal). Requires the cansignalreplicate executor function; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, CanReplicate, Note }. Signature: { instancePath: string, signalName: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| fire-connectionA | MUTATES CLIENT STATE. Invokes a single connection's :Fire(...) (or :Defer(...) when defer=true) so that ONLY the one targeted handler runs with the supplied arguments — unlike fire-signal, which triggers every connection. Identify the connection by its index within getconnections(signal) (use list-signal-connections to find indices). This is client-side only and does not reach the server. Useful for isolating and testing a single suspected handler. The connection's Fire/Defer methods may be absent on foreign/C connections, so the call is pcall-guarded. Requires getconnections; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, ConnectionIndex, Fired, Deferred } or { error }. Signature: { instancePath: string, signalName: any?, connectionIndex: any?, defer: any?, args: {{ kind: "string" | "number" | "boolean" | "nil" | "instance" | "raw", value: string | number | boolean? }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getconnections. Produces: created-handle, operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-connection-protosA | Enumerate the inner (proto) functions defined inside the Lua function bound to ONE connection on an RBXScriptSignal (selected by zero-based index) via debug.getprotos. Protos are the nested closures a handler creates — callbacks, deferred tasks, helper lambdas — so this maps out the sub-functions you may want to hook or inspect next. Each proto is reported via the standard function descriptor (Source, Name, LineDefined, NumParams, IsVararg, What, Pointer). Requires getconnections and debug.getprotos; returns a clear { error } if either is missing or the connection has no Lua Function. Returns { Signal, Instance?, ConnectionIndex, Function, Protos: [...], Count }. Signature: { instancePath: string, signalName: any?, connectionIndex: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: structured-observation, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-connections-by-sourceA | Sweep a hierarchy for event handlers and pinpoint which script each handler is defined in. Walks descendants of |
| set-connection-stateA | MUTATES CLIENT STATE. Toggles or removes connections on an RBXScriptSignal: 'disable' temporarily stops a connection from firing (reversible with 'enable'), 'enable' re-activates a disabled connection, and 'disconnect' permanently removes it — IRREVERSIBLE for that connection (you would have to recreate it). scope='one' targets a single connection by index; scope='all' applies to every connection on the signal. Because they are destructive, scope='all' and action='disconnect' BOTH require confirm=true or the tool refuses without changing anything. Useful for silencing or surgically removing event handlers (e.g. anti-cheat or input listeners) while debugging. Requires getconnections plus the connection's Disable/Enable/Disconnect methods; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, Action, Scope, Affected } or { error }. Signature: { instancePath: string, signalName: any?, action: "disable" | "enable" | "disconnect", scope: any?, connectionIndex: any?, confirm: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getconnections. Produces: created-handle, operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-signal-whitelistA | Enumerate the full set of signals the Roblox engine allows to be replicated to the server, using the executor's getsignalwhitelist. This is the global allow-list that can-signal-replicate / replicate-signal check against, so it answers "which signals can I drive server-side?" up front, without probing them one at a time. The whitelist is typically large (180+ entries), so each entry is mapped through a safe serializer and the output is capped at |
| fire-signalA | MUTATES CLIENT STATE. Invokes firesignal(signal, ...) to synchronously fire EVERY local Lua connection currently attached to an RBXScriptSignal, passing the supplied arguments. This is client-side only: it runs the handlers in your own client and does NOT send anything to the server or other players. Useful for exercising a game's own event handlers (e.g. simulating a 'Touched' or a custom BindableEvent) while debugging UI/gameplay logic, without performing the real physical action. NOTE: firesignal invokes the connection functions directly and does NOT respect a connection's Disabled state — disabled connections still run. (A real event, or set-connection-state, does respect Enabled/Disabled.) Requires the executor's firesignal; degrades with a clear { error } if unavailable. Returns { Signal, Instance?, Fired, ArgCount } or { error }. Signature: { instancePath: string, signalName: any?, args: {{ kind: "string" | "number" | "boolean" | "nil" | "instance" | "raw", value: string | number | boolean? }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getconnections, firesignal. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-metatableA | Resolve a Luau expression to ANY value (table, Instance, userdata, etc.) and dump its raw metatable via getrawmetatable (bypassing __metatable locks). For each metamethod it reports the key, value type, and — for function metamethods like __index/__namecall/__newindex — the connected function's source/line/params. Also reports whether the metatable is read-only and whether getmetatable is locked (a string __metatable). Use this to understand how a table/instance is protected or proxied, or to find the __namecall/__index that game security routes through. Unlike inspect-instance-metatable this works on any value, not just Instances. Requires getrawmetatable; returns { Target, TargetType, HasMetatable, ReadOnly, LockedMetatableValue, Metamethods } or { error }. Signature: { objectPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getrawmetatable. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-metamethodA | Resolve a Luau expression to ANY value (table, Instance, userdata, etc.), grab its raw metatable via getrawmetatable (bypassing __metatable locks), and read ONE named metamethod from it (e.g. __index, __namecall, __newindex, __call, __tostring). When the metamethod is a function this deep-dumps it: its info (Lua/C, source, line, params, upvalue count via getinfo) PLUS its constants (getconstants) and upvalues (getupvalues). This is the targeted counterpart to get-metatable: use it to drill into the exact function Roblox's security layer routes through — for example reading __namecall off getrawmetatable(game) to find the C closure that backs FireServer/InvokeServer, then inspecting its constants for method-name strings. For non-function metamethods (locked __metatable strings, __index tables, etc.) it returns the encoded value. Requires getrawmetatable; getconstants/getupvalues are best-effort (omitted if the executor lacks them or the metamethod is a C closure). Returns { Target, Method, Type, Function?, Constants?, Upvalues?, Value? } or { error } when there is no metatable, the method is absent, or getrawmetatable is missing. Signature: { objectPath: string, method: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getrawmetatable. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-readonlyA | Resolve a Luau expression to a table (or a metatable expression) and report whether it is locked read-only via isreadonly. Roblox marks core metatables (e.g. getrawmetatable(game)) and many security tables read-only so __index/__namecall can't be swapped; this tells you whether you'd need setreadonly(t, false) before any mutation would take effect. Use it as a safe, non-mutating pre-check before attempting metatable hooks or constant/upvalue edits — it changes nothing. Typical targets: a plain table from getgenv(), or 'getrawmetatable(game)' to confirm the global instance metatable is frozen. Requires isreadonly; returns { Target, TargetType, ReadOnly } or { error } when the value isn't a table or isreadonly is unavailable. Signature: { targetPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| compare-instancesA | Resolve two Luau expressions and report whether they reference the SAME underlying Roblox instance via compareinstances. This matters because a game (or an executor proxy/clone) can hand you a wrapped userdata whose identity differs from the real Instance even though |
| set-metatable-readonlyA | WRITES LIVE GAME STATE. DANGER — Resolve a Luau expression to a metatable (usually getrawmetatable(obj)) and flip its read-only flag via setreadonly. Most game metatables (e.g. getrawmetatable(game)) are locked read-only so __index/__namecall cannot be overwritten. Pass readonly=false to temporarily unlock a metatable so you can edit a metamethod (or run hook-metamethod), then call this again with readonly=true to RE-LOCK it — leaving a core metatable writable is a classic anticheat tripwire and can crash or destabilize the game. This changes the live runtime; it does not create a copy. Requires setreadonly. Because it mutates state you MUST pass confirm=true; otherwise the tool refuses and does nothing. Returns { Target, ReadOnly, ok } or { error }. Signature: { targetPath: string, readonly: boolean, confirm: boolean, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getrawmetatable. Produces: structured-observation, operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-rawmetatableA | WRITES LIVE GAME STATE. DANGER — Resolve a Luau expression to an object (table/Instance/userdata) and REPLACE its entire metatable via setrawmetatable, bypassing any __metatable lock. This swaps out __index/__namecall/__newindex etc. wholesale, so it can completely change how the object behaves — overwriting the game's core metatable can break the client, sever security routing, and is a strong anticheat signal. Typical RE use: clone the existing metatable, modify a metamethod, then set it back. Note the target metatable may need to be writable (see set-metatable-readonly) before this succeeds. This changes the live runtime in place. Requires setrawmetatable. Because it mutates state you MUST pass confirm=true; otherwise the tool refuses and does nothing. Returns { Target, ok } or { error }. Signature: { objectPath: string, metatableExpr: string, confirm: boolean, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getrawmetatable. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| hook-metamethodA | WRITES LIVE GAME STATE. DANGER — MUTATES STATE PERSISTENTLY. Resolve a Luau expression to an object and replace one of its metamethods (e.g. __namecall, __index, __newindex) with your own function via hookmetamethod. The hook stays active and INTERCEPTS EVERY call routed through that metamethod (for __namecall that is essentially every method call in the game), so a slow, throwing, or mis-behaving hook can hang or crash the client and is a strong anticheat signal. The original metamethod is stored in getgenv().__mcp_hooks under a descriptive key so you can later restore it with restorefunction or by re-hooking the saved original. Your hook function typically wraps the stored original (call it for unhandled cases) and should be a C closure (wrap it in newcclosure) to look native. Requires hookmetamethod. Because it mutates state you MUST pass confirm=true; otherwise the tool refuses and does nothing. Returns { Target, Method, Hooked, OriginalStored } or { error }. Signature: { objectPath: string, method: string, hookFunction: string, confirm: boolean, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: getrawmetatable. Produces: structured-result. Verify with: is-function-hooked. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| inspect-closureA | Resolve a Luau expression to a function and dump everything about it in one call: whether it's a Lua or C closure, its name/source/line/param count/upvalue count (via getinfo), its constants, its upvalues (captured values), its nested-proto count, and its function hash. This is the by-reference counterpart to the gc-scan tools (scan-closures-by-*) — use it when you already have a handle on the function (e.g. a remote's OnClientEvent handler, a metamethod, or |
| get-closure-constantsA | Resolve a Luau expression to a function and dump its constant pool via getconstants. Constants are the literal values the bytecode references — strings, numbers, table keys, global names, and embedded function/method names — so they are the fastest way to fingerprint what a closure does (e.g. spotting a 'FireServer' literal, a remote name, a damage value, or a URL) without reading its source. This is the by-reference companion to the GC-wide scanners (find-functions-by-constant / find-constants-xref): use it once you already hold the function (a remote handler, a metamethod, getsenv(script).fn, etc.). Each entry reports its 1-based Index, Luau Type, and an encoded Value. Requires the executor's getconstants (debug.getconstants); if unavailable a clean { error } is returned. Returns { Target, Info, Constants:[{Index,Type,Value}], Count } or { error }. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-closure-upvaluesA | Resolve a Luau expression to a function and dump its upvalues via getupvalues. Upvalues are the variables a closure captured from its enclosing scope — the live state a function carries with it (config tables, cached remotes, counters, references to other functions, flags). Inspecting them reveals hidden state that source code alone does not show, which is invaluable when reverse-engineering a handler or locating a kill-switch/flag to flip. This is the by-reference companion to find-upvalue-xref. Each entry reports its 1-based Index, Luau Type, and an encoded Value; the same Index is what set-closure-upvalue mutates. Requires the executor's getupvalues (debug.getupvalues); if unavailable a clean { error } is returned. Returns { Target, Info, Upvalues:[{Index,Type,Value}], Count } or { error }. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-closure-protosA | Resolve a Luau expression to a function and enumerate its nested prototypes (protos) via getprotos. Protos are the inner functions defined inside a closure — closures it creates, callbacks it registers, helper functions in its body. Walking protos lets you drill into a top-level script function to reach the exact inner handler you care about (e.g. an anonymous OnClientEvent callback) without scanning the whole GC, and to map a script's internal call structure. For each proto this returns the full __fnInfo (IsLua/IsC, Name, Source, ShortSource, LineDefined, NumParams, IsVararg, NumUpvalues, Pointer) so you can immediately feed a Pointer/path back into the other closure tools. Requires the executor's getprotos (debug.getprotos); if unavailable a clean { error } is returned. Returns { Target, Info, Protos:[__fnInfo...], Count } or { error }. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-script-closureA | Resolve a Luau expression to a LocalScript or ModuleScript Instance and retrieve its compiled main function via getscriptclosure (falling back to getscriptfunction if the executor exposes that name instead). The returned closure is the script's top-level chunk WITHOUT running it — so you can statically analyse a script's bytecode (its constants, upvalues, and nested protos) even when it is protected, never executed, or you don't want its side effects. This is the entry point for static RE of a single script: feed the resulting function into get-closure-constants / get-closure-upvalues / get-closure-protos to drill in. Requires the executor's getscriptclosure (or getscriptfunction); if neither exists a clean { error } is returned. Returns { Script, Function:__fnInfo, ConstantCount, UpvalueCount } or { error }. Signature: { scriptPath: string, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-closure-upvalueA | WRITES LIVE GAME STATE. DANGER — Resolve a Luau expression to a function and overwrite one of its upvalues (a variable captured by the closure) via setupvalue. Use this to patch a function's behavior in place without rehooking it — e.g. flip a captured |
| set-closure-constantA | WRITES LIVE GAME STATE. DANGER — Resolve a Luau expression to a function and overwrite one of its bytecode constants via setconstant. Constants are the literal values baked into a function's bytecode (numbers, strings, the names of globals/methods it calls). Patching one changes the function's behavior the next time it runs — e.g. rewrite a magic number, swap a hardcoded string, or redirect a method call by changing its name constant. This persists for the exact closure and can destabilize the game or trip anticheat; some executors only allow same-type replacement. Index is 1-based and must be within the function's constant count (inspect-closure reports ConstantCount). Requires setconstant. Pass confirm=true to proceed. Returns { Target, Index, ok } or { error }. Signature: { functionPath: string, index: number, value: { kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? }, confirm: boolean, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: debug closure primitives. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| hook-functionA | WRITES LIVE GAME STATE. DANGER — MUTATES STATE PERSISTENTLY. Resolve a target function and replace it with your own function via hookfunction. After hooking, every call to the target — from anywhere in the game — runs your replacement instead. This is the core primitive for intercepting/altering game behavior: log or rewrite arguments, spoof return values, or no-op a check. The hook is GLOBAL and PERSISTS until undone, so it can easily destabilize the game or trip anticheat. The original function is captured and stored in getgenv().__mcp_hooks keyed by the target expression so you can recover it; you (or your replacement) can call the original, and you can fully undo the hook with restorefunction(target). Requires hookfunction. Pass confirm=true to proceed. Returns { Target, Hooked, OriginalStored } or { error }. Signature: { targetPath: string, hookFunction: string, confirm: boolean, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: is-function-hooked. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-script-envA | Resolve an instance path to a running LocalScript/ModuleScript and dump its script environment table via getsenv. This is the live _ENV of that script: its globals, every top-level local it exposed as a global, and the functions/values it defined. Use it to discover what a script holds (config flags, references, handler functions) so you can then inspect or hook them by reference (e.g. feed getsenv(script).someFunc into inspect-closure or hook-function). The script must be currently running for getsenv to succeed. Requires getsenv. Returns { Script, KeyCount, Truncated, Keys } (keysOnly) or { Script, KeyCount, Truncated, Entries } or { error }. Signature: { scriptPath: string, keysOnly: any?, maxKeys: any?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-function-envA | Resolve a Luau expression to a function and dump its function environment table via getfenv. This is the _ENV the function reads its globals from: the global table the closure sees (often the script's environment, or a sandboxed proxy). Use it to learn what globals a handler can reach, to spot a sandbox/proxy environment, or to discover sibling functions you can then inspect or hook by reference. Read-only. Requires getfenv. Returns { Target, KeyCount, Truncated, Keys } (keysOnly) or { Target, KeyCount, Truncated, Entries } or { error }. Signature: { functionPath: string, keysOnly: any?, maxKeys: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-hooksA | List every function/metamethod hook installed through hook-function / hook-metamethod in this session. Each entry shows the key (pass it to restore-hook to undo), the kind (function or metamethod), the target expression, the metamethod name (if any), and the type of the stored original. Use this to audit what you've hooked before restoring — important because hooks are global and persistent. Reads getgenv().__mcp_hooks. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Verify with: is-function-hooked. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| restore-hookA | WRITES LIVE GAME STATE. Undo a hook created by hook-function / hook-metamethod, restoring the captured original. Pass a |
| closure-capabilitiesB | Read-only capability matrix for the official Volt closure library plus the MCP's useful debug closure operations. Reports the selected alias for every primitive without calling it. Signature: { threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| check-callerA | Call Volt checkcaller in the active executor thread. This normally reports true for a direct MCP call and is most useful as a capability/behavior probe before installing a hook. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| clone-functionA | Clone a function with clonefunction/clonefunc. The function result is retained in getgenv().__mcp_closure_refs and returned as a reusable Reference expression because functions cannot cross JSON. Signature: { functionPath: string, threadContext: number?, key: any? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-function-hashA | Resolve a function and return getfunctionhash(fn), useful for stable comparison and change detection. Volt only supports bytecode hashing for Luau closures; C closures return a clean executor error. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-c-closureB | Resolve a function and call iscclosure with guarded metadata. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-l-closureB | Resolve a function and call islclosure with guarded metadata. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-executor-closureB | Call isexecutorclosure with checkclosure/isourclosure aliases to distinguish executor-created closures from game closures. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-function-hookedB | Resolve a function and call isfunctionhooked before hooking/restoring it. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Verify with: is-function-hooked. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-new-c-closureC | Call isnewcclosure with the iscustomcclosure alias when available. Signature: { functionPath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: structured-observation, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| new-c-closureA | Call newcclosure(function, debugName?) and store the wrapper under getgenv().__mcp_closure_refs, returning a reusable Reference expression and closure metadata. Signature: { functionPath: string, threadContext: number?, key: any?, debugName: any? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| new-l-closureA | Call newlclosure(function) and store the wrapper under getgenv().__mcp_closure_refs, returning a reusable Reference expression and closure metadata. Signature: { functionPath: string, threadContext: number?, key: any? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: debug closure primitives. Produces: created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| restore-functionA | WRITES LIVE GAME STATE. Resolve a target and call restorefunction/restorefunc directly. Unlike restore-hook, this also restores hooks not installed through the MCP registry. Requires confirm=true. Signature: { functionPath: string, threadContext: number?, confirm: boolean? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: is-function-hooked. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-stack-hiddenB | WRITES LIVE GAME STATE. Call setstackhidden(function, hidden) to alter runtime stack/debug visibility. This can make diagnostics incomplete, so it is confirmation-gated and should be restored with hidden=false after use. Signature: { functionPath: string, threadContext: number?, hidden: boolean, confirm: boolean? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: is-function-hooked. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| invoke-closureA | WRITES LIVE GAME STATE. Invoke an arbitrary live function expression with up to 24 typed arguments and return up to 20 encoded results. Function calls may have side effects, so confirm=true is mandatory. Signature: { functionPath: string, threadContext: number?, arguments: any?, confirm: boolean? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: debug closure primitives. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-function-envA | WRITES LIVE GAME STATE. Resolve a function and an environment-table expression, then call setfenv. This changes global lookup behavior for the live closure and requires confirm=true. Signature: { functionPath: string, threadContext: number?, environmentExpression: string, confirm: boolean? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-closure-referencesA | Read the bounded getgenv().__mcp_closure_refs registry created by clone-function/new-c-closure/new-l-closure and return reusable expressions plus function metadata. Signature: { limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| release-closure-referenceA | WRITES LIVE GAME STATE. Remove one key from getgenv().__mcp_closure_refs so cloned/wrapped closures can be garbage-collected. This invalidates its returned Reference and requires confirm=true. Signature: { key: string, confirm: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: debug closure primitives. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-stringsA | Walk every Luau function in the GC and collect their string constants — the runtime equivalent of IDA's Strings window. Reports each unique string, how many functions reference it (xref count), and a sample owning script, sorted by frequency. Filter by substring and minimum length to cut noise. Great for finding interesting literals (remote names, URLs, error messages, anti-cheat tags) and then pivoting with find-string-xrefs. Requires getgc + getconstants; caps the scan and flags truncation. Signature: { filter: any?, minLength: any?, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-string-xrefsA | Cross-reference a string the way IDA jumps from a string literal to every place it is used. Walks every Luau function in the GC and reports each function that has the query as a string constant in its bytecode — i.e. each function that likely produces or compares against that text. Use exact=true for an exact match, otherwise it does a plain substring search (case-sensitive). Each hit reports the owning script source, line, function name and pointer, plus the first matching constant. Great for pivoting from list-strings to the code that references a remote name, URL, error message, or anti-cheat tag. Requires getgc + getconstants; caps the scan and flags truncation. Signature: { query: string, exact: any?, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-global-xrefsA | Find functions that likely call or reference this global or method by name. Luau bytecode stores global lookups and method names (e.g. FireServer, require, loadstring, HttpGet, GetService) as string constants, so this walks every function in the GC and reports each one whose constants contain the exact name string. This is the IDA xref-to-import equivalent: pivot from a sensitive API to all the code that uses it. Each hit reports the owning script source, line, function name and pointer. Requires getgc + getconstants; caps the scan and flags truncation. Signature: { name: string, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-functions-by-complexityA | Rank every Luau function in the GC by complexity so you know where to start reverse-engineering — the biggest, most interesting functions usually carry the core logic. For each function it counts the number of constants, upvalues, and nested protos, then returns the top |
| find-function-xrefsA | Resolve a target Luau FUNCTION from an expression, then walk every function in the GC and report which ones REFERENCE it — the runtime equivalent of IDA's 'cross references to' on a sub. A referrer references the target if the target appears in its upvalues (closures that captured it) OR among its nested protos (functions that embed it as an inner function). Each xref reports __fnInfo (ptr/name/source/line/nparams/nups) plus 'via' ("upvalue" or "proto"). The target itself is skipped. Requires getgc + getupvalues/getprotos; caps the scan and flags truncation. Pivot from list-gc-functions or lookup-function to get an expression that resolves here. Signature: { functionPath: string, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-instance-xrefsA | Resolve a target Instance from a Luau expression, then walk every function in the GC and report which ones hold a reference to it — the runtime equivalent of IDA's data cross-references on a global object. A referrer references the instance if it appears in the function's upvalues OR constants. Answers 'which functions read, manipulate, or watch this object?'. Each xref reports __fnInfo (ptr/name/source/line/nparams/nups) plus 'via' ("upvalue" or "constant"). Requires getgc + getupvalues/getconstants; caps the scan and flags truncation. Signature: { instancePath: string, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-remote-xrefsA | Resolve a RemoteEvent / RemoteFunction / BindableEvent / BindableFunction from a Luau expression, then walk every function in the GC and report which ones reference it — the runtime equivalent of cross-referencing a network endpoint. A referrer references the remote if it appears in the function's upvalues OR constants, which surfaces the closures that FireServer/InvokeServer/OnClientEvent-connect this remote. Each xref reports __fnInfo (ptr/name/source/line/nparams/nups) plus 'via' ("upvalue" or "constant"); the response includes the remote's ClassName. Requires getgc + getupvalues/getconstants; caps the scan and flags truncation. Signature: { remotePath: string, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| build-call-graphA | Build an IDA-style call graph (function tree) rooted at a target Luau function. Each Luau function carries its nested protos — the functions it can construct and call — so this recurses through getprotos breadth-first to map the callee tree. Returns a FLATTENED node list (each node knows its parentIndex and depth) so you can reconstruct the tree, plus per-node proto/upvalue counts and source/line from debug.info. Use it to understand how a closure fans out into helpers, spot deeply nested logic, and pick disassembly targets. Resolve the root via a Luau expression (e.g. "getrenv().game.PlayerScripts.Main.someFunc" or a global). Requires getprotos; caps depth and node count. Signature: { functionPath: string, maxDepth: any?, maxNodes: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| disassemble-functionA | Produce a full IDA-style dump of a single Luau function in one call: debug.info (name/source/line/params/ups), whether it is a Lua or C closure (islclosure/iscclosure), constant/upvalue/proto counts, the executor function hash (getfunctionhash) for duplicate-detection, and — optionally — the full constant and upvalue tables with their typeof and a string value (Instances become GetFullName, functions become tostring). Complements inspect-closure by bundling the hash and the structural counts into one reverse-engineering-focused view. Resolve the target via a Luau expression that yields a function; each list is capped at 200 entries. Signature: { functionPath: string, includeConstants: any?, includeUpvalues: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-duplicate-functionsA | Walk every Luau function in the GC, hash each one with getfunctionhash, and group functions that share the exact same hash — the runtime equivalent of IDA's 'find identical functions'. Reveals clones and copy-pasted code (duplicated module logic, repeated handlers, library functions instantiated many times). Each group reports the shared hash, how many functions carry it, and a few sample functions (ptr/name/source/line). Requires getgc + getfunctionhash; caps the scan and flags truncation. Signature: { minGroup: any?, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| search-bytecodeA | Scan every script returned by getscripts(), dump each one's compiled bytecode with getscriptbytecode, and find scripts whose bytecode contains a given hex byte pattern — the runtime equivalent of an IDA binary/byte search. Use it to locate scripts carrying a known opcode signature, constant blob, or fingerprint. Provide the pattern as a hex byte string (e.g. '1a2b3c' or '1a 2b 3c'); it is normalized (spaces stripped, lowercased) and must be an even number of hex digits. Each match reports the script's full name, class, and the byte offset of the first hit. Requires getscripts + getscriptbytecode; caps the scan and flags truncation. Signature: { hexPattern: string, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Capabilities: getscriptbytecode. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-upvalue-sharingA | Walk every Luau function in the GC and, for each function, inspect its upvalues. Whenever an upvalue is a TABLE, record the owning function under that table's identity. After scanning, report tables that are shared as an upvalue by several distinct functions — these are typically the shared state / private module table of a single closure family, so the functions that share it belong to the same module or factory. This is how you cluster functions that were defined together (a module's methods all close over the same private table). Each entry reports the table identity, how many functions share it, and a few sample functions. Requires getgc + getupvalues; caps the scan and flags truncation. Signature: { minGroup: any?, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-gc-tablesB | Enumerate table objects from getgc(true) with optional key/value query matching. Signature: { query: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getgc. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-gc-threadsA | Enumerate thread objects from getgc(true), including coroutine status where available. Signature: { limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getgc. Produces: bounded-candidates, structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-registry-objectsA | Inspect debug.getregistry() and summarize object types for runtime reversing. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| inspect-instance-metatableA | Get metatable keys from a target Instance path (e.g., game.Players.LocalPlayer). Signature: { instancePath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getrawmetatable. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-runtime-modulesA | Find ModuleScripts in game + nil instances and report metadata for reversing. Signature: { includeNil: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates, operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-module-scriptsA | Search ModuleScripts by substring against name/full path. Signature: { query: string, limit: any?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-module-sourceB | Decompile a specific ModuleScript by path. Signature: { modulePath: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: decompile. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| trace-require-callersA | Find functions that reference 'require' in constants/source via getgc scan. Signature: { limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-event-snapshot, operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-event-connectionsA | Inspect RBXScriptSignal connections by instance path + signal name. Signature: { instancePath: string, signalName: string, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getconnections. Produces: bounded-candidates, created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-remote-listenersA | List RemoteEvent/RemoteFunction objects and listener counts from connection APIs. Signature: { limit: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-constants-xrefA | Find getgc functions containing a target constant and return compact xrefs. Signature: { constantQuery: string, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-upvalue-xrefA | Find functions whose upvalue names or values match a query. Signature: { query: string, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-proto-functionsA | Use debug.getprotos over matched functions and return proto summaries. Signature: { query: any?, limit: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-function-protosC | Find a function by query and dump nested proto debug info. Signature: { query: string, maxProtos: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| dump-function-envB | Find function by query and inspect environment table keys/values. Signature: { query: string, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-global-env-keysA | List keys from getgenv/_G with type/value previews. Signature: { query: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-hook-surfacesA | Check availability of common exploit/debug hook APIs and return capability map. Signature: { threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Verify with: is-function-hooked. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-network-endpointsA | Find URL-like strings in function constants across getgc closures. Signature: { limit: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-path-referencesA | Find constants containing instance path fragments like ReplicatedStorage/Workspace. Signature: { query: string, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-script-actorsA | List Actor instances and contained LuaSourceContainer scripts for actor-based reverse analysis. Signature: { limit: any?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getactors. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-bytecode-size-outliersA | Scan scripts and rank by getscriptbytecode size to find complex/high-value targets quickly. Signature: { limit: any?, includeModules: any?, includeLocalScripts: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Capabilities: getscriptbytecode. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-closures-by-sourceA | Find getgc closures whose debug source contains a target substring. Signature: { sourceQuery: string, limit: any?, includeCClosures: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Capabilities: getgc, debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| scan-closures-by-nameB | Find getgc closures whose debug name contains a target substring. Signature: { nameQuery: string, limit: any?, includeCClosures: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Capabilities: getgc, debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| summarize-runtime-surfacesA | Quick high-level reverse summary: counts for scripts/modules/remotes/actors/functions/tables/threads. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-gc-functionsA | Enumerate live Lua closures from getgc() and return debug metadata (name/source/line/upvalues). Useful for live reversing when script paths are unknown. Signature: { nameQuery: string?, sourceQuery: string?, includeCClosures: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getgc. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| lookup-functionB | Search live functions by name/source/constant text and return enriched debug metadata for reverse engineering. Signature: { query: string, mode: any?, limit: any?, includeCClosures: any?, includeConstantsPreview: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-function-upvaluesB | Find matching functions in getgc() and dump their upvalues for live reverse engineering. Signature: { query: string, sourceQuery: string?, maxFunctions: any?, maxUpvalues: any?, includeCClosures: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-functions-by-constantA | Scan getgc() and find closures whose constants contain a target string/number. Useful for locating handlers and hidden logic by magic constants. Signature: { constantQuery: string, limit: any?, includeCClosures: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: debug closure primitives. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| compare-gc-snapshotsA | Take a census of the garbage collector (getgc) and diff it over time to find what was allocated or freed between two points - a leak-hunting / behaviour-attribution tool. Workflow: call with action='capture' (a baseline), perform some action in-game (open a menu, fire a remote, etc.), then call with action='compare' (same snapshotName) to see what changed. Snapshots are stored CLIENT-SIDE in getgenv().__mcp_gc_snapshots[name], so they live in the target game and are naturally isolated per game / per session. capture returns: { action='capture', name, ts, counts={ function, table, thread, total }, fnSampled, truncated }. compare returns: { action='compare', name, baselineTs, nowTs, countDeltas={ function, table, thread, total }, newFunctions=[..pointers..], newFunctionCount, freedApprox (functions no longer present), sampledOnly, truncated }. Caps: at most 200000 GC objects are walked per pass and at most 4000 function pointers are remembered; results note when truncation occurred, so treat large freed/new counts near the cap as approximate. Signature: { action: "capture" | "compare", snapshotName: any?, threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getgc. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-instance-propertyA | WRITES LIVE GAME STATE. Resolve a Luau expression to an Instance and assign one of its properties, returning both the OLD and NEW value so the change is auditable. Common uses while debugging: toggle a GUI's Visible, bump a character's Humanoid WalkSpeed/JumpPower, set a part's Transparency/Anchored/CanCollide, or write an IntValue/StringValue's Value. For non-primitive property types (Vector3, CFrame, Color3, UDim2, Enum, Instance references) use value.kind='raw' and pass a Luau expression. The read of the old value and the write are each pcall-guarded. WARNING: this mutates the running game on the client — the change takes effect immediately and may replicate. Returns { Path, Property, OldValue, NewValue, ok } or { error }. Signature: { instancePath: string, propertyName: string, value: { kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? }, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: get-instance-properties. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-attributeA | WRITES LIVE GAME STATE. Resolve a Luau expression to an Instance and write one of its custom attributes via inst:SetAttribute(name, value), returning both the OLD and NEW value so the change is auditable. Attributes are the named, typed key/value pairs games store on instances (visible in the Studio Attributes panel and read with :GetAttribute) — distinct from engine properties (use set-instance-property for those). Common uses while debugging: flip a 'IsAdmin'/'Frozen' boolean attribute, bump a 'Cooldown'/'Damage' number, or set a 'State' string. For non-primitive attribute types use value.kind='raw'; use kind='nil' to DELETE the attribute. The read of the old value and the write are each pcall-guarded. WARNING: this mutates the running game on the client — the change takes effect immediately and may replicate, and game scripts listening on GetAttributeChangedSignal will fire. Returns { Path, Attribute, OldValue, NewValue, ok } or { error }. Signature: { instancePath: string, attributeName: string, value: { kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? }, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: get-instance-properties. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-properties-bulkA | WRITES LIVE GAME STATE. Resolve a Luau expression to a single Instance ONCE, then apply a list of property writes to it in order. For each property the OLD value is read, the new value is written, and the NEW value is read back — each step pcall-guarded so one bad property never aborts the others. This is the efficient way to reconfigure an instance with several changes at once (e.g. make a Part Anchored + CanCollide=false + Transparency=0.5 + a new Size in one round-trip) instead of issuing many set-instance-property calls. The writes happen sequentially within the same execution so the result is effectively atomic from the game's perspective for that frame. WARNING: this mutates the running game on the client — changes take effect immediately and may replicate. Returns { Path, results:[{ name, OldValue, NewValue, ok, error? }], okCount, failCount }, or { error } if the instance itself cannot be resolved. Signature: { instancePath: string, properties: {{ name: string, value: { kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? } }}, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: get-instance-properties. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| create-instanceA | WRITES LIVE GAME STATE. Construct a brand-new Instance via Instance.new(className), optionally set its Name and a list of initial properties, and optionally parent it into the game tree. Useful while debugging for spawning a Part, a Highlight/BillboardGui ESP marker, a Folder, a Value object (IntValue/StringValue/BoolValue), or any other class. PROCESS: Instance.new is pcall-guarded (returns a clean error if className is invalid); Name is set if provided; each property is set independently and pcall-guarded so one bad property does not abort the others (failures are collected into propErrors); Parent is set LAST (only if parentPath is given) so all properties are applied before the instance becomes live in the tree. If you do NOT pass parentPath the instance is created but left parentless (nil) — it still exists in memory and can be parented later via set-instance-property on its Parent. WARNING: a parented instance immediately affects the running game and may replicate. Returns { Created, ClassName, Parented, propErrors, ok } or { error }. Signature: { className: string, name: string?, parentPath: string?, properties: {{ name: string, value: { kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? } }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: created-handle. Verify with: get-instance-properties. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| clone-instanceA | WRITES LIVE GAME STATE. Resolve a Luau expression to a source Instance, deep-copy it via source:Clone() (which duplicates the instance and all of its descendants), and optionally parent the clone into the game tree. Useful while debugging for duplicating a template Part/Model/GUI, spawning extra copies of an item, or capturing a snapshot of a subtree before mutating the original. The clone starts parentless; it is parented LAST and only if parentPath is provided. NOTE: :Clone() only succeeds when the source's Archivable property is true — a clone of a non-Archivable instance returns nil and yields a clean error. WARNING: a parented clone immediately affects the running game and may replicate. Returns { Source, Clone, Parented, ok } or { error }. Signature: { instancePath: string, parentPath: string?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: created-handle. Verify with: get-instance-properties. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| destroy-instanceA | WRITES LIVE GAME STATE. Resolve a Luau expression to an Instance and permanently remove it from the game via inst:Destroy(). Destroy() unparents the instance and ALL of its descendants, disconnects their events, and locks their Parent so they can never be re-parented — the subtree is gone. The instance's full path and ClassName are captured BEFORE destruction so the response records exactly what was removed. WARNING: THIS IS IRREVERSIBLE — there is no undo; you cannot get the instance back (use clone-instance first if you might need a copy). Destroying a player's Character, a critical service child, or a script can break the running game and may replicate to the server. Only destroy instances you are certain about. Returns { Destroyed, ClassName, ok } or { error }. Signature: { instancePath: string, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: verify-path-exists. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| invoke-methodA | ACTS ON LIVE GAME STATE. Resolve a Luau expression to an Instance and call one of its methods as a colon-call (inst:Method(args...)), returning whatever the method returns. Useful while debugging for :Destroy(), :GetChildren(), :FindFirstChild(name), :Clone(), :GetAttribute(name), :SetAttribute(name, value), :WaitForChild(name), Humanoid:TakeDamage(n), Humanoid:MoveTo(pos), Tool:Activate(), etc. Each argument is a typed value; use kind='raw' for non-primitive arguments (Vector3, Enum, Instance, ...). The call is pcall-guarded. WARNING: many methods MUTATE the game (e.g. :Destroy(), :SetAttribute, :TakeDamage) and the effect is immediate and may replicate — only call methods you understand. Returns { Path, Method, ok, ReturnValues } or { error }. Signature: { instancePath: string, methodName: string, args: {{ kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| fire-remoteA | ACTS ON LIVE STATE — CAN REACH THE SERVER. Resolve a Luau expression to a remote object (RemoteEvent / UnreliableRemoteEvent / RemoteFunction / BindableEvent / BindableFunction) and call it with the chosen mode and arguments. Modes: FireServer / InvokeServer (RemoteEvent / RemoteFunction → travel to the SERVER), FireAllClients / FireClient (server→client, only valid from the server side), Fire (BindableEvent → local listeners), and Invoke (BindableFunction → local handler, returns a value). InvokeServer and Invoke return the call's return values. The call is pcall-guarded. WARNING: FireServer, InvokeServer and FireClient cross the network boundary and trigger REAL server-side / other-client logic (granting items, taking damage, purchases, etc.) — only use this to test a game you own/control, never to affect other players. Returns { Remote, Mode, ok, ReturnValues? } or { error }. Signature: { remotePath: string, mode: "FireServer" | "InvokeServer" | "FireAllClients" | "FireClient" | "Fire", args: {{ kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| dump-tableA | Resolve a Luau expression to a TABLE and recursively encode its contents to a chosen depth. Scalar, Instance and function values are encoded via the shared encoder; nested tables are recursed into until maxDepth, after which they collapse to 'table: (truncated)'. Each level is capped at maxKeys (the cap is noted via a per-level Truncated flag), and cycles are detected so self-referential tables won't loop forever. Ideal for reading config tables, getgenv()/getrenv() subtables, a ModuleScript's return value, or any captured upvalue table you already have a handle on. WARNING: this ACTS ON THE LIVE GAME — it evaluates your expression in the running client, which may trigger __index metamethods or other side effects while iterating. Returns { Target, Depth, Table:, Truncated } or { error }. Signature: { tablePath: string, maxDepth: any?, maxKeys: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-thread-stackA | Walk the call stack of a Luau thread/coroutine frame-by-frame using debug.info. For each level it reports the function Name, Source, and Line (debug.info(thread, level, 'nsl')), stopping when the stack is exhausted. If threadPath is omitted it traces the CURRENT injected thread instead, using debug.info(level, 'nsl'). A debug.traceback() string is also included when available. Use this to see exactly where a suspended coroutine or an event handler's thread is currently executing — e.g. pass a connection's .Thread, a stored coroutine, or leave it blank to inspect your own execution context. WARNING: this ACTS ON THE LIVE GAME — it evaluates your threadPath expression and introspects live thread state in the running client. Returns { Thread?, FrameCount, Frames:[{ Level, Name, Source, Line }], Traceback? } or { error }. Signature: { threadPath: string?, maxLevels: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-gui-elementsA | Enumerate the live GUI tree under a root Instance (defaults to the LocalPlayer's PlayerGui) and return a flat list of every GuiObject it contains. This is the fastest way to discover what UI is actually on screen — the exact paths, classes and current Text — so you can then read or drive a specific element with get-gui-text, set-gui-text, click-button or type-text-box. Walks root:GetDescendants() with each property access pcall-guarded so a single hostile element never aborts the scan. For every descendant that is (or, with classFilter, exactly matches) a GuiObject it records { path = GetFullName(), class = ClassName, name = Name, Visible, Text } where Visible and Text are only present when readable. Output is capped at |
| get-gui-textA | Resolve a Luau expression to a single GUI Instance and return whichever text properties it actually exposes: .Text (the editable/displayed string on TextLabels, TextButtons and TextBoxes), .ContentText (the rendered text after rich-text/markup processing) and .PlaceholderText (the grey hint shown by an empty TextBox). Use this to inspect exactly what a label says or what a player has typed before acting on it. Each property read is independently pcall-guarded, so missing properties are simply omitted rather than erroring — a Frame with no text fields returns just { Path }. Pair with list-gui-elements to first discover the path. Returns { Path, Text?, ContentText?, PlaceholderText? } or { error }. Signature: { path: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-gui-textA | WRITES LIVE GAME STATE. Resolve a Luau expression to a GUI Instance and overwrite its .Text property, returning both the OLD and NEW text so the change is auditable. Use this to directly poke a value into a TextLabel, TextButton or TextBox without simulating keystrokes — e.g. to pre-fill a login/search box or change a label while debugging UI logic. This sets the raw .Text directly and does NOT fire FocusLost / text-changed input events, so scripts that react only to player typing may not run; use type-text-box with useKeyPress when you need real keystroke side-effects. The read of the old text and the write are each pcall-guarded. WARNING: this mutates the running client UI immediately. Returns { Path, OldText, NewText, ok } or { error }. Signature: { path: string, text: string, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: get-gui-text. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| click-buttonA | WRITES LIVE GAME STATE. Click a Roblox TextButton or ImageButton by firing its GUI signals via firesignal, exactly as if the local player clicked it — so any handler connected to the button runs. Use when direct UI activation is needed inside the active client. Resolves the path to a GuiButton, then either fires the single named action signal or, when action is omitted, fires every standard click signal (Activated, MouseButton1Down, MouseButton2Down, MouseButton1Click, MouseButton2Click). Requires the executor's firesignal; degrades with a clear { error } if unavailable. Returns { Path, Fired, ok } or { error }. Signature: { path: string, action: string?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: firesignal. Produces: structured-result. Verify with: get-gui-text. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| type-text-boxA | WRITES LIVE GAME STATE. Enter text into a Roblox TextBox by path. Resolves the path to a TextBox, captures its focus, then either simulates real keystrokes (useKeyPress=true, via VirtualInputManager:SendTextInput with a keypress/keyrelease fallback) so text-changed and FocusLost handlers run, or directly sets the .Text property (useKeyPress=false). Optionally presses Enter afterwards and releases focus. Use the keystroke path when scripts react to player typing; use the direct path for a fast value poke. Returns { Path, ok } or { error }. Signature: { path: string, text: string, enter: any?, useKeyPress: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: VirtualInputManager. Produces: structured-result. Verify with: get-gui-text. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| fire-proximity-promptA | WRITES LIVE GAME STATE. Resolve a Luau expression to a ProximityPrompt and trigger it via the executor's fireproximityprompt, exactly as if the local player walked up and held the prompt's key to completion. This bypasses distance, hold-duration, line-of-sight and Enabled checks and fires the prompt's Triggered signal, so any server logic bound to it runs (open a door, buy an item, pick up an object). Use it to drive interaction-gated game flow during automation/testing. Guards that fireproximityprompt exists in this executor and that the target is actually a ProximityPrompt before firing; the fire call is pcall-guarded. WARNING: this mutates the running game and the effect may replicate to the server. Returns { Path, ok } or { error }. Signature: { path: string, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: fireproximityprompt. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| fire-click-detectorA | WRITES LIVE GAME STATE. Resolve a Luau expression to a ClickDetector and trigger it via the executor's fireclickdetector, exactly as if the local player clicked the part it is attached to. This bypasses MaxActivationDistance and line-of-sight and fires the MouseClick signal, so any server/client logic bound to the detector runs (buy buttons, levers, clickable doors, NPC dialogs). Use it to drive click-gated game flow during automation/testing. Guards that fireclickdetector exists in this executor and that the target is actually a ClickDetector before firing; the fire call is pcall-guarded. WARNING: this mutates the running game and the effect may replicate to the server. Returns { Path, ok } or { error }. Signature: { path: string, distance: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: fireclickdetector. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| press-keyA | WRITES LIVE GAME STATE. Simulate a real keyboard key press/release in the running client via VirtualInputManager, so anything listening for keyboard input runs: UserInputService.InputBegan/InputEnded, ContextActionService bindings, default movement, and keybound abilities. The key string is resolved against Enum.KeyCode (e.g. 'E', 'Space', 'W', 'LeftShift', 'F'); an unknown name returns a clean error listing what you passed. Sends KeyDown immediately, optionally holds for holdSec seconds (via task.wait) to emulate a held key, then sends KeyUp. NOTE: VirtualInputManager:SendKeyEvent only works from an exploit/elevated context (injected executor thread) — in an ordinary game script it is locked and will error. Getting the service and each SendKeyEvent are pcall-guarded. WARNING: this drives real input into the game and may move the character or trigger abilities. Returns { key, ok, error? }. Signature: { key: string, holdSec: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: VirtualInputManager. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| virtual-inputA | WRITES LIVE GAME STATE. Send keyboard, mouse, touch, or gamepad input into the active Roblox client. This is the broad low-level input surface: keyDown/keyUp/keyPress use Enum.KeyCode, mouseMove supports absolute or relative movement, mouseButton supports down/up/click, mouseWheel sends a wheel delta, touch sends Begin/Change/End, and gamepadButton/gamepadAxis target a gamepad. VirtualInputManager is preferred; common executor mouse/key fallbacks are used when available. Calls into VirtualInputManager are wrapped with newcclosure when the executor provides it. Unsupported executor APIs return a structured error rather than silently claiming success. Use press-key for the simpler keyboard-only case. Signature: { action: "keyDown" | "keyUp" | "keyPress" | "mouseMove" | "mouseButton" | "mouseWheel" | "touch" | "gamepadButton" | "gamepadAxis", key: string?, x: number?, y: number?, relative: any?, button: any?, buttonAction: any?, delta: any?, holdSec: any?, touchId: any?, touchState: any?, gamepad: any?, gamepadButton: string?, gamepadDown: any?, axis: string?, axisX: any?, axisY: any?, axisZ: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: VirtualInputManager. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| camera-controlA | WRITES LIVE GAME STATE. Read the active camera or set its CFrame, position/look-at target, FieldOfView, and optional CameraType. Use this to reproduce camera movement and aim states in the local client. The tool only changes the local CurrentCamera; it does not move the character or replicate a camera state to the server. For a one-shot read, use action=get. For movement, action=setCFrame requires position and either lookAt or rotation in degrees. Existing camera properties are returned so the change is auditable. Signature: { action: "get" | "setCFrame" | "setFov", position: { x: number, y: number, z: number }?, lookAt: { x: number, y: number, z: number }?, rotation: { pitch: number, yaw: number, roll: number }?, fov: number?, cameraType: "Fixed" | "Attach" | "Watch" | "Track" | "Follow" | "Custom" | "Scriptable" | "Orbital"?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-remotesA | Read-only inventory of every remote/bindable object in a part of the game tree. Resolves |
| get-remote-signatureA | Read-only inspection of ONE remote or bindable to learn how it is used WITHOUT firing it or installing any hook. Resolves |
| monitor-remoteA | WRITES LIVE GAME STATE on start. Starts the selected engine if needed and opens a view for one remote instance. fetch reads retained captures since the view started; stop closes the view while shared capture continues. Starting a different engine stops the previous spy on this client. No additional game hooks are installed for views. Signature: { engine: "cobalt" | "ketamine"?, action: "start" | "fetch" | "stop", remotePath: string?, direction: any?, limit: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| trace-remote-trafficA | WRITES LIVE GAME STATE on start. Starts/adopts the selected engine and opens a traffic view. fetch reads retained captures since start; stop closes only the view. Direction is selected on start. Shares the bounded buffer with all spy tools for this engine. Starting another engine stops the previous spy on this client. Signature: { engine: "cobalt" | "ketamine"?, action: "start" | "fetch" | "stop", direction: any?, limit: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| inspect-callbacksA | Find and disassemble the invoke callbacks bound to RemoteFunctions and BindableFunctions — these are where a game's request/response logic lives (the server-authoritative answer to a client question, or a cross-script RPC), so they are frequently the single most valuable functions to reverse. Unlike signal events (OnClientEvent/OnServerEvent), invoke callbacks are stored as a hidden property on the instance and are NOT visible to getconnections; the ONLY way to retrieve them is getcallbackvalue. This tool walks a subtree (default the whole DataModel), and for every RemoteFunction reads its OnClientInvoke and OnServerInvoke slots, and for every BindableFunction reads its OnInvoke slot. For each slot that actually holds a function it captures debug.info (source / line-defined / name) so you can immediately pivot to inspect-closure, get-closure-constants, get-closure-upvalues, scan-proto-functions, or hook-function on the exact callback. Use the source/line to locate the defining script and the name to understand intent. Requires getcallbackvalue (returns a clean { error } if the executor lacks it). The scan is fully pcall-guarded (locked/parented-out/dead instances never abort it), capped by maxScan, and the output is capped by limit with a |
| ensure-remote-spyA | WRITES LIVE GAME STATE. Starts the selected engine (default cobalt), stopping the other spy on this client first. Cobalt is bundled; Ketamine is downloaded from a pinned upstream commit and hash-checked before loading. Ketamine requires hookfunction, hookmetamethod, getnamecallmethod, getcallbackvalue, setfenv, and crypt.hash. Idempotently attaches one capture observer. RakNet is Cobalt-only. max bounds the MCP buffer, separate from GUI history. Use remote-spy operation=restart for mode changes. Signature: { engine: "cobalt" | "ketamine"?, mode: any?, max: number?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-remote-spy-logsA | Reads bounded captures from the selected engine without loading it. Query filters by direction, remoteId/path, method, class, blocked-only, name, and afterId cursor affect this read only; use configure-remote-spy for persistent capture filters. Typed argument snapshots preserve nil arity and binary previews. Cobalt supplies available RakNet/actor metadata and results; Ketamine captures request arguments only. gap reports expired history. IDs are scoped to the engine and generation. Signature: { engine: "cobalt" | "ketamine"?, limit: any?, afterId: number?, direction: any?, remotePath: string?, remoteId: string?, nameFilter: string?, method: string?, classFilter: "RemoteEvent" | "UnreliableRemoteEvent" | "RemoteFunction"?, blockedOnly: boolean?, raknetOnly: boolean?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: bounded-event-snapshot, structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| clear-remote-spy-logsB | WRITES LIVE GAME STATE. Clears the selected engine's MCP buffer and GUI history while retaining block/ignore settings and continuing capture. Call IDs remain monotonic. Signature: { engine: "cobalt" | "ketamine"?, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, explicit-mutation-approval. Produces: bounded-event-snapshot, operation-receipt. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| block-remoteA | WRITES LIVE GAME STATE. Reversibly sets the selected spy's block state for an observed remoteId or Luau remotePath, in the selected direction. blocked=false undoes it. Ketamine supports outgoing remotes and incoming RemoteFunction callbacks; incoming RemoteEvent blocking returns an explicit unsupported error. Both-direction requests are validated before changing any state. Signature: { engine: "cobalt" | "ketamine"?, remotePath: string?, remoteId: string?, direction: any?, blocked: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| ignore-remoteA | WRITES LIVE GAME STATE. Reversibly ignores captures for an observed remoteId or Luau remotePath in the selected engine/direction. ignored=false undoes it. Calls continue executing. Ketamine suppresses MCP captures; Cobalt suppresses its engine/MCP history. Signature: { engine: "cobalt" | "ketamine"?, remotePath: string?, remoteId: string?, direction: any?, ignored: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| remote-spyA | WRITES LIVE GAME STATE. Controls the selected spy: lifecycle, configure, pause/resume, clear, block/unblock, ignore/unignore, and reset-controls. Select engine=cobalt (default) or ketamine. status reports effective capture/GUI settings and capabilities; controls lists active block/ignore rules with limit/offset and direction filters. reset-controls clears block/ignore rules in the selected direction, preserving history and capture settings; Ketamine GUI ignore rules span Both and reset only with direction=Both. logs/list support query filters; code generates call code without replay. Configuration is a patch; capture filters affect future MCP records only. Pausing recording preserves blocking and GUI logging. Starting another engine stops the previous after preflight; read/configuration operations never load spies. Block/ignore require observed remotes. Ketamine cannot block incoming RemoteEvents. restart expires IDs/views and resets configuration; stop unloads the selected GUI/hooks. Signature: { engine: "cobalt" | "ketamine"?, operation: "status" | "start" | "restart" | "stop" | "list" | "logs" | "clear" | "block" | "unblock" | "ignore" | "unignore" | "code" | "configure" | "pause" | "resume" | "controls" | "reset-controls", mode: any?, max: number?, capture: { enabled: boolean?, direction: "Incoming" | "Outgoing" | "Both"?, nameFilter: string?, method: "FireServer" | "InvokeServer" | "OnClientEvent" | "OnClientInvoke"?, classFilter: "RemoteEvent" | "UnreliableRemoteEvent" | "RemoteFunction"?, blockedOnly: boolean? }?, resetFilters: boolean?, guiVisible: boolean?, guiLogging: boolean?, limit: any?, offset: number?, resetControl: "block" | "ignore" | "Both"?, direction: any?, remotePath: string?, remoteId: string?, nameFilter: string?, method: "FireServer" | "InvokeServer" | "OnClientEvent" | "OnClientInvoke"?, classFilter: "RemoteEvent" | "UnreliableRemoteEvent" | "RemoteFunction"?, blockedOnly: boolean?, afterId: number?, summaryOnly: any?, callId: number?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| configure-remote-spyA | WRITES LIVE GAME STATE. Configures an already-running spy without restarting or expiring IDs. Use engine=ketamine for Ketamine. Patch persistent MCP capture filters, pause/resume with capture.enabled, resize bounded history, or control Ketamine GUI visibility/logging. Omitted settings are preserved; resetFilters clears capture filters. Returns effective settings and capabilities. Pausing/filtering capture does not unblock remotes or change network delivery. Reads/configuration never load a spy; start it with remote-spy first. Cobalt accepts capture/buffer settings but rejects Ketamine GUI settings. Signature: { engine: "cobalt" | "ketamine"?, max: number?, capture: { enabled: boolean?, direction: "Incoming" | "Outgoing" | "Both"?, nameFilter: string?, method: "FireServer" | "InvokeServer" | "OnClientEvent" | "OnClientInvoke"?, classFilter: "RemoteEvent" | "UnreliableRemoteEvent" | "RemoteFunction"?, blockedOnly: boolean? }?, resetFilters: boolean?, guiVisible: boolean?, guiLogging: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| hook-and-log-functionA | DANGER — INSTALLS A PERSISTENT GLOBAL HOOK. Turnkey call-tracing for any function: hook a target, automatically record every invocation (stringified arguments + return values + a timestamp), then fetch the captured call log and restore the original — all from three actions of this one tool. This is the fastest way to answer 'what is this function actually called with, how often, and what does it return?' without hand-writing a hook. WORKFLOW (stateful — survives across tool calls via getgenv().__mcp_fnlogs, keyed by functionPath): 1. action='start' with functionPath — resolves the target, captures the original, installs a logging hook that transparently calls the original and records up to maxCalls invocations. Returns { started, key }. 2. action='fetch' with the same functionPath — reads the accumulated call log so far WITHOUT stopping it. Returns { count, max, calls } where each call is { args[], returns[], t }. Call repeatedly to watch live. 3. action='stop' with the same functionPath — restores the original function and removes the registry entry. Returns { stopped }. ALWAYS stop when done. CAVEATS: The hook is GLOBAL and PERSISTS until you stop it (or the client restarts). It adds overhead on every call to the target and CAN TRIP ANTICHEAT or destabilize the game, especially on hot paths — prefer specific, low-frequency targets and keep maxCalls modest. Arguments/returns are captured by tostring (Instances become GetFullName()) and both arrays are capped at 8 entries each. Logging stops accumulating once maxCalls is reached, but the hook stays installed (and keeps calling the original) until you stop it. Requires hookfunction, newcclosure, and getgenv; restoration uses hookfunction(target, original) with a restorefunction fallback. Returns { error } with a clear message if a capability is missing, the target cannot be resolved, or there is no active log for fetch/stop. Signature: { action: "start" | "fetch" | "stop", functionPath: string?, maxCalls: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: is-function-hooked. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| call-closureA | ACTS ON LIVE GAME STATE — EXECUTES THE FUNCTION. Resolve a Luau expression to a function and CALL it with an ordered list of typed arguments, returning every value it produces. This lets you invoke internal, hidden, or anonymous functions on demand: a remote's OnClientEvent handler (getconnections(remote.OnClientEvent)[1].Function), a metamethod (getrawmetatable(game).__namecall), a member pulled from a script env (getsenv(script).someFunc), a constant/upvalue you extracted, or any closure found in the GC. Each argument is a typed value; use kind='raw' for non-primitive arguments (Vector3, Color3, Enum, CFrame, tables, Instance references, ...). The call is fully pcall-guarded, so a function that errors reports its message instead of aborting. WARNING: this genuinely runs the target function with the arguments you supply — it MAY cause side effects, mutate game state, fire remotes to the server, or trip anti-cheat. Only call functions you understand. Returns { Target, ok, returns, returnCount, truncated, argCount } on success, or { Target, ok=false, error, argCount } when the function raised. Signature: { functionPath: string, args: {{ kind: "string" | "number" | "boolean" | "nil" | "raw", value: string | number | boolean? }}?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: debug closure primitives. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| count-function-callsA | WRITES LIVE GAME STATE — INSTALLS A PERSISTENT GLOBAL HOOK. Lightweight call-frequency counter for any function: hook a target so that every invocation bumps an integer counter, then read the counter, then restore the original. Unlike hook-and-log-function (which records full args/returns), this captures ONLY a count, so it is the cheapest way to answer 'is this function actually being called, and how often?' — ideal for confirming an anticheat tick fires, measuring how hot a code path is, or verifying a remote handler runs. WORKFLOW (stateful — survives across tool calls via getgenv().__mcp_callCounts, keyed by functionPath): 1. action='start' with functionPath — resolves the target, captures the original, installs a counting hook that transparently calls the original and increments a counter. Returns { started, key }. 2. action='fetch' with the same functionPath — returns { calls } captured so far WITHOUT stopping. Poll to watch live. 3. action='stop' with the same functionPath — restores the original and clears the entry. Returns { stopped, calls }. CAVEATS: the hook is GLOBAL and PERSISTS until you stop it (or the client restarts), adds (small) overhead on every call, and a live function hook CAN TRIP ANTICHEAT — always stop when done. The counting work is pcall-isolated and the hook always calls through to the original, so behavior is unchanged. Requires hookfunction, newcclosure, and getgenv; restoration uses hookfunction(target, original) with a restorefunction fallback. Returns { error } if a capability is missing, the target cannot be resolved, or there is no active counter for fetch/stop. Signature: { action: "start" | "fetch" | "stop", functionPath: string?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| spoof-function-returnA | WRITES LIVE GAME STATE — INSTALLS A PERSISTENT GLOBAL HOOK. Replaces a target function with a stub that IGNORES its arguments and ALWAYS returns a value you choose, without ever calling the original. This is the canonical anticheat/validation bypass: make a check like |
| block-functionA | WRITES LIVE GAME STATE — INSTALLS A PERSISTENT GLOBAL HOOK. Replaces a target function with a no-op that ignores its arguments, returns nothing, and NEVER calls the original. Use this to disable a behavior outright: silence an anticheat heartbeat/tick, stop a function that kicks the player, neutralize a telemetry reporter, or freeze a damage routine. Distinct from spoof-function-return (which forces a specific return value) — block-function simply makes the call a complete no-op (returns nil/nothing). WORKFLOW (stateful — survives across tool calls via getgenv().__mcp_blockedFns, keyed by functionPath): 1. action='start' with functionPath — resolves the target, captures the original, installs the no-op stub. Returns { started, key }. 2. action='stop' with the same functionPath — restores the original function. Returns { stopped }. CAVEATS: the hook is GLOBAL and PERSISTS until you stop it (or the client restarts). Because the original never runs, blocking a function the game depends on can break gameplay, and a live function hook CAN TRIP ANTICHEAT. Always stop when done. Requires hookfunction, newcclosure, and getgenv; restoration uses hookfunction(target, original) with a restorefunction fallback. Returns { error } if a capability is missing, the target cannot be resolved, or there is already an active block for fetch/stop. Signature: { action: "start" | "stop", functionPath: string?, threadContext: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| trace-call-durationsA | WRITES LIVE GAME STATE — INSTALLS A PERSISTENT GLOBAL HOOK. Per-function profiler: hook a target so that every invocation is timed with os.clock(), accumulating call count plus total/min/max time, then read the aggregated stats, then restore the original. This is the fastest way to answer 'how expensive is this function and how often does it run?' — ideal for finding the hot path in an anticheat loop, a render step, or a remote handler. Unlike count-function-calls (count only) it also measures duration; unlike hook-and-log-function it stores only aggregates (no per-call args), so it is cheap enough for hot paths. WORKFLOW (stateful — survives across tool calls via getgenv().__mcp_callTimings, keyed by functionPath): 1. action='start' with functionPath — resolves the target, captures the original, installs a timing wrapper that transparently calls the original and records elapsed time. Returns { started, key }. 2. action='fetch' with the same functionPath — returns { count, totalMs, avgMs, minMs, maxMs } so far WITHOUT stopping. Poll to watch live. 3. action='stop' with the same functionPath — restores the original and clears the entry. Returns final stats. CAVEATS: the hook is GLOBAL and PERSISTS until you stop it (or the client restarts), adds (small) timing overhead on every call, and a live function hook CAN TRIP ANTICHEAT — always stop when done. The original is called through real-time (its return values are passed back unchanged); timing/aggregation is pcall-isolated. Requires hookfunction, newcclosure, and getgenv; restoration uses hookfunction(target, original) with a restorefunction fallback. Returns { error } if a capability is missing, the target cannot be resolved, or there is no active profile for fetch/stop. Signature: { action: "start" | "fetch" | "stop", functionPath: string?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: bounded-event-snapshot, operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| capture-log-outputA | WRITES LIVE GAME STATE — INSTALLS A PERSISTENT LOG CONNECTION. Connects LogService.MessageOut and records every line the game emits (print, warn, error, and engine messages) into a ring buffer, so you can later read everything that was logged during a window of play. This is the best way to watch a game's own console output over time — see what a script prints when you trigger an action, catch errors/stack traces as they happen, or correlate warnings with behavior. It uses a signal CONNECTION (LogService.MessageOut), NOT a function hook, so it is low-risk compared to the hook-based instrument tools. WORKFLOW (stateful — survives across tool calls via getgenv().__mcp_logCapture): 1. action='start' — connects MessageOut to a handler that pushes { message (first 500 chars), messageType, t } into a 1000-entry ring buffer. Returns { started }. 2. action='fetch' — returns the captured messages (newest-bounded by |
| watch-property-changesA | Connects an Instance's Changed signal for a bounded window and records EVERY property that changes (its name plus the new value), then disconnects and returns the log. This is the discovery counterpart to watch-instance-property (inspection), which polls a SINGLE named property you already know: use watch-property-changes when you DON'T know which property to watch and want to see everything that moves — e.g. perform an action in-game and learn which of an Instance's properties the game actually mutates, or catch a property you didn't expect to change. It uses a signal CONNECTION (Instance.Changed), not a function hook, so it is low-risk; the connection is always disconnected at the end of the window. HOW IT WORKS: resolves the Instance, connects inst.Changed (which fires with the changed property NAME for plain Instances), and for each fire pcall-reads inst[prop] and appends { property, newValue, t }; then task.wait(s) for the duration and disconnects. The call BLOCKS for roughly durationMs while listening — perform the triggering action (click/move/etc.) shortly before or during the watch. NOTE: on some objects the Changed signal carries a Property-value-changed payload rather than a name (e.g. ValueBase objects fire with the value); this tool records the raw signal argument as the property identifier in that case. Returns { Path, ClassName, durationMs, changeCount, changes = [{ property, newValue, t }], truncated } or { error }. Signature: { instancePath: string, durationMs: any?, limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: bounded-event-snapshot. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-hidden-scriptsA | Scan ALL scripts (getscripts) and currently-running scripts (getrunningscripts) and report the ones that are trying to hide — i.e. not sitting normally in the game tree: nil-parented, detached from the DataModel, running inside an Actor (parallel-Luau VM), living in CoreGui, or destroyed-but-still-executing. Each result gives the script's name, class, where it actually lives, and whether it is currently running. This is the go-to tool for finding malicious/obfuscated/anti-detection scripts that hide outside the normal hierarchy. Requires getscripts/getrunningscripts; degrades with a clear error otherwise. Signature: { maxScan: any?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-actorsA | Enumerate every Actor instance in the game (getactors). Actors run code in isolated parallel-Luau VMs, so scripts inside them execute outside the normal serial scheduler and are a common place to hide logic. For each Actor this returns its name, full path, where it lives (in tree / nil-parented / detached / CoreGui), how many LuaSourceContainer descendants it has, and — when includeScripts is true — a capped list (30 per Actor) of those scripts with their name, class, and full path. Requires getactors; degrades with a clear error otherwise. Output is capped at 200 actors with a truncated flag. Signature: { includeScripts: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getactors. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-nil-instancesA | Enumerate instances whose Parent is nil (getnilinstances). Nil-parenting is a classic hiding spot: a remote, script, GUI, or other object is kept alive by a reference but is unreachable from the game tree, so it never shows up in the Explorer or normal descendant scans. This returns the total count, a byClass breakdown (ClassName -> count) computed across ALL nil instances, and a capped samples list (each with class, name, and full path) for inspection. Requires getnilinstances; degrades with a clear error otherwise. Signature: { limit: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-running-scriptsA | List every script that is currently executing (getrunningscripts), including ones that are not visible in the normal hierarchy — nil-parented, detached from the DataModel, running inside an Actor, or living in CoreGui. For each running script this returns its name, class, full path, where it actually lives (location), and whether it is still reachable from the game tree (inTree). This surfaces active anti-detection / obfuscated logic that is running but hidden from the Explorer. Requires getrunningscripts; degrades with a clear error otherwise. Output is capped at 300 scripts with a truncated flag. Signature: { threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates, operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-hidden-instancesA | Enumerate EVERY instance the executor can see (getinstances — this includes objects that are not reachable from the game DataModel) and report the ones that are hidden: nil-parented, detached from the game tree, or buried inside an Actor / CoreGui. An instance is considered hidden when it is not reachable from |
| find-hidden-guisA | Surface GUI overlays/menus that are hidden away from the normal PlayerGui hierarchy — the classic home of cheat menus, ESP overlays, and anti-detection UIs. Scans every nil-parented instance (getnilinstances) and the children of CoreGui, keeping anything that is a GUI container (LayerCollector / ScreenGui / BillboardGui / SurfaceGui / any GuiBase2d). Each hit reports its name, class, full path, and where it is hidden (location: nil-parented, CoreGui, detached, inside an Actor, etc.). Results are deduped. Requires getnilinstances for the nil sweep; the CoreGui sweep still runs even if getnilinstances is missing. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| summarize-hidden-surfacesA | One-call high-level overview answering 'what is hiding in this game?'. Safely (each executor call guarded + pcall'd) counts: Actors (parallel-Luau VMs), nil-parented instances (with a small top-classes breakdown), currently-running scripts, loaded modules, and a quick count of scripts that are NOT sitting normally in the tree (hiddenScripts). Any executor function that is unavailable in this executor is listed under |
| find-hidden-remotesA | Find RemoteEvent / RemoteFunction / UnreliableRemoteEvent / BindableEvent / BindableFunction instances that are NOT in the normal game tree — i.e. nil-parented or detached from the DataModel. A remote/bindable kept alive by a reference but hidden off the hierarchy is a classic backdoor / data-exfiltration channel: an exploit or malicious script fires it to phone home or to receive commands without the object ever appearing in the Explorer. This tool pulls getnilinstances() (the primary source of nil-parented objects) and, when getinstances() is available, also includes any remote/bindable that is not a descendant of |
| get-actor-detailsA | Drill into Actor instances (parallel-Luau VMs) and report their contents. Actors run code in isolated VMs outside the normal serial scheduler, so they are a common place to hide logic. Give an actorPath to inspect ONE Actor in detail, or omit it to summarize EVERY Actor (getactors). For each Actor this returns its name, where it lives (in tree / nil-parented / detached / inside CoreGui), how many descendants it has, and a list (capped at 30 per Actor) of the LuaSourceContainer scripts inside it — each with name, class, full path, and whether the script is currently executing (running, determined by membership in getrunningscripts). This complements list-actors by adding the running flag, the descendant count, and single-target resolution from a Luau expression. Requires getactors; getrunningscripts is used additionally when present (running falls back to false if it is unavailable). Returns a single Actor object when actorPath is given, otherwise { actorCount, truncated, actors: [...] }. Degrades with a clear error if getactors is missing or actorPath does not resolve to an Actor. Signature: { actorPath: string?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: getactors. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-detached-instancesA | Walk every instance the executor can see (getinstances) and report the ones that are DETACHED from the running game — i.e. they exist in the executor's instance registry but pcall(inst.IsDescendantOf, inst, game) returns false, so they are not reachable from the DataModel. This catches objects that were Destroy()'d or reparented to nil yet kept alive by a lingering reference, plus anything an anti-detection script has stashed off the hierarchy. An optional className filter narrows the walk to a single ClassName (matched via IsA so subclasses are included). Unlike find-hidden-instances (which uses an ancestor-walk to test reachability), this tool uses IsDescendantOf against game directly, supports a class filter, and always reports a full byClass breakdown across ALL detached instances. Returns { totalDetached, byClass, truncated, samples: [{ class, name }] }. Requires getinstances; degrades with a clear error otherwise. Signature: { className: string?, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| actor-capabilitiesB | Read-only matrix for Volt's complete Actors and LuaStateProxy surface, including event objects and aliases. Signature: { threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getactors. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| run-on-actorA | WRITES LIVE GAME STATE. Resolve an Actor expression and call run_on_actor(actor, source, ...arguments). The operation is asynchronous and returns scheduling metadata, not the actor script's return value. Requires confirm=true. Signature: { actorPath: string, source: string, arguments: any?, confirm: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval, validated-source. Capabilities: getactors. Produces: operation-receipt. Verify with: get-lua-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-lua-stateA | Call getluastate() for the current state, or getluastate(target) for an Actor/BaseScript expression. Returns serializable Id/IsActorState/Event/Actors metadata plus a reusable registry Reference. Signature: { targetExpression: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getluastate. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-game-stateA | Call getgamestate() and return Id/IsActorState/Event/Actors metadata plus a reusable registry Reference. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-lua-statesA | Call getactorstates(), cap output at 256 states, and return compact state/actor metadata plus reusable References. Signature: { includeActors: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getluastate. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| new-lua-state-proxyA | Call LuaStateProxy.new() and return serializable state metadata plus a retained Reference; no raw proxy crosses JSON. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getluastate. Produces: created-handle. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-lua-state-actorsA | Resolve current/game/expression state, call LuaStateProxy:GetActors(), and return at most 200 Actor paths. Signature: { state: any?, stateExpression: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getactors, getluastate. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| execute-lua-stateA | WRITES LIVE GAME STATE. Resolve current/game/expression state and call LuaStateProxy:Execute(source, ...args). Execution is asynchronous and confirmation-gated. Signature: { state: any?, stateExpression: any?, source: string, arguments: any?, confirm: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, validated-source. Capabilities: getluastate. Produces: operation-receipt. Verify with: get-lua-state. Safety: MUTATING; executes caller-selected behavior in the live client. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| fire-lua-state-eventA | WRITES LIVE GAME STATE. Resolve current/game/expression state and call state.Event:Fire(...typed arguments). Requires confirm=true because listeners may mutate live behavior. Signature: { state: any?, stateExpression: any?, arguments: any?, confirm: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: getluastate. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| is-parallel-contextB | Call isparallel/is_parallel and return a boolean without changing scheduler state. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| create-comm-channelA | WRITES LIVE GAME STATE. Call create_comm_channel(name?), retain the Channel in getgenv().__mcp_comm_channels, and return only its serializable identifier/metadata. Requires confirm=true. Signature: { name: any?, confirm: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: create_comm_channel. Produces: created-handle. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-comm-channelB | Call get_comm_channel(id), falling back to the MCP channel registry, and return serializable channel/Event metadata. Signature: { id: string, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: create_comm_channel. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| fire-comm-channelA | WRITES LIVE GAME STATE. Resolve get_comm_channel(id) and call Channel:Fire(...typed arguments). Requires confirm=true because channel listeners may execute arbitrary live behavior. Signature: { id: string, arguments: any?, confirm: boolean?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: create_comm_channel. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| actor-event-monitorA | WRITES LIVE GAME STATE when starting/stopping. Connect to on_actor_added and/or on_actor_state_created, retain a bounded 200-event buffer, and poll it without repeated game-tree scans. Start/stop require confirm=true. Signature: { action: "start" | "poll" | "stop", key: any?, limit: any?, clear: any?, confirm: any?, threadContext: number?, events: any? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: getactors. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| comm-channel-monitorA | WRITES LIVE GAME STATE when starting/stopping. Connect to Channel.Event, retain a bounded 200-message buffer, and poll by monitor key. Start/stop require confirm=true. Signature: { action: "start" | "poll" | "stop", key: any?, limit: any?, clear: any?, confirm: any?, threadContext: number?, id: any? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: create_comm_channel. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| lua-state-event-monitorA | WRITES LIVE GAME STATE when starting/stopping. Connect to LuaStateProxy.Event, retain a bounded 200-event buffer, and poll it by key. Start/stop require confirm=true. Signature: { action: "start" | "poll" | "stop", key: any?, limit: any?, clear: any?, confirm: any?, threadContext: number?, state: any?, stateExpression: any? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: getluastate. Produces: bounded-event-snapshot. Verify with: assert-state. Safety: MUTATING; changes persistent executor-side observer or hook state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-tables-by-keyA | Cheat-Engine-style STRUCTURE scan: walk every live Luau GC table and report each one that contains a string key matching |
| scan-number-rangeA | Cheat-Engine-style RANGE scan: walk every live Luau GC table and report each numeric value v where min <= v <= max. Use this when you know a stat is within a window but not its exact value — e.g. coins between 100 and 200, health under 50, a timer in [0, 10], a damage multiplier in [1, 5]. It is the inexact complement to search-gc-value (which needs the precise number). Each hit is recorded as { table, key, value } where 'table' is the container address (tostring), 'key' is the field the number sits under (tostring), and 'value' is the raw number. To narrow many hits down to one, run successive scans with tightening bounds after the stat changes in-game (the Cheat-Engine 'next scan' technique), then read or flip the survivor with read-path-value / write-path-value. Each table's pairs() iteration is pcall-guarded so a locked/proxy table never aborts the scan; GC objects examined are capped by maxScan and results by limit, with a 'truncated' flag. NaN values are skipped. Requires getgc (falls back from getgc(true) to getgc()). Returns { min, max, matchCount, scannedObjects, truncated, matches } or { error }. Signature: { min: number, max: number, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| read-path-valueA | Evaluate a single Luau expression and report exactly what lives at that slot — without mutating anything. Use it to read a precise location after a heap scan points you at it (e.g. 'getgenv().PlayerData.Coins', 'game.Players.LocalPlayer.leaderstats.Cash.Value', 'require(game.ReplicatedStorage.Config).GodMode', 'getrawmetatable(game).__namecall'), or to spot-check any value/global/field during analysis. The expression is evaluated as |
| write-path-valueA | WRITES LIVE GAME STATE. Direct heap write into one slot of a Luau table: resolve a Luau expression to a TABLE container, then assign container[key] = , returning BOTH the OLD and NEW value so the change is auditable. This is the write counterpart to read-path-value and the natural action after a memscan locates a field — e.g. flip a config flag ('require(game.ReplicatedStorage.Config)', key='GodMode', value true), bump a cached stat ('getgenv().PlayerData', key='Coins', value=9999), or clear a slot (kind='nil'). The container expression is evaluated as |
| find-table-referencesA | Answer 'who holds this table alive / who can reach it?' Resolve a Luau expression to a target TABLE, then walk the entire GC and record every OTHER object that references it: (1) for each GC TABLE, pcall-iterate pairs() and if any VALUE is the target, record { container, via='value', key } (the surrounding key text); (2) for each Lua CLOSURE, scan its upvalues (getupvalues, guarded) and if any UPVALUE is the target, record { container, via='upvalue', key } where container is the function's source:line (via debug.info / getinfo). The target table itself is skipped so it never lists itself. This is the inverse of the look-down tools (read-path-value, dump-table): use it to find the owner of a shared state/config table, to discover which closures captured it (so you can hook or inspect them), or to understand why a table is not being collected. Every access is pcall-guarded so locked objects never abort the scan; GC objects examined are capped by maxScan and results by limit, with a 'truncated' flag. Requires getgc; upvalue scanning additionally needs getupvalues (type-guarded — skipped if absent). Returns { target, referenceCount, scannedObjects, truncated, references } or { error }. Signature: { tableExpr: string, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| find-string-in-tablesA | Walk every live Luau GC table and report each string VALUE that matches |
| search-gc-valueA | Cheat-Engine-style heap scanner: find WHERE a specific value lives across the entire Luau garbage collector. Resolve a target from one of five value types, then walk every live object via getgc(true) and report each place that holds it. For GC TABLES the tool pcall-iterates pairs() and records a hit when a KEY or a VALUE matches (string matches support exact OR 'contains' substring search). For Lua CLOSURES (when scanFunctions is on) it scans the function's constants and upvalues. Each match reports { container, where, keyText? } where 'where' is one of value/key/constant/upvalue and 'container' is the table address or the closure's source:line. Use it to locate a coin/HP total, a remote or flag name, a boolean toggle, or a Part/Instance reference, then pivot with inspect-closure / dump-table / set-closure-upvalue to read or mutate it. Requires getgc; closure scanning additionally requires getconstants/getupvalues (each is type-guarded and simply skipped if the executor lacks it). Everything is pcall-guarded so locked/dead objects never abort the scan; the object count is capped by maxScan and the result list by limit, with a 'truncated' flag. Returns { valueType, matchCount, truncated, matches } or { error }. Signature: { valueType: "number" | "string" | "boolean" | "instance" | "raw", value: string | number | boolean?, match: any?, scanFunctions: any?, limit: any?, maxScan: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getgc. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| watch-valueA | Sample ANY Luau expression repeatedly over a bounded window and report every value it took plus exactly when it changed — a live memory/state monitor for reverse-engineering and debugging. Give an expression that returns a value (no |
| list-roblox-windowsA | List the Roblox player processes on the SERVER host that own a visible OS window, with their process id and window title. Windows-only: runs a PowerShell |
| screenshot-windowA | Capture an OS screenshot of a Roblox window on the SERVER host and save it as a PNG, returning the saved file path and the captured width/height. Windows-only: locates the RobloxPlayerBeta window by |
| semantic-search-scriptsA | Rank the active client's loaded/GC scripts by semantic relevance to a natural-language query. NOTE: full decompiled source is NOT available in the clean protocol, so each script is indexed over its GetFullName() path + Name + ClassName + the string constants reachable from its closure (capped per script) — think of it as 'find the script most likely about X', not a full-text code search. The first call embeds and caches every script (locally or via the configured embeddings endpoint); later calls reuse the cache for unchanged scripts. Returns { hits: [{ path, score, snippet }], model } sorted by descending cosine similarity. Signature: { query: string, limit: any?, maxScripts: any? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-semantic-index-statsA | Report the semantic script index for THIS session's active client WITHOUT touching the game: whether anything is indexed, how many documents are cached, and the embedding model + dimensions in use. Resolves the active client from this session's selection; if no client is resolved it returns an empty, not-indexed summary. Use it to confirm an index exists before searching, or to see which embeddings backend is active. Signature: {}. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| clear-semantic-indexA | Drop the cached semantic index for THIS session's active client. This clears a SERVER-SIDE embedding cache only — it does not touch the game or any live script. Resolves the active client from this session's selection; if one is resolved its index is cleared, otherwise nothing happens. Use it to force the next semantic-search-scripts call to re-harvest and re-embed from scratch (e.g. after the game's scripts changed). Signature: {}. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| read-fileA | Read the entire contents of a file from the executor's workspace folder and return it as a string. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so paths are relative to the executor's workspace directory on the host machine, NOT anything in the Roblox game/DataModel. Requires the UNC function readfile(path). The call is type-guarded and pcall-wrapped: if readfile is missing you get { error = 'readfile is not available in this executor.' }, and any read failure (missing file, permission) returns { error = }. Returns { path, content } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: readfile. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| write-fileA | Write content to a file in the executor's workspace folder, creating it if needed and OVERWRITING any existing contents. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. Requires the UNC function writefile(path, content). The call is type-guarded and pcall-wrapped: if writefile is missing you get { error = 'writefile is not available in this executor.' }, and any write failure (bad path, denied extension, permission) returns { error = }. Returns { path, ok = true } or { error }. Signature: { path: string, content: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: executor filesystem. Produces: operation-receipt. Verify with: file-exists. Safety: MUTATING; writes executor workspace filesystem. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| append-fileA | Append content to the end of a file in the executor's workspace folder, creating the file first if it does not exist. Existing contents are preserved (unlike write-file, which overwrites). NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. Requires the UNC function appendfile(path, content). The call is type-guarded and pcall-wrapped: if appendfile is missing you get { error = 'appendfile is not available in this executor.' }, and any failure returns { error = }. Returns { path, ok = true } or { error }. Signature: { path: string, content: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: executor filesystem. Produces: operation-receipt. Verify with: file-exists. Safety: MUTATING; writes executor workspace filesystem. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-filesA | List the files and subfolders directly inside a folder in the executor's workspace, returning their paths. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. Pass an empty string to list the workspace root. Requires the UNC function listfiles(path) -> { string }. The call is type-guarded and pcall-wrapped: if listfiles is missing you get { error = 'listfiles is not available in this executor.' }, and any failure (missing folder) returns { error = }. The returned list is capped at 1000 entries with a 'truncated' flag. Returns { path, files, count, truncated } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: readfile. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| make-folderA | Create a folder (and any required parent folders) inside the executor's workspace. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. Requires the UNC function makefolder(path). The call is type-guarded and pcall-wrapped: if makefolder is missing you get { error = 'makefolder is not available in this executor.' }, and any failure returns { error = }. Creating a folder that already exists is a no-op on most executors. Returns { path, ok = true } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: executor filesystem. Produces: structured-result. Verify with: file-exists. Safety: MUTATING; writes executor workspace filesystem. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| delete-fileA | Delete a single file from the executor's workspace folder. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. This is destructive and cannot be undone. Requires the UNC function delfile(path). The call is type-guarded and pcall-wrapped: if delfile is missing you get { error = 'delfile is not available in this executor.' }, and any failure (missing file, permission) returns { error = }. Returns { path, ok = true } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: executor filesystem. Produces: operation-receipt. Verify with: file-exists. Safety: MUTATING; writes executor workspace filesystem. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| delete-folderA | Delete a folder (and typically its contents) from the executor's workspace. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. This is destructive and recursive on most executors; it cannot be undone. Requires the UNC function delfolder(path). The call is type-guarded and pcall-wrapped: if delfolder is missing you get { error = 'delfolder is not available in this executor.' }, and any failure (missing folder, permission) returns { error = }. Returns { path, ok = true } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Capabilities: executor filesystem. Produces: operation-receipt. Verify with: file-exists. Safety: MUTATING; writes executor workspace filesystem. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| file-existsA | Probe a path in the executor's workspace and report whether it is an existing file and/or an existing folder. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. Requires the UNC functions isfile(path) -> bool and isfolder(path) -> bool. Each is type-guarded and pcall-wrapped INDEPENDENTLY: if a probe's function is missing or errors, its result is reported as false. If NEITHER isfile nor isfolder is available you get { error = 'isfile/isfolder are not available in this executor.' }. Returns { path, isFile, isFolder } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: readfile. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| load-fileA | Compile a Luau file from the executor's workspace into a function WITHOUT executing it, to verify that it parses and to surface any syntax error. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. This tool intentionally does NOT call the compiled function; it only reports whether compilation succeeded. Requires the UNC function loadfile(path) -> (fn?, err?). The call is type-guarded and pcall-wrapped: if loadfile is missing you get { error = 'loadfile is not available in this executor.' }. On a compile error loadfile returns nil plus an error string, surfaced as { compiled = false, error }. Returns { path, compiled, error? } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Capabilities: readfile. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-custom-assetA | Turn a file in the executor's workspace into a content URL (rbxasset://...) usable as an asset id for images, sounds, meshes, etc. inside the game. NOTE: this is executor-side file I/O — the connector runs INSIDE the executor, so the path is relative to the executor's workspace directory on the host machine, NOT the Roblox game. This is marked state-mutating because on most executors getcustomasset COPIES the file into the Roblox content cache as a side effect. Requires the UNC function getcustomasset(path) -> string. The call is type-guarded and pcall-wrapped: if getcustomasset is missing you get { error = 'getcustomasset is not available in this executor.' }, and any failure returns { error = }. Returns { path, asset } or { error }. Signature: { path: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-observation, operation-receipt. Verify with: assert-state. Safety: MUTATING; writes executor workspace filesystem. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| crypt-base64-encodeA | Encode an arbitrary string to Base64 using the executor's |
| crypt-base64-decodeA | Decode a Base64 string back to its raw bytes using the executor's |
| crypt-hashA | Compute a cryptographic digest of a string using the executor's |
| crypt-encryptA | Encrypt a string with the executor's |
| crypt-decryptA | Decrypt a ciphertext with the executor's |
| crypt-generate-keyA | Generate a cryptographically random symmetric key using the executor's |
| crypt-generate-bytesA | Generate |
| draw-createA | Creates a new on-screen overlay object via the executor |
| draw-updateA | Mutates a Drawing overlay previously created by draw-create, looking the handle up by its integer id in getgenv().__mcp_drawings and assigning each given property. Use it to move a tracer (To = 'Vector2.new(400,300)'), recolor an ESP box (Color = 'Color3.new(0,1,0)'), toggle visibility (Visible = 'false'), or change a label (Text = '"BOSS"'). PROPERTIES: each value is a Luau EXPRESSION STRING evaluated via loadstring, identical to draw-create. Unknown/failed properties are reported per-property in 'updated' (ok=false) without aborting the rest. Requires the |
| draw-removeA | Destroys one Drawing overlay created by draw-create: looks the handle up by its integer id in getgenv().__mcp_drawings, calls handle:Remove(), and clears the registry slot so list-drawings no longer reports it. Use it to clean up a single ESP element while leaving the rest of the overlay intact. Requires the |
| draw-clearA | Tears down the entire MCP-managed Drawing overlay: iterates every handle stored in getgenv().__mcp_drawings, calls :Remove() on each, empties the registry, and additionally calls Drawing.clear() when the executor exposes it (to sweep any stray objects this tool did not create). Use it as a one-shot reset between ESP sessions. Requires the |
| list-drawingsA | Read-only inventory of the Drawing overlay this server manages: walks getgenv().__mcp_drawings and returns each registered object's { id, type, visible } so you can see what is currently on screen before updating or removing it. 'visible' reflects the live handle.Visible property (pcall-read; null if it could not be read). Does NOT touch the screen or any handle. Requires the |
| filter-gcA | The headline reflection tool: run the executor's UNC filtergc(filterType, options) against the entire live garbage collector to find Lua closures or tables that match a structural fingerprint, without writing any Luau by hand. Far more targeted than a raw getgc() sweep — you describe WHAT you are looking for and the executor returns only the objects that match. For filterType='function' the options are { Name?, Hash?, IgnoreExecutor? (default true), Constants? (array of constants the closure must reference), Upvalues? (array of upvalue values the closure must hold) } — e.g. find the closure that owns the string 'FireServer' and the upvalue 1337. For filterType='table' the options are { Keys? (array of keys that must be present), Values? (array of values that must be present), KeyValuePairs? (record of exact key=value pairs), Metatable? } — e.g. find the player-data table that has a 'Coins' key. Each match is encoded to a compact summary: functions report { source, line, name } (via debug.info) and tables report { address, keyCount }. Output is capped by 'limit'. Requires filtergc (type-guarded; returns { error } where it is unavailable) and every call is pcall-wrapped so a locked object can never abort the query. Returns { filterType, matchCount, truncated, matches } or { error }. Signature: { filterType: "function" | "table", options: { Name: string?, Hash: string?, IgnoreExecutor: boolean?, Constants: {string | number | boolean}?, Upvalues: {string | number | boolean}?, Keys: {string | number | boolean}?, Values: {string | number | boolean}?, KeyValuePairs: {[string]: string | number | boolean}?, Metatable: string | number | boolean? }, limit: number?, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: getgc. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-call-stackA | Unwind the current Luau call stack from the executing thread and return one frame per level: { level, name, source, line }. Walks debug.info(level, 'nsl') (name / source / currentline) from level 1 outward, stopping at the first level that yields nil or after maxLevels frames. Use it to see who is calling the code you just ran — the chain of functions leading into the current execution — which is invaluable when reasoning about a hook callback or a deferred task's origin. Requires debug.info (or debug.getinfo) — type-guarded and pcall-wrapped, returning { error } on an executor that lacks it. Returns { frames } or { error }. Signature: { maxLevels: number?, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation, operation-receipt. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-stackA | Read the raw values currently sitting on the Luau stack at a given call level via the executor's debug.getstack. Without 'index' it returns every live stack slot at that level as an encoded list (Instances/EnumItems/tables are flattened to a JSON-friendly shape); with 'index' it returns just that one slot's encoded value. This exposes the in-flight locals and temporaries of a running function — the values a frame is actively working with — letting you snapshot what a callback or hooked function holds at the moment your code runs. Requires debug.getstack — type-guarded and pcall-wrapped, returning { error } when missing or on failure. Returns { level, index?, value } / { level, count, values } or { error }. Signature: { level: number, index: number?, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-hidden-uiA | Return a shallow tree of the executor's hidden, protected GUI container via gethui(). This is the parent that executors hand back for ScreenGuis they want kept away from CoreGui/PlayerGui and shielded from the game's anti-cheat — the usual home of cheat menus, ESP layers, and overlays. The tool walks gethui():GetChildren() and returns a { name, class, children } tree capped at depth 3 with a per-node child cap, reporting how many children were truncated. Requires gethui — type-guarded and pcall-wrapped, returning { error } when missing or on failure. Returns { root: { name, class, childCount, children } } or { error }. Signature: { maxChildren: number?, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-rendered-instancesA | Enumerate the instances the engine is currently rendering via getrendered() and return { count, samples }, where each sample is { class, name, path }. This is the set of objects actually on screen this frame — useful for ESP/render auditing, spotting which parts/GUIs are visible, or correlating a render spike with specific instances. The full count is reported even though only a capped sample of entries is returned. Requires getrendered — type-guarded and pcall-wrapped, returning { error } when missing or on failure. Returns { count, truncated, samples } or { error }. Signature: { limit: number?, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| cache-invalidateA | Invalidate the executor's cached reference to a single Instance via cache.invalidate(inst). After invalidation the next time the game indexes that instance it receives a FRESH reference rather than the cached one — the classic technique for de-syncing a server-trusted object so your subsequent edits to the cached copy go unnoticed, or for forcing the executor to re-wrap a part you have been tampering with. The target is resolved from a Luau path/expression via loadstring('return ' .. expr). Requires the cache library (type(cache)=='table') with cache.invalidate — both are type-guarded and the call is pcall-wrapped, returning { error } when missing or on failure. Mutates live executor state. Returns { ok } or { error }. Signature: { instancePath: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| cache-is-cachedA | Report whether the executor currently holds a cached reference for a single Instance via cache.iscached(inst). Pairs with cache-invalidate / cache-replace: use it to confirm an instance is cached before invalidating it, or to verify that an invalidate actually dropped the cached reference. The target is resolved from a Luau path/expression via loadstring('return ' .. expr). Read-only. Requires the cache library (type(cache)=='table') with cache.iscached — both are type-guarded and the call is pcall-wrapped, returning { error } when missing or on failure. Returns { cached } or { error }. Signature: { instancePath: string, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| cache-replaceA | Replace the executor's cached reference for one Instance with another via cache.replace(a, b). After the swap, every script that indexes instance A through the cache transparently receives instance B instead — a powerful redirection primitive for impersonating one object with another (e.g. pointing a checkpoint, hitbox, or remote wrapper at a substitute you control). Both targets are resolved from Luau path/expressions via loadstring('return ' .. expr). Requires the cache library (type(cache)=='table') with cache.replace — both are type-guarded and the call is pcall-wrapped, returning { error } when missing or on failure. Mutates live executor state. Returns { ok } or { error }. Signature: { instancePath: string, replacementPath: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-script-bytecodeA | Retrieve the compiled Luau bytecode for a script via the executor's getscriptbytecode. The script is resolved from a Luau expression (typically a path to a LuaSourceContainer, e.g. 'game.ReplicatedStorage.Module') via loadstring('return ' .. expr). Returns the total byte count and a hex preview of the first |
| get-script-hashA | Compute the content hash of a script via the executor's getscripthash. The script is resolved from a Luau expression (typically a path to a LuaSourceContainer, e.g. 'game.ReplicatedStorage.Module') via loadstring('return ' .. expr). Handy for detecting when a script's bytecode/source changes between two checks. Requires getscripthash — type-guarded and pcall-wrapped, returning { error } when missing or on failure. Returns { hash } or { error }. Signature: { scriptPath: string, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=read-only. Requires: active-client, resolved-target. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| packet-spyA | WRITES LIVE GAME STATE — installs a RakNet send hook. Captures every OUTGOING low-level packet the client sends (RakNet only exposes outgoing traffic). For each packet it records Size, Priority, Reliability, OrderingChannel, and a hex preview of the payload. action='start' installs the hook (idempotent), 'fetch' returns the captured packets newest-first without stopping, 'stop' removes the hook and clears the buffer. Requires the |
| send-packetA | WRITES LIVE GAME STATE — transmits a raw packet. Sends a custom OUTGOING low-level packet via raknet.send with the given payload (a hex string, converted to a byte array), priority, reliability, and ordering channel. Requires the |
| block-packetsA | WRITES LIVE GAME STATE — installs a RakNet send hook that DROPS matching outgoing packets. A packet is blocked when its Size >= minSize (if set) and/or its payload contains containsHex (if set); with neither criterion every outgoing packet is blocked (dangerous). action='start' installs the hook, 'stop' removes it. Requires the |
| http-requestA | SENDS A REAL OUTBOUND HTTP REQUEST from the Roblox client via the executor's request({ Url, Method, Headers, Body }) (falling back to http_request, then syn.request). Unlike Roblox's HttpService this can hit arbitrary hosts and set custom headers. The response body is capped at ~100 KB. Requires one of these functions to be available. The call is type-guarded and pcall-wrapped: if none is present you get { error = 'request is not available in this executor.' }, and a transport failure returns { error }. Returns { statusCode, success, headers, body, statusMessage } or { error }. Signature: { url: string, method: any?, headers: {[string]: string}?, body: string?, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: request. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; performs external network or socket I/O. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| ws-connectA | WRITES LIVE GAME STATE — opens a real outbound WebSocket from the client via WebSocket.connect(url). The live socket is parked in a getgenv registry keyed by an integer id (returned as |
| ws-sendA | WRITES LIVE GAME STATE — sends a text frame over a WebSocket previously opened with ws-connect, addressed by its registry id. Looks up getgenv().__mcp_ws[id], verifies the socket is still open, and calls socket:Send(message). Requires getgenv and the live socket from ws-connect — both are guarded and the send is pcall-wrapped, returning { error } when the id is unknown, the socket is closed, or Send fails. Returns { id, sent = true } or { error }. Signature: { id: number, message: string, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: WebSocket. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; performs external network or socket I/O. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| ws-receiveA | Read the inbound frames buffered for a WebSocket opened with ws-connect, addressed by its registry id. Returns the captured { text, t } records newest-first, capped at |
| ws-closeA | WRITES LIVE GAME STATE — closes a WebSocket previously opened with ws-connect, addressed by its registry id. Calls socket:Close() (pcall-wrapped), marks the entry closed, and removes it from the getgenv registry so the id no longer appears in ws-list. Requires getgenv and the entry from ws-connect — guarded, returning { error } when the id is unknown. Returns { id, closed = true } or { error }. Signature: { id: number, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Capabilities: WebSocket. Produces: structured-result. Verify with: ws-list. Safety: MUTATING; performs external network or socket I/O. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| ws-listA | List every WebSocket currently parked in the getgenv registry by ws-connect. For each entry it reports { id, url, open, messageCount } so you can see which sockets are still live and how many inbound frames are buffered. Read-only. Requires getgenv — guarded; when no registry exists it simply returns an empty list. Returns { count, sockets } or { error }. Signature: { threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Capabilities: WebSocket. Produces: bounded-candidates. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-fast-flagA | Read the current value of a Roblox engine FastFlag by name via the executor's getfflag(name). FastFlags (FFlag/DFFlag/FInt/etc.) are the runtime feature toggles the Roblox client reads at startup; getfflag returns the current value as a string, or nil when the flag is unknown. Requires getfflag. The call is type-guarded and pcall-wrapped: if getfflag is missing you get { error = 'getfflag is not available in this executor.' }. Returns { name, value } or { error }. Signature: { name: string, threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-fast-flagA | WRITES CLIENT STATE — overrides a Roblox engine FastFlag for the running client via setfflag(name, value). The value is supplied as a string and coerced by the executor to the flag's native type (bool/int/string). This changes engine behavior at runtime and can destabilize the client if a flag is set to an invalid value. Requires setfflag. The call is type-guarded and pcall-wrapped: if setfflag is missing you get { error = 'setfflag is not available in this executor.' }. Returns { name, value, ok } or { error }. Signature: { name: string, value: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-fps-capA | Read the executor's current render frame-rate cap via getfpscap(). Returns the cap as a number; 0 means uncapped. Requires getfpscap. The call is type-guarded and pcall-wrapped: if getfpscap is missing you get { error = 'getfpscap is not available in this executor.' }. Returns { fpsCap } or { error }. Signature: { threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-fps-capA | WRITES CLIENT STATE — sets the executor's render frame-rate cap via setfpscap(cap). Pass 0 to uncap the frame rate. Requires setfpscap. The call is type-guarded and pcall-wrapped: if setfpscap is missing you get { error = 'setfpscap is not available in this executor.' }. Returns { cap, ok } or { error }. Signature: { cap: number, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| get-hwidA | Read the host machine's hardware identifier (HWID) via the executor's gethwid(). This is the stable per-machine fingerprint executors commonly use for key-system/license binding. Requires gethwid. The call is type-guarded and pcall-wrapped: if gethwid is missing you get { error = 'gethwid is not available in this executor.' }. Returns { hwid } or { error }. Signature: { threadContext: number?, timeoutMs: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: structured-observation. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| set-clipboardA | WRITES HOST STATE — copies the given text to the host machine's OS clipboard via setclipboard(text), falling back to toclipboard(text) on executors that use that name. This overwrites whatever is currently on the clipboard. Requires one of these functions. The call is type-guarded and pcall-wrapped: if neither is present you get { error = 'setclipboard is not available in this executor.' }. Returns { ok, length } or { error }. Signature: { text: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| queue-on-teleportA | WRITES EXECUTOR STATE — queues a chunk of Luau source via queueonteleport(code) so it runs automatically after the NEXT teleport completes, in the destination place. This is how scripts survive a Roblox teleport: the queued code persists across the place change and executes once the new place loads. Requires queueonteleport. The call is type-guarded and pcall-wrapped: if queueonteleport is missing you get { error = 'queueonteleport is not available in this executor.' }. Returns { queued } or { error }. Signature: { code: string, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, validated-source. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| clear-queue-on-teleportA | WRITES EXECUTOR STATE — clears any code previously queued with queueonteleport, via clearqueueonteleport(). After this, nothing will auto-run on the next teleport. Requires clearqueueonteleport. The call is type-guarded and pcall-wrapped: if clearqueueonteleport is missing you get { error = 'clearqueueonteleport is not available in this executor.' }. Returns { cleared } or { error }. Signature: { threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=idempotent-write. Requires: active-client, explicit-mutation-approval. Produces: operation-receipt. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| save-instanceA | WRITES HOST FILES — serializes the entire game (or a chosen instance subtree) to a file in the executor's workspace folder via saveinstance. By default it dumps the whole DataModel; pass instancePath to dump just that subtree. This is a heavy operation that can take a while and produce a large file. Because executors differ on the exact signature, this tries several forms in order: saveinstance({ FilePath = fileName }), then saveinstance(instance, fileName) / saveinstance(instance), then saveinstance(). Requires saveinstance. The call is type-guarded and pcall-wrapped: if saveinstance is missing you get { error = 'saveinstance is not available in this executor.' }. Returns { saved, note } or { error }. Signature: { fileName: string?, instancePath: string?, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, resolved-target, explicit-mutation-approval. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| message-boxA | WRITES HOST STATE — pops up a NATIVE OS dialog on the host machine via messagebox(text, caption, flags). The flags select the dialog's button/icon style (the same bitfield as the Win32 MessageBox), and the call blocks until the user dismisses it, returning the numeric code of the button pressed. Requires messagebox. The call is type-guarded and pcall-wrapped: if messagebox is missing you get { error = 'messagebox is not available in this executor.' }. Returns { result } or { error }. Signature: { text: string, caption: any?, flags: any?, threadContext: number?, timeoutMs: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval. Produces: structured-result. Verify with: assert-state. Safety: MUTATING; writes live game/client state. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| tool-schemaA | Return the input schema for any tool on this server in a compact, Luau-friendly form. Pass { name } for one tool: returns its title, compiled description, quality grade, safety/execution/success/recovery guidance, category, mutatesState, requiresClient, a one-line Luau signature (e.g. |
| tool-planA | READ-ONLY. Convert a vague Roblox goal into a ranked, schema-aware workflow. Give this tool the user's natural-language objective, not a guessed tool name. It combines intent aliases, the live tool catalog, available schemas, mutation flags, and curated discover→act→verify recipes. Use the returned workflow as a starting point, then inspect the exact schema of the selected tool before calling it. This is especially useful for goals involving UI/input, remotes, player values, instance inspection, or reverse engineering. Signature: { goal: string, limit: any?, includeMutating: any?, capabilityAware: any? }. Phase: observe; cost=low; idempotency=read-only. Requires: none. Produces: agent-guidance. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| agent-contextA | READ-ONLY. Bootstrap an AI agent with the current MCP/session/game context in one call. Returns connected clients, this session's active selection resolution, game identity, executor identity/capabilities, and actionable next steps. Use this at the start of a task or after a reconnect instead of separately guessing which client, place, executor, or capability set is active. If multiple clients are connected, the brief tells you to select one; it never silently chooses between distinct accounts. Optional capability probing is safe but slower. The tool never mutates game state. Signature: { includeGameInfo: any?, includeExecutorInfo: any?, includeCapabilities: any?, includeHistory: any?, historyLimit: any?, includeMemory: any?, memoryLimit: any? }. Phase: observe; cost=medium; idempotency=read-only. Requires: none. Produces: agent-guidance. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| agent-runA | ORCHESTRATES LIVE TOOLS. Execute an explicit discover→act→verify workflow with step IDs, result references, dry-run planning, mutation approval, retries, and automatic contract-based verification. Use |
| agent-memoryA | PERSISTENT AGENT MEMORY. Store, recall, or forget compact facts and successful workflow notes across tasks. Memory is scoped optionally by game/place/executor and stored in the existing local playbook store, never in the Roblox game. Use remember after a verified discovery or successful workflow; use recall before planning a similar task. The learn-session operation summarizes the current session's successful tool sequence into a reusable episodic memory. Do not store secrets or tokens. Signature: { operation: "remember" | "recall" | "forget" | "learn-session", key: string?, text: string?, facts: {[string]: any}?, scope: string?, query: string?, limit: any?, fromSeq: number? }. Phase: observe; cost=high; idempotency=read-only. Requires: none. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| tool-quality-auditA | Read-only catalog self-audit for tool titles, descriptions, input documentation, schema examples/defaults/constraints, AI data-flow contracts, prerequisites, capability requirements, mutation side effects, verification paths, and recovery guidance. It evaluates the same centrally compiled metadata exposed to MCP clients, so every current and future tool can be checked against one measurable standard. Filter by exact name/category or return only entries below a score threshold; no Roblox client is required. Signature: { name: string?, category: string?, minimumScore: any?, includePassing: any?, limit: any? }. Phase: verify; cost=medium; idempotency=read-only. Requires: none. Produces: structured-result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| observe-worldA | Perform one bounded, read-only Luau observation that fuses the active or custom character rig, current camera, visible PlayerGui objects, nearby 3D parts, ClickDetectors, ProximityPrompts, TouchTransmitters, and Tool instances in the Backpack or character. It returns compact evidence, exact GetFullName paths plus executable bracket-safe Luau expressions, screen position and distance where available, exact scanned/truncation counts, and stable session-local handles. Handles are retained in getgenv().__mcp_world_brain using weak references when supported and structural fingerprints for later resolve-entity calls. The walk uses GetChildren with hard instance/result caps; it never starts frame loops or performs an unbounded GetDescendants scan. Signature: { radius: any?, roots: any?, features: any?, maxInstances: any?, maxResults: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=read-only. Requires: active-client. Produces: grounded-evidence, bounded-world-model, semantic-entity-handles, actionable-instance-expressions, custom-character-resolution, camera-state, visible-gui, nearby-3d-entities, interaction-targets, inventory-tools. Verify with: resolve-entity. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| resolve-entityA | Resolve a session-local handle returned by observe-world back to its live Roblox Instance. A live weak reference resolves immediately. If it is stale or destroyed, optional bounded rediscovery scores candidates against the stored structural fingerprint (class, name, parent, grandparent, original path, and root) and reattaches the same handle when confidence clears the requested threshold. Returns an exact path and executable bracket-safe expression, class, confidence, staleness state, match evidence, runner-up ambiguity, scan counts, and truncation. Read-only; uses GetChildren with a hard cap and never performs GetDescendants or a frame loop. Signature: { handle: string, rediscover: any?, roots: any?, maxInstances: any?, minConfidence: any?, threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client, semantic handle previously returned by observe-world. Produces: grounded-evidence, live-instance-path, actionable-instance-expression, staleness-status, structural-match-confidence, resolution-evidence. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| smart-taskA | DETERMINISTIC ADAPTIVE ORCHESTRATOR. Turn a goal into a schema-aware plan, preview an explicit typed workflow, or execute it one tool at a time under hard step, tool-call, and wall-clock budgets. Inputs may safely reference prior outputs with exact $steps.. references. Mutations require allowMutations=true and an identical mutating action is never retried. Semantic postconditions are delegated to the read-only assert-state tool and count as verified only when it returns explicit boolean truth. Handled failures may be diagnosed by the read-only explain-failure tool and can activate only named recoverWith branches supplied by the caller. The result includes an evidence timeline, consumed budgets, confidence, unresolved assertions, recovery advice, and a continuation plan. This tool contains no LLM: omitted steps produce deterministic rankTools/matchWorkflows suggestions and leave required arguments blank instead of guessing them. Signature: { goal: string, mode: any?, steps: {{ type: any?, id: string, phase: "observe" | "act" | "verify"?, tool: string, input: any?, assertions: any?, recoverWith: any?, onFailure: any? }}?, fallbacks: any?, successAssertions: any?, finalRecoverWith: any?, allowMutations: any?, budgets: any? }. Phase: orchestrate; cost=medium; idempotency=contextual-write. Requires: explicit-mutation-approval. Produces: grounded-evidence, schema-aware plan, evidence timeline, assertion truth, completion confidence, continuation plan. Verify with: assert-state. Safety: MUTATING; writes live game/client state, may invoke multiple registered tools, mutating nested tools require allowMutations=true. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| assert-stateA | VERIFY LIVE OUTCOMES in one bounded, read-only execution. Evaluate path existence, property and attribute values, effective GUI state, bounded descendant searches, custom-character distance, camera facing angle, and collection counts. Every result includes expected/actual evidence and errors. Missing, unreadable, or incomplete state always fails instead of being mistaken for success. Use this after actions and consume aggregate.passed, passRatio, and confidence as proof of the real outcome. Signature: { assertions: {{ id: string, kind: any, path: string } | { id: string, kind: any, path: string } | { id: string, kind: any, path: string, property: string, expected: string | number | boolean } | { id: string, kind: any, path: string, property: string, expected: string | number | boolean } | { id: string, kind: any, path: string, property: string, expected: string, caseSensitive: any? } | { id: string, kind: any, path: string, property: string, expected: number } | { id: string, kind: any, path: string, property: string, expected: number } | { id: string, kind: any, path: string, attribute: string, expected: string | number | boolean } | { id: string, kind: any, path: string, expected: any?, effective: any? } | { id: string, kind: any, path: string, expected: any? } | { id: string, kind: any, path: string, selector: { by: any, value: string } | { by: any, value: string, match: any?, caseSensitive: any? } | { by: any, value: string, match: any?, caseSensitive: any? }, expected: any? } | { id: string, kind: any, targetPath: string, operator: "at-most" | "at-least", distance: number, playerName: string?, characterPath: string?, rootPath: string? } | { id: string, kind: any, targetPath: string, maxAngleDegrees: any?, cameraPath: string? } | { id: string, kind: any, path: string, scope: any?, operator: "equals" | "not-equals" | "greater" | "less" | "at-least" | "at-most", count: number, selector: { by: any, value: string } | { by: any, value: string, match: any?, caseSensitive: any? } | { by: any, value: string, match: any?, caseSensitive: any? }? }}, scanLimit: any?, readBudget: any?, timeoutMs: any?, threadContext: number? }. Phase: verify; cost=medium; idempotency=read-only. Requires: active-client. Produces: grounded-evidence, per-assertion evidence, aggregate verification result. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| explain-failureA | READ-ONLY AND NO CLIENT REQUIRED. Deterministically classify a failed MCP/Roblox tool call from its error, handled result, attempted input, and optional context. Returns a standard recovery envelope with cause, exact evidence, confidence, retry safety, a schema-validated correctedInput only when safely derivable, live-registry fallback tools ranked using AI contracts and discovery, an optional useful recovery script, and concrete next actions. Use this after any failed or blocked call. It never invokes a fallback and never recommends repeating an identical failed mutation. Signature: { toolName: string, error: any?, result: any?, attemptedInput: any?, context: {[string]: any}? }. Phase: observe; cost=medium; idempotency=read-only. Requires: none. Produces: agent-guidance, grounded-evidence, failure classification, safe retry policy, ranked recovery plan. Safety: read-only. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| state-transactionA | STATE TRANSACTION JOURNAL. Begin a bounded getgenv-backed transaction, capture explicitly requested Instance properties/attributes and camera fields, register known cleanup resources, inspect status, commit without restoration, or rollback in reverse journal order with pcall-isolated per-item results. Cleanup can rollback or explicitly discard expired and cross-place/job orphaned transactions. Registered resources support MCP Drawing ids, held virtual input releases, connection state restoration or cleanup-only disconnection, and canonical __mcp_hooks/__mcp_hook_meta entries when their metadata is safely understood. This is a best-effort client-state journal, not a general undo system: destroyed Instances, fired remotes, server-side changes, arbitrary script side effects, and connections destroyed before capture cannot be reconstructed. Commit intentionally discards all snapshots and does not clean registered resources. Signature: { action: "begin" | "capture" | "status" | "commit" | "rollback" | "cleanup", transactionId: string?, name: string?, targets: any?, captureCamera: any?, cleanupItems: any?, maxItems: number?, expirySeconds: number?, limit: any?, cleanupMode: any?, includeOrphans: any?, threadContext: number? }. Phase: act; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, begin a transaction before mutating reversible client state, capture every property/attribute before changing it. Capabilities: getgenv. Produces: grounded-evidence, bounded state journal, per-item rollback evidence, expired/orphaned cleanup report. Verify with: assert-state. Safety: MUTATING; writes live game/client state, capture stores raw client references in getgenv until commit, rollback, cleanup, expiry, or executor shutdown, rollback writes captured values and runs registered cleanup actions in reverse order, connection disconnect cleanup is irreversible and is reported separately from reversible restoration. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| teach-modeA | Event-driven demonstration recorder with start, poll, stop, and cancel actions. It uses bounded client-side ring buffers and temporary Roblox signal connections to observe keyboard, mouse, touch, throttled movement, GuiButton activation, meaningful GUI appearance/disappearance, ProximityPrompt triggers, character respawns, and Tool equip/backpack transitions. Optional remote capture is started and read through trace-remote-traffic via the normal nested-tool invoker when that tool and executor capabilities are available. stop disconnects every owned listener, returns the retained chronological timeline, and builds a conservative review-required playbook draft with semantic selectors, path evidence, virtual-input/click-button/fire-proximity-prompt and remote candidates, inferred waits/guards, placeholders, uncertainty, and manual-review flags. It does not claim perfect intent inference. cancel disconnects and discards. Idle sessions self-expire and a three-session cap evicts the oldest recorder to prevent leaked listeners. Signature: { action: "start" | "poll" | "stop" | "cancel", sessionId: string?, maxEvents: any?, movementThrottleMs: any?, expirySeconds: any?, maxGuiWatch: any?, sinceSeq: any?, limit: any?, includeRemoteSpy: any?, remoteLimit: any?, sinceRemoteTime: any?, threadContext: number? }. Phase: orchestrate; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, An active Roblox client, The user is ready to demonstrate the workflow after action=start. Capabilities: UserInputService and Roblox RBXScriptSignal connections, getgenv for state across calls, Optional hookmetamethod/getnamecallmethod/newcclosure for remote capture. Produces: grounded-evidence, Bounded chronological event timeline, Semantic instance selectors and path evidence, Conservative reusable playbook draft with uncertainty and review flags. Verify with: assert-state, teach-mode action=poll to confirm events are arriving, Manual review of selectors, guards, timing, and server-reaching candidates, Run the reviewed playbook in a disposable/test game state and verify outcomes. Safety: MUTATING; writes live game/client state, Temporarily installs bounded signal listeners in the active client, May temporarily install a remote-spy metamethod hook when explicitly requested, Does not execute the generated playbook automatically. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| world-deltaA | WRITES LIVE CLIENT OBSERVER STATE — installs RBXScriptConnections and a bounded getgenv registry, but never modifies gameplay Instances. action='start' subscribes to Workspace and PlayerGui descendant additions/removals, character spawn/removal and equipped Tool changes, CurrentCamera replacement and selected camera properties, Backpack Tool changes, plus explicitly requested Instance properties. action='poll' returns cursor-ordered deltas; action='status' reports observer health; action='stop' disconnects every connection. Events are filtered before storage, repeated noise is coalesced/throttled, the ring buffer reports every capacity eviction, and a fixed TTL runs the same cleanup path automatically. It uses Roblox signals only: no RenderStepped, per-frame polling, or world scans. Signature: { action: "start" | "poll" | "status" | "stop", observerId: string?, cursor: any?, limit: any?, maxEvents: any?, ttlSeconds: any?, throttleMs: any?, coalesceWindowMs: any?, filters: any?, cameraProperties: any?, watchedProperties: any?, threadContext: number? }. Phase: observe; cost=medium; idempotency=contextual-write. Requires: active-client, explicit-mutation-approval, getgenv capability, a bounded observation goal and relevant source filters. Capabilities: getgenv. Produces: grounded-evidence, event-driven-world-deltas, monotonic-cursor, buffer-gap-and-drop-accounting, observer-health-and-expiry, coalescing-and-throttle-statistics. Verify with: assert-state, observe-world. Safety: MUTATING; writes live game/client state, installs bounded RBXScriptConnections in the active client, stores bounded observer metadata and events in getgenv.__mcp_world_delta, schedules one TTL cleanup callback; no gameplay Instance is written. On failure: inspect tool-schema for exact fields, defaults, constraints, and an invocation example. |
| list-toolsA | Discover the right tool without scanning all of them. Call with NO arguments to see every category and its count plus the total. Pass { category } to list that category's tools, or { search } to rank tools against a natural-language goal. Results include signatures, required inputs, definition quality, execution phase/cost, capabilities, outputs, contracts, and safety flags. Reads the server's own tool catalog (no game client required). |
| suggest-toolsA | Surface the right tool faster from a natural-language goal. Uses intent aliases and field-aware ranking, then adds a small past-success bias so tools that have worked in this server session float above equally relevant untouched tools. Returns exact signatures, required inputs, definition quality, phase/cost, capabilities, outputs, mutation/client flags, match reasons, and usage stats. Pass { keyword } (required), { limit } (default 10), and optional { category }. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 291 tools
With 291 tools, many overlap heavily: list-strings/find-string-xrefs/find-constants-xref/find-functions-by-constant all search closure constants; remote-spy/monitor-remote/trace-remote-traffic/ensure-remote-spy/get-remote-spy-logs/configure-remote-spy all manage remote capture; hook-function/block-function/spoof-function-return/hook-and-log-function/count-function-calls/trace-call-durations all install function hooks; find-hidden-instances/find-detached-instances/get-nil-instances/find-hidden-remotes/find-hidden-scripts/find-running-scripts heavily overlap. Descriptions are detailed but the boundaries between these clusters are blurry, causing misselection.
Conventions are mixed: many kebab-case verb_noun tools (find-string-xrefs, list-gc-tables, get-instance-properties), but also camelCase (search-instances, get-players, select-client), terse single-word tools (execute, script, run-luau, draw-create, ws-list, filter-gc), and others with irregular verbs. The pattern is not predictable across the set.
291 tools is an extreme mismatch for any coherent server surface; many clusters duplicate functionality (multiple hidden-instance finders, multiple spy managers, multiple hooking variants), indicating over-expansion rather than well-scoped coverage. This is far beyond the 15-tool well-scoped range and well past the 25+ 'too many' threshold.
For the Roblox executor domain the surface is remarkably exhaustive: reflection/GC scanning, closure inspection, hooking, remote/signal monitoring, GUI driving, file I/O, crypto, drawing, packet, WebSocket, and agent-orchestration tools are all present. Minor lifecycle gaps (e.g. no first-class 'list all active hooks/spies' consolidated view) are workarounds, not dead ends.