Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Chrrxs/robloxstudio-mcp/llms.txt

Use this file to discover all available pages before exploring further.

The script-editing tools give an AI agent precise control over Luau source code. Use set_script_source to overwrite an entire script, the line-based tools (edit_script_lines, insert_script_lines, delete_script_lines) for targeted in-place edits that preserve unchanged code, and find_and_replace_in_scripts to apply the same change across every script in the place at once. Before using any of these tools, read the current source with get_script_source and the API docs for any engine classes involved with get_roblox_docs.

set_script_source

Replace the entire source of a script with new content. Use this when you need to write a script from scratch or completely rewrite an existing one. For partial edits — changing a few lines, inserting a block, or fixing a bug — use the line-editing tools below to avoid overwriting unrelated code.
instancePath
string
required
Canonical path to a LuaSourceContainer (e.g. game.ServerScriptService.RoundManager or game.ReplicatedStorage.Modules.Combat).
source
string
required
The complete new source code to write. All existing content is replaced.
instance_id
string
Which connected Studio place to target. Required when multiple places are connected; omit when only one is open. Use get_connected_instances to list available IDs.
set_script_source replaces the entire script. Any code not included in the source string will be lost. For partial edits, use edit_script_lines, insert_script_lines, or delete_script_lines instead.
-- Example: write a new ModuleScript from scratch
-- instancePath: "game.ReplicatedStorage.Modules.MathUtils"
-- source:
local MathUtils = {}

function MathUtils.clamp(value, min, max)
    return math.max(min, math.min(max, value))
end

function MathUtils.lerp(a, b, t)
    return a + (b - a) * t
end

return MathUtils

edit_script_lines

Replace a specific block of text inside a script by matching exact content. The old_string must uniquely identify the text to replace within the script — if the same string appears more than once, the tool will reject the edit. When the text is ambiguous, use line_range to anchor the match to a specific line number.
instancePath
string
required
Canonical path to a LuaSourceContainer.
old_string
string
required
The exact text to find and replace. Must appear exactly once in the script unless line_range is also provided. Include enough surrounding context (e.g. the full function signature or block header) to make the match unique.
new_string
string
required
The replacement text. Replaces the matched old_string verbatim — indentation and whitespace are preserved exactly as supplied.
line_range
string
Optional single-line anchor (e.g. "42") where old_string begins. When provided, the uniqueness check is skipped and the tool requires old_string to match starting at exactly that line. Use this when the same string appears more than once in the file.
instance_id
string
Which connected Studio place to target. Required when multiple places are connected.
Uniqueness requirement: if old_string appears more than once in the script and no line_range is given, the tool returns an error listing every line where it matched. Read the script with get_script_source to identify the correct line, then re-call with line_range set to that line number.
-- Example: change a hard-coded health value to a variable reference
-- old_string:
local MAX_HEALTH = 100
-- new_string:
local MAX_HEALTH = GameConfig.PlayerMaxHealth

-- Example: anchor edit to line 42 when the same pattern repeats
-- old_string: "local speed = 16"
-- new_string: "local speed = WalkSpeedConfig.Default"
-- line_range: "42"

insert_script_lines

Insert new lines of content into a script at any position. Pass afterLine: 0 to prepend content at the very beginning of the file.
instancePath
string
required
Canonical path to a LuaSourceContainer.
newContent
string
required
The text to insert. The content is placed starting on the line immediately after afterLine.
afterLine
number
The 1-based line number after which the new content is inserted. Pass 0 to insert at the very beginning of the file. Defaults to 0 when omitted.
instance_id
string
Which connected Studio place to target. Required when multiple places are connected.
-- Example: prepend a module-level require at the top of a script
-- instancePath: "game.ServerScriptService.EnemySpawner"
-- afterLine: 0
-- newContent:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Config = require(ReplicatedStorage.Config)

-- Example: append a new helper function after line 80
-- afterLine: 80
-- newContent:
local function clampHealth(value)
    return math.clamp(value, 0, MAX_HEALTH)
end

delete_script_lines

Delete a specific range of lines from a script. The range is 1-indexed and inclusive. Open-ended ranges (e.g. "100-") are not accepted for deletion — you must specify both a start and an end line.
instancePath
string
required
Canonical path to a LuaSourceContainer.
line_range
string
required
The lines to delete. Must be a closed range like "10-20" (delete lines 10 through 20 inclusive) or a single line like "42" (delete only line 42). Open-ended ranges such as "100-" or "-50" are rejected.
instance_id
string
Which connected Studio place to target. Required when multiple places are connected.
Before deleting a range, read the target lines with get_script_source and a matching line_range to confirm you have the right lines. Deletions cannot be previewed — use undo to reverse a mistake.
-- Example: remove a deprecated debug block on lines 55-60
-- instancePath: "game.ServerScriptService.MatchManager"
-- line_range: "55-60"

-- Example: remove a single unused line
-- line_range: "42"

find_and_replace_in_scripts

Find and replace text across every script in the game (or a scoped subtree) in a single call. Supports both literal text and Lua pattern matching, class-type filtering, and a dryRun mode that shows exactly what would change before you commit. Pair with grep_scripts when you only need to find matches — find_and_replace_in_scripts is for when you are ready to write.
pattern
string
required
The text or Lua pattern to search for across all script sources.
replacement
string
required
The replacement text. When usePattern is true, Lua captures (%1, %2, etc.) are supported.
caseSensitive
boolean
Case-sensitive matching. Defaults to false. Must be true when usePattern is true.
usePattern
boolean
Use Lua pattern matching instead of literal text search. Defaults to false. Requires caseSensitive: true.
path
string
Limit the scope to a subtree (e.g. "game.ServerScriptService" to leave client scripts untouched).
classFilter
string
Only process scripts of a specific class: "Script", "LocalScript", or "ModuleScript".
dryRun
boolean
When true, return a preview of all changes that would be made without applying them. Defaults to false. Always run a dry-run first for broad replacements.
maxReplacements
number
Safety limit on the total number of replacements applied. Defaults to 1000. Reduce this value when testing a replacement on a large codebase to avoid unintended mass changes.
instance_id
string
Which connected Studio place to target. Required when multiple places are connected.

Example: find deprecated API usage and replace it safely

Roblox deprecated game.Players.LocalPlayer:GetMouse() in favour of UserInputService. The workflow below uses dryRun first to preview the scope of change, then applies it:
// Step 1 — dry run to see what would change
{
  "pattern": ":GetMouse()",
  "replacement": "-- TODO: migrate to UserInputService",
  "caseSensitive": true,
  "dryRun": true,
  "classFilter": "LocalScript"
}
After reviewing the dry-run output, confirm the replacement is correct and remove dryRun to apply:
// Step 2 — apply the replacement
{
  "pattern": "local mouse = game.Players.LocalPlayer:GetMouse()",
  "replacement": "local UserInputService = game:GetService(\"UserInputService\")",
  "caseSensitive": true,
  "dryRun": false,
  "classFilter": "LocalScript",
  "maxReplacements": 50
}
Use grep_scripts with filesOnly: true first to get a list of affected scripts. Then use find_and_replace_in_scripts with dryRun: true to verify the exact lines that will change, and finally apply with dryRun: false. This three-step pattern prevents accidental mass edits.

Build docs developers (and LLMs) love