@valbuild/mcp 0.129.0 → 0.130.0
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/CHANGELOG.md +68 -0
- package/dist/valbuild-mcp.cjs.dev.js +16 -2
- package/dist/valbuild-mcp.cjs.prod.js +16 -2
- package/dist/valbuild-mcp.esm.js +16 -2
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# @valbuild/mcp
|
|
2
2
|
|
|
3
|
+
## 0.130.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#684](https://github.com/valbuild/val/pull/684) [`cab4098`](https://github.com/valbuild/val/commit/cab4098969585977b8d7574e86d66fcb01cb1d75) Thanks [@freekh](https://github.com/freekh)! - A third ValOps mode, for a host that already holds its own source
|
|
8
|
+
|
|
9
|
+
EXPERIMENTAL. `fs` mode assumes a working tree it can watch and write; `http`
|
|
10
|
+
mode assumes Val's content service owns the patch chain and that a commit is a
|
|
11
|
+
git commit. A host that builds and publishes its own output is neither: it holds
|
|
12
|
+
the source already, it has nowhere to watch, and its "commit" is a new build.
|
|
13
|
+
|
|
14
|
+
Forcing such a host into `fs` mode cost three things, all now fixed: `/stat`
|
|
15
|
+
long-polled against watchers that could never fire, burning CPU for the whole
|
|
16
|
+
hold to learn nothing;
|
|
17
|
+
`/api/val/enable` 500'd; and every read of a `.val.ts` went through a shimmed
|
|
18
|
+
filesystem when the host could simply hand the source over.
|
|
19
|
+
|
|
20
|
+
`ValOpsMemory` takes the source as `sourceFiles`, refuses the local binary
|
|
21
|
+
members by name — this configuration uses Val's remote files — and answers the
|
|
22
|
+
history members with the same closed `not-supported-in-fs-mode` error `ValOpsFS`
|
|
23
|
+
gives, so the History UI degrades the way it already knows how rather than
|
|
24
|
+
inventing a commit list.
|
|
25
|
+
|
|
26
|
+
`getStat` still long-polls -- the hold is what paces the client, and an earlier
|
|
27
|
+
version that answered immediately turned a 20-second poll into a request every
|
|
28
|
+
6ms -- but it parks on a SIGNAL rather than a timer. This mode owns its store,
|
|
29
|
+
so it is told when something changes: no timers while parked, and a patch
|
|
30
|
+
written by another tab is seen at once rather than up to 250ms later.
|
|
31
|
+
|
|
32
|
+
Two seams come with it. `commitPrepared` lets a host take what a save produced
|
|
33
|
+
instead of a git commit, and `publishOverride` lets a publish be something other
|
|
34
|
+
than a push. Both are opt-in; an app that sets neither behaves exactly as before.
|
|
35
|
+
|
|
36
|
+
The in-memory patch store is explicitly **not durable**. It is behind
|
|
37
|
+
`ValPatchStore`, so a durable implementation is a swap rather than a rewrite,
|
|
38
|
+
but as shipped a restart loses unpublished patches.
|
|
39
|
+
|
|
40
|
+
**Memory mode authenticates.** `ValOps` gained `requiresAuth` alongside
|
|
41
|
+
`patchesAreLocal`, because one flag was answering two questions: whether a store
|
|
42
|
+
auto-saves or publishes (behaviour, reported as `mode` and keyed off by the UI),
|
|
43
|
+
and whether an unauthenticated request may write (security). With two
|
|
44
|
+
implementations the answers coincided — `fs` is a developer's own machine where
|
|
45
|
+
no credential exists, `http` is remote — so `getAuth` was written against
|
|
46
|
+
`patchesAreLocal` and returned anonymous _success_ for a missing cookie, an
|
|
47
|
+
invalid JWT, an unparseable payload, or no configured secret.
|
|
48
|
+
|
|
49
|
+
Memory mode splits them: its store is local, and it runs deployed. It therefore
|
|
50
|
+
requires a verified session, like `http` mode. A host that authorises requests
|
|
51
|
+
before Val sees them can opt out with `unsafelyAllowUnauthenticated`, which is
|
|
52
|
+
spelled that way on purpose and warns at startup. `fs` mode is unchanged.
|
|
53
|
+
|
|
54
|
+
Val's own MCP endpoint refuses memory mode outright. It has the same absence fs
|
|
55
|
+
mode has — no credential, no backend, every permission check on the far side of
|
|
56
|
+
one — and unlike fs mode it is meant to run deployed, so the existing
|
|
57
|
+
"development only" and loopback guards refuse nothing. A host in this mode owns
|
|
58
|
+
its own trust boundary and can offer the tools through it.
|
|
59
|
+
|
|
60
|
+
Internally, the routes' `instanceof ValOpsFS` checks meant "is this a local
|
|
61
|
+
store" — correct with two implementations and silently wrong with three. They are
|
|
62
|
+
now `ValOps.patchesAreLocal` at all 17 policy sites.
|
|
63
|
+
|
|
64
|
+
### Patch Changes
|
|
65
|
+
|
|
66
|
+
- Updated dependencies [[`cab4098`](https://github.com/valbuild/val/commit/cab4098969585977b8d7574e86d66fcb01cb1d75), [`8425378`](https://github.com/valbuild/val/commit/8425378c315ea46b5d822f1130b633e0449ff1b0), [`cab4098`](https://github.com/valbuild/val/commit/cab4098969585977b8d7574e86d66fcb01cb1d75), [`473a185`](https://github.com/valbuild/val/commit/473a185f70351b44388f3bc1852649e2c1dbe001), [`64f0de3`](https://github.com/valbuild/val/commit/64f0de339b8621cb5a6c422dfe55cae5b2bbe2a0), [`cab4098`](https://github.com/valbuild/val/commit/cab4098969585977b8d7574e86d66fcb01cb1d75)]:
|
|
67
|
+
- @valbuild/server@0.130.0
|
|
68
|
+
- @valbuild/core@0.130.0
|
|
69
|
+
- @valbuild/shared@0.130.0
|
|
70
|
+
|
|
3
71
|
## 0.129.0
|
|
4
72
|
|
|
5
73
|
### Patch Changes
|
|
@@ -3365,7 +3365,7 @@ var packageJson = {
|
|
|
3365
3365
|
"./package.json": "./package.json"
|
|
3366
3366
|
},
|
|
3367
3367
|
types: "dist/valbuild-mcp.cjs.d.ts",
|
|
3368
|
-
version: "0.
|
|
3368
|
+
version: "0.130.0",
|
|
3369
3369
|
scripts: {
|
|
3370
3370
|
typecheck: "tsc --noEmit",
|
|
3371
3371
|
test: "jest",
|
|
@@ -4343,7 +4343,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
4343
4343
|
}
|
|
4344
4344
|
|
|
4345
4345
|
/**
|
|
4346
|
-
* The
|
|
4346
|
+
* The three ways this route is dangerous, all refused here.
|
|
4347
4347
|
*
|
|
4348
4348
|
* 1. **Local filesystem mode outside development.** In fs mode there is no
|
|
4349
4349
|
* credential and no backend: the tools read and write the running process's
|
|
@@ -4361,10 +4361,24 @@ function initValMcp(valModules, config, opts) {
|
|
|
4361
4361
|
* needs a credential in fs mode. So a cross-origin `Origin` is refused, and
|
|
4362
4362
|
* in fs mode the request must actually be addressed to a loopback host.
|
|
4363
4363
|
*
|
|
4364
|
+
* 3. **Memory mode, always.** A host that holds its own source has the same
|
|
4365
|
+
* absence fs mode has -- no credential, no backend, and every permission
|
|
4366
|
+
* check on the far side of one -- and unlike fs mode it is *meant* to run
|
|
4367
|
+
* deployed, so "only in development" refuses nothing. Neither does the
|
|
4368
|
+
* loopback check: there is no localhost to require. So this is refused
|
|
4369
|
+
* outright rather than narrowed. A host in this mode owns its own trust
|
|
4370
|
+
* boundary and can offer the tools through it; what it cannot do is let
|
|
4371
|
+
* Val's own endpoint write content for anyone who can reach the port.
|
|
4372
|
+
*
|
|
4364
4373
|
* MCP clients are not browsers and send no `Origin`, so the check costs them
|
|
4365
4374
|
* nothing.
|
|
4366
4375
|
*/
|
|
4367
4376
|
function refuseUnsafeRequest(request, mode) {
|
|
4377
|
+
if (mode === "memory") {
|
|
4378
|
+
return jsonResponse(403, {
|
|
4379
|
+
error: "Val: the MCP endpoint is disabled. This project is running in memory mode, where the host holds the source and MCP calls would be unauthenticated writes to it. Serve the tools through the host's own authenticated surface instead."
|
|
4380
|
+
});
|
|
4381
|
+
}
|
|
4368
4382
|
if (mode === "fs" && process.env.NODE_ENV !== "development") {
|
|
4369
4383
|
return jsonResponse(403, {
|
|
4370
4384
|
error: "Val: the MCP endpoint is disabled. This project is running in local filesystem mode, where MCP calls are unauthenticated and write directly to the working tree, so it is only served in development. Configure Val for proxy mode to use MCP on a deployed host."
|
|
@@ -3365,7 +3365,7 @@ var packageJson = {
|
|
|
3365
3365
|
"./package.json": "./package.json"
|
|
3366
3366
|
},
|
|
3367
3367
|
types: "dist/valbuild-mcp.cjs.d.ts",
|
|
3368
|
-
version: "0.
|
|
3368
|
+
version: "0.130.0",
|
|
3369
3369
|
scripts: {
|
|
3370
3370
|
typecheck: "tsc --noEmit",
|
|
3371
3371
|
test: "jest",
|
|
@@ -4343,7 +4343,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
4343
4343
|
}
|
|
4344
4344
|
|
|
4345
4345
|
/**
|
|
4346
|
-
* The
|
|
4346
|
+
* The three ways this route is dangerous, all refused here.
|
|
4347
4347
|
*
|
|
4348
4348
|
* 1. **Local filesystem mode outside development.** In fs mode there is no
|
|
4349
4349
|
* credential and no backend: the tools read and write the running process's
|
|
@@ -4361,10 +4361,24 @@ function initValMcp(valModules, config, opts) {
|
|
|
4361
4361
|
* needs a credential in fs mode. So a cross-origin `Origin` is refused, and
|
|
4362
4362
|
* in fs mode the request must actually be addressed to a loopback host.
|
|
4363
4363
|
*
|
|
4364
|
+
* 3. **Memory mode, always.** A host that holds its own source has the same
|
|
4365
|
+
* absence fs mode has -- no credential, no backend, and every permission
|
|
4366
|
+
* check on the far side of one -- and unlike fs mode it is *meant* to run
|
|
4367
|
+
* deployed, so "only in development" refuses nothing. Neither does the
|
|
4368
|
+
* loopback check: there is no localhost to require. So this is refused
|
|
4369
|
+
* outright rather than narrowed. A host in this mode owns its own trust
|
|
4370
|
+
* boundary and can offer the tools through it; what it cannot do is let
|
|
4371
|
+
* Val's own endpoint write content for anyone who can reach the port.
|
|
4372
|
+
*
|
|
4364
4373
|
* MCP clients are not browsers and send no `Origin`, so the check costs them
|
|
4365
4374
|
* nothing.
|
|
4366
4375
|
*/
|
|
4367
4376
|
function refuseUnsafeRequest(request, mode) {
|
|
4377
|
+
if (mode === "memory") {
|
|
4378
|
+
return jsonResponse(403, {
|
|
4379
|
+
error: "Val: the MCP endpoint is disabled. This project is running in memory mode, where the host holds the source and MCP calls would be unauthenticated writes to it. Serve the tools through the host's own authenticated surface instead."
|
|
4380
|
+
});
|
|
4381
|
+
}
|
|
4368
4382
|
if (mode === "fs" && "production" !== "development") {
|
|
4369
4383
|
return jsonResponse(403, {
|
|
4370
4384
|
error: "Val: the MCP endpoint is disabled. This project is running in local filesystem mode, where MCP calls are unauthenticated and write directly to the working tree, so it is only served in development. Configure Val for proxy mode to use MCP on a deployed host."
|
package/dist/valbuild-mcp.esm.js
CHANGED
|
@@ -3356,7 +3356,7 @@ var packageJson = {
|
|
|
3356
3356
|
"./package.json": "./package.json"
|
|
3357
3357
|
},
|
|
3358
3358
|
types: "dist/valbuild-mcp.cjs.d.ts",
|
|
3359
|
-
version: "0.
|
|
3359
|
+
version: "0.130.0",
|
|
3360
3360
|
scripts: {
|
|
3361
3361
|
typecheck: "tsc --noEmit",
|
|
3362
3362
|
test: "jest",
|
|
@@ -4334,7 +4334,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
4334
4334
|
}
|
|
4335
4335
|
|
|
4336
4336
|
/**
|
|
4337
|
-
* The
|
|
4337
|
+
* The three ways this route is dangerous, all refused here.
|
|
4338
4338
|
*
|
|
4339
4339
|
* 1. **Local filesystem mode outside development.** In fs mode there is no
|
|
4340
4340
|
* credential and no backend: the tools read and write the running process's
|
|
@@ -4352,10 +4352,24 @@ function initValMcp(valModules, config, opts) {
|
|
|
4352
4352
|
* needs a credential in fs mode. So a cross-origin `Origin` is refused, and
|
|
4353
4353
|
* in fs mode the request must actually be addressed to a loopback host.
|
|
4354
4354
|
*
|
|
4355
|
+
* 3. **Memory mode, always.** A host that holds its own source has the same
|
|
4356
|
+
* absence fs mode has -- no credential, no backend, and every permission
|
|
4357
|
+
* check on the far side of one -- and unlike fs mode it is *meant* to run
|
|
4358
|
+
* deployed, so "only in development" refuses nothing. Neither does the
|
|
4359
|
+
* loopback check: there is no localhost to require. So this is refused
|
|
4360
|
+
* outright rather than narrowed. A host in this mode owns its own trust
|
|
4361
|
+
* boundary and can offer the tools through it; what it cannot do is let
|
|
4362
|
+
* Val's own endpoint write content for anyone who can reach the port.
|
|
4363
|
+
*
|
|
4355
4364
|
* MCP clients are not browsers and send no `Origin`, so the check costs them
|
|
4356
4365
|
* nothing.
|
|
4357
4366
|
*/
|
|
4358
4367
|
function refuseUnsafeRequest(request, mode) {
|
|
4368
|
+
if (mode === "memory") {
|
|
4369
|
+
return jsonResponse(403, {
|
|
4370
|
+
error: "Val: the MCP endpoint is disabled. This project is running in memory mode, where the host holds the source and MCP calls would be unauthenticated writes to it. Serve the tools through the host's own authenticated surface instead."
|
|
4371
|
+
});
|
|
4372
|
+
}
|
|
4359
4373
|
if (mode === "fs" && process.env.NODE_ENV !== "development") {
|
|
4360
4374
|
return jsonResponse(403, {
|
|
4361
4375
|
error: "Val: the MCP endpoint is disabled. This project is running in local filesystem mode, where MCP calls are unauthenticated and write directly to the working tree, so it is only served in development. Configure Val for proxy mode to use MCP on a deployed host."
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"./package.json": "./package.json"
|
|
21
21
|
},
|
|
22
22
|
"types": "dist/valbuild-mcp.cjs.d.ts",
|
|
23
|
-
"version": "0.
|
|
23
|
+
"version": "0.130.0",
|
|
24
24
|
"preconstruct": {
|
|
25
25
|
"entrypoints": [
|
|
26
26
|
"./index.ts",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"minimatch": "^10.2.6",
|
|
33
33
|
"zod": "^4.4.3",
|
|
34
|
-
"@valbuild/
|
|
35
|
-
"@valbuild/
|
|
36
|
-
"@valbuild/
|
|
34
|
+
"@valbuild/shared": "0.130.0",
|
|
35
|
+
"@valbuild/server": "0.130.0",
|
|
36
|
+
"@valbuild/core": "0.130.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@prettier/sync": "^0.6.1",
|