Skip to content

feat: Add write_script and read_script tools for script management#52

Closed
kevinswint wants to merge 2 commits intoRoblox:mainfrom
kevinswint:feature/write-script-tool
Closed

feat: Add write_script and read_script tools for script management#52
kevinswint wants to merge 2 commits intoRoblox:mainfrom
kevinswint:feature/write-script-tool

Conversation

@kevinswint
Copy link

@kevinswint kevinswint commented Jan 10, 2026

Summary

This PR adds MCP tools for reading and writing script source code:

  • write_script - Creates or updates Script, LocalScript, or ModuleScript with provided Luau source
  • read_script - Reads source code from existing scripts (enables diff/patch workflows)

Both tools use ScriptEditorService for safe, Studio-integrated script access.

Motivation

AI assistants need to both read existing code (to understand before modifying) and write new code. The run_code tool can execute Luau but cannot access script source directly due to Roblox security restrictions.

ScriptEditorService provides the officially supported methods:

  • UpdateSourceAsync() for writing
  • GetEditorSource() for reading

Changes

Rust Server:

  • Added WriteScript and ReadScript structs
  • Added tool functions for both operations

Plugin:

  • WriteScript.luau - Creates scripts, handles nested paths, writes source
  • ReadScript.luau - Navigates to script, reads source with metadata

Types:

  • Added WriteScriptArgs and ReadScriptArgs type definitions

Test plan

  • Create a Script in ServerScriptService
  • Create nested paths with automatic folder creation
  • Update existing script source
  • Read script source back and verify content
  • Verify metadata (type, path, char count, line count)

Example Usage

-- Write a script
write_script({
  path: "ServerScriptService.GameManager",
  source: "print('Hello from MCP!')"
})

-- Read it back
read_script({
  path: "ServerScriptService.GameManager"
})
-- Returns: [SUCCESS] Script at ServerScriptService.GameManager (25 characters, 1 lines)
-- print('Hello from MCP!')

🤖 Generated with Claude Code

@kevinswint kevinswint force-pushed the feature/write-script-tool branch from c07a213 to afec379 Compare January 30, 2026 02:56
Adds a new MCP tool that creates or updates Script, LocalScript, or
ModuleScript instances with provided Luau source code.

Why this matters:
The official MCP server can only execute code via run_code, but cannot
create or modify script source directly. This is because Roblox blocks
direct Script.Source access. This tool uses ScriptEditorService:UpdateSourceAsync()
- the officially supported method for writing script source in Studio plugins.

Features:
- Creates scripts in any service (ServerScriptService, ReplicatedStorage, etc.)
- Automatically creates intermediate folders for nested paths
- Updates existing scripts with new source code
- Supports Script, LocalScript, and ModuleScript types
- Optional script_type parameter (defaults to "Script")

Plugin changes:
- New WriteScript.luau tool handler
- Updated Types.luau with WriteScriptArgs

Usage:
  write_script({
    path: "ServerScriptService.GameManager",
    source: "print('Hello!')",
    script_type: "Script"
  })
@kevinswint kevinswint force-pushed the feature/write-script-tool branch from afec379 to ce154a2 Compare January 30, 2026 03:54
Adds read_script tool that reads source code from existing scripts using
ScriptEditorService:GetEditorSource(). This enables diff/patch workflows
and allows Claude to understand existing code before modifying it.

Returns source code with metadata (script type, path, character count,
line count).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@kevinswint kevinswint changed the title Add write_script tool for creating and updating scripts feat: Add write_script and read_script tools for script management Jan 30, 2026
@Shchvova
Copy link
Contributor

Hi! We added community contribution guidelines to help us triage and accept PRs.

This PR adds several tools which would be better described as tools executed with run_code. MCP tools are added to each LLM request consuming tokens. We tested and found that all LLMS can crate scripts with Instance.new() and set/read sources with .Source property.

Thank you for understanding!

@Shchvova Shchvova closed this Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants