@el4cteo/rbx-studio-mcp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/index.js +1 -1
- package/dist/tools/session.js +15 -3
- package/dist/tools/session.js.map +1 -1
- package/package.json +1 -1
- package/plugin/src/Config.luau +1 -1
- package/plugin/src/handlers/Debug.luau +26 -1
- package/plugin/src/handlers/Session.luau +17 -0
- package/scripts/release-notes.mjs +43 -0
package/README.md
CHANGED
|
@@ -157,6 +157,8 @@ Port defaults to **44755** — `--port` or `ROBLOX_STUDIO_MCP_PORT`, matched in
|
|
|
157
157
|
|
|
158
158
|
Each agent keeps its **own** target: `set_active_studio` binds per client, so two agents can work on two open places at once and neither can retarget the other. Pass `studioId` on a single call to reach elsewhere without changing your default.
|
|
159
159
|
|
|
160
|
+
Isolation is per MCP connection, and **subagents share their parent's** — measured, not assumed. A subagent calling `set_active_studio` retargets its parent and its siblings, silently: later calls still succeed, just against the wrong place. Give subagents an explicit `studioId` per call instead. Nothing on the wire distinguishes a subagent from its parent, so this is guidance rather than something the server can enforce.
|
|
161
|
+
|
|
160
162
|
## Tools
|
|
161
163
|
|
|
162
164
|
| | |
|
|
@@ -221,6 +223,7 @@ calls are N round trips and N undo steps, a batch is one of each.
|
|
|
221
223
|
- **One Ctrl+Z per action**, via `ChangeHistoryService`.
|
|
222
224
|
- **29 tools, ~16k tokens of schema**, against 43–51 elsewhere. Cursor-paged, capped, with `detail: concise | standard | full`.
|
|
223
225
|
- **Live API dump** for property validation, so typos get suggestions (`Anchorred` → `Anchored`).
|
|
226
|
+
- **Several agents, one Studio**, each with its own target — no id needed on every call, and no agent able to retarget another. The built-in server reaches the same isolation by making `studio_id` mandatory everywhere and removing `set_active_studio`; this keeps the default, so a single open Studio needs no id at all.
|
|
224
227
|
|
|
225
228
|
Not built here: terrain, AI mesh and material generation.
|
|
226
229
|
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { registerInputTools } from "./tools/input.js";
|
|
|
20
20
|
import { registerDeviceTools } from "./tools/device.js";
|
|
21
21
|
import { registerApiTools } from "./tools/api.js";
|
|
22
22
|
import { registerResources } from "./resources.js";
|
|
23
|
-
const VERSION = "0.1.
|
|
23
|
+
const VERSION = "0.1.4";
|
|
24
24
|
function parsePort(argv) {
|
|
25
25
|
const flag = argv.indexOf("--port");
|
|
26
26
|
const raw = flag !== -1 ? argv[flag + 1] : process.env["ROBLOX_STUDIO_MCP_PORT"];
|
package/dist/tools/session.js
CHANGED
|
@@ -21,6 +21,11 @@ export function registerSessionTools(context) {
|
|
|
21
21
|
"place or asking which file they mean. Studio exposes no focused-tab API, " +
|
|
22
22
|
"so with several open, prefer the one holding a selection and otherwise " +
|
|
23
23
|
"ask.\n\n" +
|
|
24
|
+
"`debuggerBeta: \"off\"` appears only when the Debugger Luau API beta is " +
|
|
25
|
+
"disabled, which is the default. `debug` cannot work until the user turns " +
|
|
26
|
+
"it on in File > Beta Features and restarts Studio — tell them rather than " +
|
|
27
|
+
"retrying, because nothing an agent can do will enable it. Everything else " +
|
|
28
|
+
"works regardless.\n\n" +
|
|
24
29
|
"Returns JSON. Selection is capped at 50 entries and selected text at 400 " +
|
|
25
30
|
"characters; use `find` or `script_read` for more.",
|
|
26
31
|
inputSchema: {
|
|
@@ -125,9 +130,16 @@ export function registerSessionTools(context) {
|
|
|
125
130
|
"The choice persists until it is changed or that Studio disconnects. " +
|
|
126
131
|
"While several Studios are connected and none has been chosen, tools " +
|
|
127
132
|
"refuse with AMBIGUOUS_STUDIO rather than guessing.\n\n" +
|
|
128
|
-
"The choice belongs to this
|
|
129
|
-
"Studio
|
|
130
|
-
"moves
|
|
133
|
+
"The choice belongs to this MCP connection alone. Several agents can " +
|
|
134
|
+
"share one Studio, and each keeps its own target, so calling this never " +
|
|
135
|
+
"moves another client's — two editors, or two sessions, can work on two " +
|
|
136
|
+
"places at once.\n\n" +
|
|
137
|
+
"SUBAGENTS SHARE THEIR PARENT'S CONNECTION, and therefore its target. A " +
|
|
138
|
+
"subagent calling this retargets its parent and every sibling, and the " +
|
|
139
|
+
"damage is silent: later calls that name no studioId still succeed, just " +
|
|
140
|
+
"against the wrong place — and if that place is a playtest, everything " +
|
|
141
|
+
"written there is discarded when it stops. Inside a subagent, pass " +
|
|
142
|
+
"`studioId` on each call instead of calling this.",
|
|
131
143
|
inputSchema: {
|
|
132
144
|
studioId: z
|
|
133
145
|
.string()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/plugin/src/Config.luau
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
local Config = {}
|
|
11
11
|
|
|
12
|
-
Config.PLUGIN_VERSION = "0.1.
|
|
12
|
+
Config.PLUGIN_VERSION = "0.1.4"
|
|
13
13
|
|
|
14
14
|
-- Fingerprint of plugin/src, stamped in by scripts/build-plugin.mjs. The server
|
|
15
15
|
-- computes the same hash from its own copy of the sources and compares, so a
|
|
@@ -42,7 +42,27 @@
|
|
|
42
42
|
is why nothing in this file offers one.
|
|
43
43
|
]]
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
--[[
|
|
46
|
+
Fetched defensively, because this module is required at plugin start.
|
|
47
|
+
|
|
48
|
+
`ScriptDebuggerService` exists only when the "Debugger Luau API" beta is on,
|
|
49
|
+
and `GetService` throws for a service that is not registered. This file is
|
|
50
|
+
required from init.server.luau alongside every other handler, so an
|
|
51
|
+
unguarded throw here would take down the whole plugin -- every tool, not
|
|
52
|
+
just these three -- for the majority of users, who have the beta off. The
|
|
53
|
+
failure would also be silent from the outside: no plugin, no connection, and
|
|
54
|
+
nothing to read.
|
|
55
|
+
|
|
56
|
+
Missing is therefore a value, not an error, and `requireService` turns it
|
|
57
|
+
into a message naming the beta.
|
|
58
|
+
]]
|
|
59
|
+
local ScriptDebuggerService: any = nil
|
|
60
|
+
do
|
|
61
|
+
local ok, service = pcall(game.GetService, game, "ScriptDebuggerService")
|
|
62
|
+
if ok then
|
|
63
|
+
ScriptDebuggerService = service
|
|
64
|
+
end
|
|
65
|
+
end
|
|
46
66
|
|
|
47
67
|
local Dispatch = require(script.Parent.Parent.Dispatch)
|
|
48
68
|
local Paths = require(script.Parent.Parent.Paths)
|
|
@@ -190,6 +210,11 @@ local function install(): boolean
|
|
|
190
210
|
return true
|
|
191
211
|
end
|
|
192
212
|
|
|
213
|
+
if ScriptDebuggerService == nil then
|
|
214
|
+
installError = "the service is not registered in this Studio"
|
|
215
|
+
return false
|
|
216
|
+
end
|
|
217
|
+
|
|
193
218
|
local ok, err = pcall(function()
|
|
194
219
|
service.OnStopped = function(stopped: any): any
|
|
195
220
|
-- Capture must never be what keeps a thread paused.
|
|
@@ -20,6 +20,18 @@ local Paths = require(script.Parent.Parent.Paths)
|
|
|
20
20
|
-- session. Bound indirectly so the deprecation lint stays enabled file-wide.
|
|
21
21
|
local studioVersion: () -> string = (version :: any)
|
|
22
22
|
|
|
23
|
+
--[[
|
|
24
|
+
Whether the Debugger Luau API beta is on.
|
|
25
|
+
|
|
26
|
+
`ScriptDebuggerService` is registered only when it is, so asking for the
|
|
27
|
+
service is the test. Guarded because `GetService` throws on a service that
|
|
28
|
+
does not exist, and status must answer for every Studio rather than only the
|
|
29
|
+
ones where `debug` would have worked anyway.
|
|
30
|
+
]]
|
|
31
|
+
local function debuggerAvailable(): boolean
|
|
32
|
+
return (pcall(game.GetService, game, "ScriptDebuggerService"))
|
|
33
|
+
end
|
|
34
|
+
|
|
23
35
|
-- Selection can be tens of thousands of instances after a rubber-band drag.
|
|
24
36
|
-- Anything past this is noise for an agent and would blow the response budget.
|
|
25
37
|
local MAX_SELECTION = 50
|
|
@@ -145,6 +157,11 @@ function Session.status(): { [string]: any }
|
|
|
145
157
|
scriptCount = totals.scripts,
|
|
146
158
|
studioVersion = studioVersion(),
|
|
147
159
|
emulatedDevice = Emulation.summary(),
|
|
160
|
+
-- Present only when it is off, so the usual answer costs nothing. Said
|
|
161
|
+
-- here rather than left for `debug` to discover, because the fix needs
|
|
162
|
+
-- the user: it is a Studio setting behind a restart, not something an
|
|
163
|
+
-- agent can turn on mid-task.
|
|
164
|
+
debuggerBeta = if debuggerAvailable() then nil else "off",
|
|
148
165
|
}
|
|
149
166
|
end
|
|
150
167
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulls one version's section out of CHANGELOG.md for the release body.
|
|
3
|
+
*
|
|
4
|
+
* Exists so a release cannot go out without notes. GitHub's own
|
|
5
|
+
* `generate_release_notes` lists commit subjects, which are written for whoever
|
|
6
|
+
* reads the diff and say nothing useful to someone deciding whether to upgrade.
|
|
7
|
+
* Failing the workflow on a missing section is the point: the alternative is a
|
|
8
|
+
* tag that quietly publishes with an empty body, which is what happened for
|
|
9
|
+
* 0.1.1 through 0.1.3.
|
|
10
|
+
*
|
|
11
|
+
* Usage: node scripts/release-notes.mjs <version> <outFile>
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
14
|
+
|
|
15
|
+
const [, , rawVersion, outFile] = process.argv;
|
|
16
|
+
if (!rawVersion || !outFile) {
|
|
17
|
+
throw new Error("usage: release-notes.mjs <version> <outFile>");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Tags carry a leading v; the changelog headings do not.
|
|
21
|
+
const version = rawVersion.replace(/^v/, "");
|
|
22
|
+
const changelog = readFileSync("CHANGELOG.md", "utf8");
|
|
23
|
+
|
|
24
|
+
// Everything from this version's heading up to the next one, so adding a
|
|
25
|
+
// release never means touching the extractor.
|
|
26
|
+
const heading = new RegExp(`^## ${version.replace(/\./g, "\\.")}\\s*$`, "m");
|
|
27
|
+
const start = changelog.search(heading);
|
|
28
|
+
if (start === -1) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`CHANGELOG.md has no "## ${version}" section. Add one describing what changed ` +
|
|
31
|
+
`before tagging, or the release would publish with an empty body.`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const body = changelog.slice(start).split("\n").slice(1).join("\n");
|
|
36
|
+
const next = body.search(/^## /m);
|
|
37
|
+
const section = (next === -1 ? body : body.slice(0, next)).trim();
|
|
38
|
+
|
|
39
|
+
if (section.length === 0) {
|
|
40
|
+
throw new Error(`The "## ${version}" section in CHANGELOG.md is empty.`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
writeFileSync(outFile, `${section}\n`);
|