@valbuild/next 0.121.0 → 0.122.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 +65 -0
- package/dist/{ValApp-e17eb734.esm.js → ValApp-074c8289.esm.js} +1 -1
- package/dist/ValApp-17eb6e93.cjs.js +7 -0
- package/dist/{ValApp-90c4171d.cjs.prod.js → ValApp-17eb6e93.cjs.prod.js} +1 -1
- package/dist/{ValApp-c1c3ef55.cjs.dev.js → ValApp-2bdb460a.cjs.dev.js} +1 -1
- package/dist/{ValNextProvider-f206d2ea.cjs.dev.js → ValNextProvider-016a494b.cjs.dev.js} +1 -1
- package/dist/{ValNextProvider-588f2ff0.esm.js → ValNextProvider-32156acd.esm.js} +1 -1
- package/dist/ValNextProvider-72d3561b.cjs.js +7 -0
- package/dist/{ValNextProvider-bd3f89d3.cjs.prod.js → ValNextProvider-72d3561b.cjs.prod.js} +1 -1
- package/dist/declarations/src/server/initValMcp.d.ts +5 -5
- package/dist/{fallbackColors-5ead2c26.esm.js → fallbackColors-77aeedf8.esm.js} +2 -2
- package/dist/{fallbackColors-d4a5b0da.cjs.prod.js → fallbackColors-8842243c.cjs.prod.js} +2 -2
- package/dist/{fallbackColors-9a2ac53a.cjs.dev.js → fallbackColors-a491e700.cjs.dev.js} +2 -2
- package/dist/valbuild-next.cjs.dev.js +2 -2
- package/dist/valbuild-next.cjs.prod.js +2 -2
- package/dist/valbuild-next.esm.js +2 -2
- package/package.json +6 -6
- package/server/dist/valbuild-next-server.cjs.dev.js +43 -28
- package/server/dist/valbuild-next-server.cjs.prod.js +43 -28
- package/server/dist/valbuild-next-server.esm.js +43 -28
- package/dist/ValApp-90c4171d.cjs.js +0 -7
- package/dist/ValNextProvider-bd3f89d3.cjs.js +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,70 @@
|
|
|
1
1
|
# @valbuild/next
|
|
2
2
|
|
|
3
|
+
## 0.122.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#597](https://github.com/valbuild/val/pull/597) [`5d14612`](https://github.com/valbuild/val/commit/5d14612f612d657a37338136188f2b3c02b28fe7) Thanks [@freekh](https://github.com/freekh)! - MCP: remove personal access token auth. The endpoint now needs an `oauth`
|
|
8
|
+
config, or local filesystem mode.
|
|
9
|
+
|
|
10
|
+
Until now, an MCP endpoint with no `oauth` config accepted whatever bearer token
|
|
11
|
+
a caller presented and relayed it to the Val content backend unread. The
|
|
12
|
+
reasoning was that without an issuer the app has no key to check a token
|
|
13
|
+
against, so it should not pretend to be the authority on what that token may
|
|
14
|
+
do — and that much was right. The shape was not: a credential the app cannot
|
|
15
|
+
check is one it cannot refuse either, so "a deployed endpoint that authenticates
|
|
16
|
+
nobody" was a supported configuration, and an app could serve content-rewriting
|
|
17
|
+
tools without ever being told where its callers should authorize.
|
|
18
|
+
|
|
19
|
+
**If you run Val in proxy mode**, MCP now requires the `oauth` config that
|
|
20
|
+
shipped in `0.120.0`. Callers authorize as themselves against the Val
|
|
21
|
+
authorization server, this app verifies the token's signature, issuer, audience
|
|
22
|
+
and expiry itself, and patches carry the verified profile as their author:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
initValMcp(valModules, config, {
|
|
26
|
+
oauth: {
|
|
27
|
+
issuer: "https://admin.val.build",
|
|
28
|
+
resource: "https://your-app.com/api/mcp",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Leave it out and the endpoint answers `500` naming the missing config, rather
|
|
34
|
+
than serving the request.
|
|
35
|
+
|
|
36
|
+
**If you run Val in local filesystem mode**, nothing changes. Local development
|
|
37
|
+
still needs no `oauth` config and no authorization server: there is no backend
|
|
38
|
+
to authenticate to, and patches are written with no author. A token presented
|
|
39
|
+
to such a project is still refused rather than ignored — the endpoint answers
|
|
40
|
+
`400` and says to take the credential out of the client's configuration, since
|
|
41
|
+
what it reached was a working tree with no permission check in front of it.
|
|
42
|
+
|
|
43
|
+
Two API changes if you built your own host on `createValTools`:
|
|
44
|
+
|
|
45
|
+
- `ValToolContext.auth` no longer has a `{ type: "pat", pat }` variant.
|
|
46
|
+
`{ type: "verified-profile", profileId, scopes }` is the only credential the
|
|
47
|
+
registry accepts, and `null` still means local filesystem mode.
|
|
48
|
+
- `createValOps` no longer takes an `auth` argument. `ValOpsHttp` still accepts
|
|
49
|
+
a personal access token directly — that is how `val debug` uses the token from
|
|
50
|
+
`val login` — but no server request builds one.
|
|
51
|
+
|
|
52
|
+
Proxy mode also stops keeping one data layer per credential. Each personal
|
|
53
|
+
access token needed its own `ValOpsHttp` to hold it, each of those cached the
|
|
54
|
+
project's evaluated modules, and the bounded cache that kept the memory in
|
|
55
|
+
check turned an eviction into a re-evaluation of every module on the next call.
|
|
56
|
+
Verified callers all share one instance, because they all reach the backend
|
|
57
|
+
under the app's own API key.
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- Updated dependencies [[`be32261`](https://github.com/valbuild/val/commit/be32261af19db8018bc37b180d903416018c0b79), [`5d14612`](https://github.com/valbuild/val/commit/5d14612f612d657a37338136188f2b3c02b28fe7), [`da6794f`](https://github.com/valbuild/val/commit/da6794f3dbd77d49ccfe780b359bab1689ee1b11), [`1c8b7fd`](https://github.com/valbuild/val/commit/1c8b7fda1e84cd8bd32a03a85d2789598b98c3fb)]:
|
|
62
|
+
- @valbuild/server@0.122.0
|
|
63
|
+
- @valbuild/shared@0.122.0
|
|
64
|
+
- @valbuild/ui@0.122.0
|
|
65
|
+
- @valbuild/language-server@0.122.0
|
|
66
|
+
- @valbuild/react@0.122.0
|
|
67
|
+
|
|
3
68
|
## 0.121.0
|
|
4
69
|
|
|
5
70
|
### Minor Changes
|
|
@@ -3,7 +3,7 @@ import { _ as _slicedToArray } from './slicedToArray-aa291011.esm.js';
|
|
|
3
3
|
import { VERSION, VAL_APP_PATH, VAL_APP_ID } from '@valbuild/ui';
|
|
4
4
|
import Script from 'next/script';
|
|
5
5
|
import { useState, useRef, useEffect } from 'react';
|
|
6
|
-
import { u as useConfigStorageSave, v as valPrefixedClass, c as cn, a as canvasDarkBg, b as canvasLightBg } from './fallbackColors-
|
|
6
|
+
import { u as useConfigStorageSave, v as valPrefixedClass, c as cn, a as canvasDarkBg, b as canvasLightBg } from './fallbackColors-77aeedf8.esm.js';
|
|
7
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import './unsupportedIterableToArray-5baabfdc.esm.js';
|
|
9
9
|
import '@valbuild/shared/internal';
|
|
@@ -7,7 +7,7 @@ var slicedToArray = require('./slicedToArray-ce613de6.cjs.prod.js');
|
|
|
7
7
|
var ui = require('@valbuild/ui');
|
|
8
8
|
var Script = require('next/script');
|
|
9
9
|
var React = require('react');
|
|
10
|
-
var fallbackColors = require('./fallbackColors-
|
|
10
|
+
var fallbackColors = require('./fallbackColors-8842243c.cjs.prod.js');
|
|
11
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
12
12
|
require('./unsupportedIterableToArray-0d2087a2.cjs.prod.js');
|
|
13
13
|
require('@valbuild/shared/internal');
|
|
@@ -7,7 +7,7 @@ var slicedToArray = require('./slicedToArray-44036a76.cjs.dev.js');
|
|
|
7
7
|
var ui = require('@valbuild/ui');
|
|
8
8
|
var Script = require('next/script');
|
|
9
9
|
var React = require('react');
|
|
10
|
-
var fallbackColors = require('./fallbackColors-
|
|
10
|
+
var fallbackColors = require('./fallbackColors-a491e700.cjs.dev.js');
|
|
11
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
12
12
|
require('./unsupportedIterableToArray-c8ab77c9.cjs.dev.js');
|
|
13
13
|
require('@valbuild/shared/internal');
|
|
@@ -13,7 +13,7 @@ var React = require('react');
|
|
|
13
13
|
var ValOverlayContext = require('./ValOverlayContext-5bd7628b.cjs.dev.js');
|
|
14
14
|
var stega = require('@valbuild/react/stega');
|
|
15
15
|
var internal = require('@valbuild/shared/internal');
|
|
16
|
-
var fallbackColors = require('./fallbackColors-
|
|
16
|
+
var fallbackColors = require('./fallbackColors-a491e700.cjs.dev.js');
|
|
17
17
|
var createForOfIteratorHelper = require('./createForOfIteratorHelper-0445603c.cjs.dev.js');
|
|
18
18
|
var ValCanvasBridge = require('./ValCanvasBridge-9d148bdd.cjs.dev.js');
|
|
19
19
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -9,7 +9,7 @@ import React, { useEffect } from 'react';
|
|
|
9
9
|
import { ValExternalStore, ValOverlayProvider } from './ValOverlayContext-e42a2e14.esm.js';
|
|
10
10
|
import { SET_AUTO_TAG_JSX_ENABLED } from '@valbuild/react/stega';
|
|
11
11
|
import { VAL_THEME_SESSION_STORAGE_KEY, createValClient, isValCanvasFrame } from '@valbuild/shared/internal';
|
|
12
|
-
import { p as prefixStyles, u as useConfigStorageSave, f as floatDarkBg, d as floatLightBg, v as valPrefixedClass, c as cn } from './fallbackColors-
|
|
12
|
+
import { p as prefixStyles, u as useConfigStorageSave, f as floatDarkBg, d as floatLightBg, v as valPrefixedClass, c as cn } from './fallbackColors-77aeedf8.esm.js';
|
|
13
13
|
import { _ as _createForOfIteratorHelper } from './createForOfIteratorHelper-5758a730.esm.js';
|
|
14
14
|
import { ValCanvasBridge } from './ValCanvasBridge-d9948526.esm.js';
|
|
15
15
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -13,7 +13,7 @@ var React = require('react');
|
|
|
13
13
|
var ValOverlayContext = require('./ValOverlayContext-d690744f.cjs.prod.js');
|
|
14
14
|
var stega = require('@valbuild/react/stega');
|
|
15
15
|
var internal = require('@valbuild/shared/internal');
|
|
16
|
-
var fallbackColors = require('./fallbackColors-
|
|
16
|
+
var fallbackColors = require('./fallbackColors-8842243c.cjs.prod.js');
|
|
17
17
|
var createForOfIteratorHelper = require('./createForOfIteratorHelper-d4afcad8.cjs.prod.js');
|
|
18
18
|
var ValCanvasBridge = require('./ValCanvasBridge-e62125f8.cjs.prod.js');
|
|
19
19
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -52,11 +52,11 @@ export declare function initValMcp(valModules: ValModules, config: ValConfig, op
|
|
|
52
52
|
/**
|
|
53
53
|
* Where to authorize, and what audience to expect.
|
|
54
54
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* needs a verified access token
|
|
59
|
-
* refused rather than ignored
|
|
55
|
+
* Required for proxy mode, and only omittable in local filesystem mode —
|
|
56
|
+
* where there is no authorization server to talk to and no backend to
|
|
57
|
+
* authenticate to, so local development stays a one-liner. Provide it and
|
|
58
|
+
* every call needs a verified access token, including in fs mode, where a
|
|
59
|
+
* token is refused rather than ignored: a host that thinks it is
|
|
60
60
|
* authenticating should never silently get unauthenticated local access.
|
|
61
61
|
*/
|
|
62
62
|
oauth?: ValOAuthConfig;
|
|
@@ -48,11 +48,11 @@ var cn = function cn(className) {
|
|
|
48
48
|
/** `--bg-canvas`, dark. The studio's own background. */
|
|
49
49
|
var canvasDarkBg = "#08080a";
|
|
50
50
|
/** `--bg-canvas`, light. */
|
|
51
|
-
var canvasLightBg = "#
|
|
51
|
+
var canvasLightBg = "#f4f4f5";
|
|
52
52
|
|
|
53
53
|
/** `--bg-float`, dark. Val's chrome, floating over the customer's page. */
|
|
54
54
|
var floatDarkBg = "#131316";
|
|
55
55
|
/** `--bg-float`, light. */
|
|
56
|
-
var floatLightBg = "#
|
|
56
|
+
var floatLightBg = "#fcfcfc";
|
|
57
57
|
|
|
58
58
|
export { canvasDarkBg as a, canvasLightBg as b, cn as c, floatLightBg as d, floatDarkBg as f, prefixStyles as p, useConfigStorageSave as u, valPrefixedClass as v };
|
|
@@ -54,12 +54,12 @@ var cn = function cn(className) {
|
|
|
54
54
|
/** `--bg-canvas`, dark. The studio's own background. */
|
|
55
55
|
var canvasDarkBg = "#08080a";
|
|
56
56
|
/** `--bg-canvas`, light. */
|
|
57
|
-
var canvasLightBg = "#
|
|
57
|
+
var canvasLightBg = "#f4f4f5";
|
|
58
58
|
|
|
59
59
|
/** `--bg-float`, dark. Val's chrome, floating over the customer's page. */
|
|
60
60
|
var floatDarkBg = "#131316";
|
|
61
61
|
/** `--bg-float`, light. */
|
|
62
|
-
var floatLightBg = "#
|
|
62
|
+
var floatLightBg = "#fcfcfc";
|
|
63
63
|
|
|
64
64
|
exports.canvasDarkBg = canvasDarkBg;
|
|
65
65
|
exports.canvasLightBg = canvasLightBg;
|
|
@@ -54,12 +54,12 @@ var cn = function cn(className) {
|
|
|
54
54
|
/** `--bg-canvas`, dark. The studio's own background. */
|
|
55
55
|
var canvasDarkBg = "#08080a";
|
|
56
56
|
/** `--bg-canvas`, light. */
|
|
57
|
-
var canvasLightBg = "#
|
|
57
|
+
var canvasLightBg = "#f4f4f5";
|
|
58
58
|
|
|
59
59
|
/** `--bg-float`, dark. Val's chrome, floating over the customer's page. */
|
|
60
60
|
var floatDarkBg = "#131316";
|
|
61
61
|
/** `--bg-float`, light. */
|
|
62
|
-
var floatLightBg = "#
|
|
62
|
+
var floatLightBg = "#fcfcfc";
|
|
63
63
|
|
|
64
64
|
exports.canvasDarkBg = canvasDarkBg;
|
|
65
65
|
exports.canvasLightBg = canvasLightBg;
|
|
@@ -7,10 +7,10 @@ var objectSpread2 = require('./objectSpread2-58024783.cjs.dev.js');
|
|
|
7
7
|
var core = require('@valbuild/core');
|
|
8
8
|
var stega = require('@valbuild/react/stega');
|
|
9
9
|
var internal = require('@valbuild/react/internal');
|
|
10
|
-
var ValNextProvider = require('./ValNextProvider-
|
|
10
|
+
var ValNextProvider = require('./ValNextProvider-016a494b.cjs.dev.js');
|
|
11
11
|
var NextImage = require('next/image');
|
|
12
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
13
|
-
var ValApp = require('./ValApp-
|
|
13
|
+
var ValApp = require('./ValApp-2bdb460a.cjs.dev.js');
|
|
14
14
|
var ValModulesClient = require('./ValModulesClient-4ecabf99.cjs.dev.js');
|
|
15
15
|
var createForOfIteratorHelper = require('./createForOfIteratorHelper-0445603c.cjs.dev.js');
|
|
16
16
|
require('./defineProperty-f90345d7.cjs.dev.js');
|
|
@@ -7,10 +7,10 @@ var objectSpread2 = require('./objectSpread2-13f847a9.cjs.prod.js');
|
|
|
7
7
|
var core = require('@valbuild/core');
|
|
8
8
|
var stega = require('@valbuild/react/stega');
|
|
9
9
|
var internal = require('@valbuild/react/internal');
|
|
10
|
-
var ValNextProvider = require('./ValNextProvider-
|
|
10
|
+
var ValNextProvider = require('./ValNextProvider-72d3561b.cjs.prod.js');
|
|
11
11
|
var NextImage = require('next/image');
|
|
12
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
13
|
-
var ValApp = require('./ValApp-
|
|
13
|
+
var ValApp = require('./ValApp-17eb6e93.cjs.prod.js');
|
|
14
14
|
var ValModulesClient = require('./ValModulesClient-10c0721c.cjs.prod.js');
|
|
15
15
|
var createForOfIteratorHelper = require('./createForOfIteratorHelper-d4afcad8.cjs.prod.js');
|
|
16
16
|
require('./defineProperty-8951f469.cjs.prod.js');
|
|
@@ -6,10 +6,10 @@ export { core as expr };
|
|
|
6
6
|
export { GenericSelector, Schema, VAL_EXTENSION, derefPatch, modules } from '@valbuild/core';
|
|
7
7
|
import { stegaEncode, stegaDecodeStrings, attrs, raw, autoTagJSX } from '@valbuild/react/stega';
|
|
8
8
|
export { ValRichText } from '@valbuild/react/internal';
|
|
9
|
-
import { ValNextProvider } from './ValNextProvider-
|
|
9
|
+
import { ValNextProvider } from './ValNextProvider-32156acd.esm.js';
|
|
10
10
|
import NextImage from 'next/image';
|
|
11
11
|
import { jsx } from 'react/jsx-runtime';
|
|
12
|
-
export { ValApp } from './ValApp-
|
|
12
|
+
export { ValApp } from './ValApp-074c8289.esm.js';
|
|
13
13
|
export { ValModulesClient, useRegisterValModules } from './ValModulesClient-0dd601a1.esm.js';
|
|
14
14
|
import { _ as _createForOfIteratorHelper } from './createForOfIteratorHelper-5758a730.esm.js';
|
|
15
15
|
import './defineProperty-cca5affa.esm.js';
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"next",
|
|
13
13
|
"react"
|
|
14
14
|
],
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.122.0",
|
|
16
16
|
"main": "dist/valbuild-next.cjs.js",
|
|
17
17
|
"module": "dist/valbuild-next.esm.js",
|
|
18
18
|
"exports": {
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"client-only": "^0.0.1",
|
|
49
49
|
"server-only": "^0.0.1",
|
|
50
|
-
"@valbuild/react": "0.121.0",
|
|
51
|
-
"@valbuild/shared": "0.121.0",
|
|
52
|
-
"@valbuild/server": "0.121.0",
|
|
53
|
-
"@valbuild/ui": "0.121.0",
|
|
54
50
|
"@valbuild/core": "0.121.0",
|
|
55
|
-
"@valbuild/
|
|
51
|
+
"@valbuild/react": "0.122.0",
|
|
52
|
+
"@valbuild/server": "0.122.0",
|
|
53
|
+
"@valbuild/shared": "0.122.0",
|
|
54
|
+
"@valbuild/language-server": "0.122.0",
|
|
55
|
+
"@valbuild/ui": "0.122.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@testing-library/react": "^16.3.3",
|
|
@@ -924,7 +924,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
924
924
|
},
|
|
925
925
|
valMcpAuthorize: function valMcpAuthorize(request) {
|
|
926
926
|
return version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee3() {
|
|
927
|
-
var setup, refusal, sessionId, verified, status,
|
|
927
|
+
var setup, refusal, sessionId, verified, status, _t;
|
|
928
928
|
return version._regenerator().w(function (_context3) {
|
|
929
929
|
while (1) switch (_context3.p = _context3.n) {
|
|
930
930
|
case 0:
|
|
@@ -967,20 +967,51 @@ function initValMcp(valModules, config, opts) {
|
|
|
967
967
|
response: refusal
|
|
968
968
|
});
|
|
969
969
|
case 5:
|
|
970
|
-
// Not the MCP session id, in
|
|
970
|
+
// Not the MCP session id, in any branch below. Val's patch `sessionId`
|
|
971
971
|
// names a Val AI session, and putting an unrelated id in it would claim a
|
|
972
972
|
// relationship that does not exist.
|
|
973
973
|
sessionId = null;
|
|
974
|
-
if (
|
|
974
|
+
if (oauth) {
|
|
975
975
|
_context3.n = 8;
|
|
976
976
|
break;
|
|
977
977
|
}
|
|
978
|
-
|
|
979
|
-
|
|
978
|
+
if (!(setup.mode !== "fs")) {
|
|
979
|
+
_context3.n = 6;
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
return _context3.a(2, {
|
|
983
|
+
status: "refused",
|
|
984
|
+
response: jsonResponse(500, {
|
|
985
|
+
error: "Val: this MCP endpoint has no `oauth` config, and this project is configured to talk to the Val content backend. Pass `oauth` to `initValMcp` with the authorization server's URL and this endpoint's own URL, so callers authorize as themselves."
|
|
986
|
+
})
|
|
987
|
+
});
|
|
980
988
|
case 6:
|
|
989
|
+
if (!(readBearerToken(request) !== null)) {
|
|
990
|
+
_context3.n = 7;
|
|
991
|
+
break;
|
|
992
|
+
}
|
|
993
|
+
return _context3.a(2, {
|
|
994
|
+
status: "refused",
|
|
995
|
+
response: jsonResponse(400, {
|
|
996
|
+
error: "Val: this project is running in local filesystem mode, where there is nothing to authenticate against — the tools read and write this working tree directly. Remove the credential from this MCP client's configuration: a token sent here is checked by nothing."
|
|
997
|
+
})
|
|
998
|
+
});
|
|
999
|
+
case 7:
|
|
1000
|
+
return _context3.a(2, {
|
|
1001
|
+
status: "ok",
|
|
1002
|
+
tools: setup.tools,
|
|
1003
|
+
ctx: {
|
|
1004
|
+
auth: null,
|
|
1005
|
+
sessionId: sessionId
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
case 8:
|
|
1009
|
+
_context3.n = 9;
|
|
1010
|
+
return verifyValAccessToken(request, oauth);
|
|
1011
|
+
case 9:
|
|
981
1012
|
verified = _context3.v;
|
|
982
1013
|
if (!(verified.status === "refused")) {
|
|
983
|
-
_context3.n =
|
|
1014
|
+
_context3.n = 10;
|
|
984
1015
|
break;
|
|
985
1016
|
}
|
|
986
1017
|
// 401 for a missing or bad token, 403 once the token is good but does
|
|
@@ -1003,7 +1034,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
1003
1034
|
}
|
|
1004
1035
|
})
|
|
1005
1036
|
});
|
|
1006
|
-
case
|
|
1037
|
+
case 10:
|
|
1007
1038
|
return _context3.a(2, {
|
|
1008
1039
|
status: "ok",
|
|
1009
1040
|
tools: setup.tools,
|
|
@@ -1012,23 +1043,6 @@ function initValMcp(valModules, config, opts) {
|
|
|
1012
1043
|
sessionId: sessionId
|
|
1013
1044
|
}
|
|
1014
1045
|
});
|
|
1015
|
-
case 8:
|
|
1016
|
-
pat = readBearerToken(request);
|
|
1017
|
-
return _context3.a(2, {
|
|
1018
|
-
status: "ok",
|
|
1019
|
-
tools: setup.tools,
|
|
1020
|
-
ctx: {
|
|
1021
|
-
// Passed through unverified, deliberately: without an `oauth` config
|
|
1022
|
-
// this app has no key to check anything against, so it is not the
|
|
1023
|
-
// authority on what the token may do and the registry sends it to the
|
|
1024
|
-
// backend that is. See `docs/plans/mcp.md` D.2.
|
|
1025
|
-
auth: pat === null ? null : {
|
|
1026
|
-
type: "pat",
|
|
1027
|
-
pat: pat
|
|
1028
|
-
},
|
|
1029
|
-
sessionId: sessionId
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1032
1046
|
}
|
|
1033
1047
|
}, _callee3, null, [[0, 2]]);
|
|
1034
1048
|
}))();
|
|
@@ -1046,7 +1060,8 @@ function initValMcp(valModules, config, opts) {
|
|
|
1046
1060
|
* that is unauthenticated write access to the site's content for anyone who
|
|
1047
1061
|
* can reach the port. There is no configuration that makes it safe, so there
|
|
1048
1062
|
* is no flag to turn this off — a project that wants MCP in production wants
|
|
1049
|
-
* proxy mode, where every call carries
|
|
1063
|
+
* proxy mode with an `oauth` config, where every call carries an access
|
|
1064
|
+
* token this app verified itself.
|
|
1050
1065
|
*
|
|
1051
1066
|
* 2. **A browser driving the local server.** A page on any origin can `fetch`
|
|
1052
1067
|
* `http://localhost:3000/api/mcp` while a developer has the app running, and
|
|
@@ -1103,9 +1118,9 @@ var LOOPBACK_HOSTNAMES = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
|
1103
1118
|
*
|
|
1104
1119
|
* The cost is that behind a proxy that rewrites `Host`, a *browser* request
|
|
1105
1120
|
* whose `Origin` is the public name no longer matches. That is acceptable: such
|
|
1106
|
-
* a request carries no
|
|
1107
|
-
*
|
|
1108
|
-
*
|
|
1121
|
+
* a request carries no access token, so proxy mode refuses it anyway, and a
|
|
1122
|
+
* non-browser MCP client sends no `Origin` and never reaches the comparison.
|
|
1123
|
+
* Trusting the forwarded header would need an explicit trusted-proxy
|
|
1109
1124
|
* configuration, which is a bigger thing than this needs.
|
|
1110
1125
|
*/
|
|
1111
1126
|
function requestHost(request) {
|
|
@@ -924,7 +924,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
924
924
|
},
|
|
925
925
|
valMcpAuthorize: function valMcpAuthorize(request) {
|
|
926
926
|
return version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee3() {
|
|
927
|
-
var setup, refusal, sessionId, verified, status,
|
|
927
|
+
var setup, refusal, sessionId, verified, status, _t;
|
|
928
928
|
return version._regenerator().w(function (_context3) {
|
|
929
929
|
while (1) switch (_context3.p = _context3.n) {
|
|
930
930
|
case 0:
|
|
@@ -967,20 +967,51 @@ function initValMcp(valModules, config, opts) {
|
|
|
967
967
|
response: refusal
|
|
968
968
|
});
|
|
969
969
|
case 5:
|
|
970
|
-
// Not the MCP session id, in
|
|
970
|
+
// Not the MCP session id, in any branch below. Val's patch `sessionId`
|
|
971
971
|
// names a Val AI session, and putting an unrelated id in it would claim a
|
|
972
972
|
// relationship that does not exist.
|
|
973
973
|
sessionId = null;
|
|
974
|
-
if (
|
|
974
|
+
if (oauth) {
|
|
975
975
|
_context3.n = 8;
|
|
976
976
|
break;
|
|
977
977
|
}
|
|
978
|
-
|
|
979
|
-
|
|
978
|
+
if (!(setup.mode !== "fs")) {
|
|
979
|
+
_context3.n = 6;
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
return _context3.a(2, {
|
|
983
|
+
status: "refused",
|
|
984
|
+
response: jsonResponse(500, {
|
|
985
|
+
error: "Val: this MCP endpoint has no `oauth` config, and this project is configured to talk to the Val content backend. Pass `oauth` to `initValMcp` with the authorization server's URL and this endpoint's own URL, so callers authorize as themselves."
|
|
986
|
+
})
|
|
987
|
+
});
|
|
980
988
|
case 6:
|
|
989
|
+
if (!(readBearerToken(request) !== null)) {
|
|
990
|
+
_context3.n = 7;
|
|
991
|
+
break;
|
|
992
|
+
}
|
|
993
|
+
return _context3.a(2, {
|
|
994
|
+
status: "refused",
|
|
995
|
+
response: jsonResponse(400, {
|
|
996
|
+
error: "Val: this project is running in local filesystem mode, where there is nothing to authenticate against — the tools read and write this working tree directly. Remove the credential from this MCP client's configuration: a token sent here is checked by nothing."
|
|
997
|
+
})
|
|
998
|
+
});
|
|
999
|
+
case 7:
|
|
1000
|
+
return _context3.a(2, {
|
|
1001
|
+
status: "ok",
|
|
1002
|
+
tools: setup.tools,
|
|
1003
|
+
ctx: {
|
|
1004
|
+
auth: null,
|
|
1005
|
+
sessionId: sessionId
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
case 8:
|
|
1009
|
+
_context3.n = 9;
|
|
1010
|
+
return verifyValAccessToken(request, oauth);
|
|
1011
|
+
case 9:
|
|
981
1012
|
verified = _context3.v;
|
|
982
1013
|
if (!(verified.status === "refused")) {
|
|
983
|
-
_context3.n =
|
|
1014
|
+
_context3.n = 10;
|
|
984
1015
|
break;
|
|
985
1016
|
}
|
|
986
1017
|
// 401 for a missing or bad token, 403 once the token is good but does
|
|
@@ -1003,7 +1034,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
1003
1034
|
}
|
|
1004
1035
|
})
|
|
1005
1036
|
});
|
|
1006
|
-
case
|
|
1037
|
+
case 10:
|
|
1007
1038
|
return _context3.a(2, {
|
|
1008
1039
|
status: "ok",
|
|
1009
1040
|
tools: setup.tools,
|
|
@@ -1012,23 +1043,6 @@ function initValMcp(valModules, config, opts) {
|
|
|
1012
1043
|
sessionId: sessionId
|
|
1013
1044
|
}
|
|
1014
1045
|
});
|
|
1015
|
-
case 8:
|
|
1016
|
-
pat = readBearerToken(request);
|
|
1017
|
-
return _context3.a(2, {
|
|
1018
|
-
status: "ok",
|
|
1019
|
-
tools: setup.tools,
|
|
1020
|
-
ctx: {
|
|
1021
|
-
// Passed through unverified, deliberately: without an `oauth` config
|
|
1022
|
-
// this app has no key to check anything against, so it is not the
|
|
1023
|
-
// authority on what the token may do and the registry sends it to the
|
|
1024
|
-
// backend that is. See `docs/plans/mcp.md` D.2.
|
|
1025
|
-
auth: pat === null ? null : {
|
|
1026
|
-
type: "pat",
|
|
1027
|
-
pat: pat
|
|
1028
|
-
},
|
|
1029
|
-
sessionId: sessionId
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1032
1046
|
}
|
|
1033
1047
|
}, _callee3, null, [[0, 2]]);
|
|
1034
1048
|
}))();
|
|
@@ -1046,7 +1060,8 @@ function initValMcp(valModules, config, opts) {
|
|
|
1046
1060
|
* that is unauthenticated write access to the site's content for anyone who
|
|
1047
1061
|
* can reach the port. There is no configuration that makes it safe, so there
|
|
1048
1062
|
* is no flag to turn this off — a project that wants MCP in production wants
|
|
1049
|
-
* proxy mode, where every call carries
|
|
1063
|
+
* proxy mode with an `oauth` config, where every call carries an access
|
|
1064
|
+
* token this app verified itself.
|
|
1050
1065
|
*
|
|
1051
1066
|
* 2. **A browser driving the local server.** A page on any origin can `fetch`
|
|
1052
1067
|
* `http://localhost:3000/api/mcp` while a developer has the app running, and
|
|
@@ -1103,9 +1118,9 @@ var LOOPBACK_HOSTNAMES = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
|
1103
1118
|
*
|
|
1104
1119
|
* The cost is that behind a proxy that rewrites `Host`, a *browser* request
|
|
1105
1120
|
* whose `Origin` is the public name no longer matches. That is acceptable: such
|
|
1106
|
-
* a request carries no
|
|
1107
|
-
*
|
|
1108
|
-
*
|
|
1121
|
+
* a request carries no access token, so proxy mode refuses it anyway, and a
|
|
1122
|
+
* non-browser MCP client sends no `Origin` and never reaches the comparison.
|
|
1123
|
+
* Trusting the forwarded header would need an explicit trusted-proxy
|
|
1109
1124
|
* configuration, which is a bigger thing than this needs.
|
|
1110
1125
|
*/
|
|
1111
1126
|
function requestHost(request) {
|
|
@@ -920,7 +920,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
920
920
|
},
|
|
921
921
|
valMcpAuthorize: function valMcpAuthorize(request) {
|
|
922
922
|
return _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
923
|
-
var setup, refusal, sessionId, verified, status,
|
|
923
|
+
var setup, refusal, sessionId, verified, status, _t;
|
|
924
924
|
return _regenerator().w(function (_context3) {
|
|
925
925
|
while (1) switch (_context3.p = _context3.n) {
|
|
926
926
|
case 0:
|
|
@@ -963,20 +963,51 @@ function initValMcp(valModules, config, opts) {
|
|
|
963
963
|
response: refusal
|
|
964
964
|
});
|
|
965
965
|
case 5:
|
|
966
|
-
// Not the MCP session id, in
|
|
966
|
+
// Not the MCP session id, in any branch below. Val's patch `sessionId`
|
|
967
967
|
// names a Val AI session, and putting an unrelated id in it would claim a
|
|
968
968
|
// relationship that does not exist.
|
|
969
969
|
sessionId = null;
|
|
970
|
-
if (
|
|
970
|
+
if (oauth) {
|
|
971
971
|
_context3.n = 8;
|
|
972
972
|
break;
|
|
973
973
|
}
|
|
974
|
-
|
|
975
|
-
|
|
974
|
+
if (!(setup.mode !== "fs")) {
|
|
975
|
+
_context3.n = 6;
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
return _context3.a(2, {
|
|
979
|
+
status: "refused",
|
|
980
|
+
response: jsonResponse(500, {
|
|
981
|
+
error: "Val: this MCP endpoint has no `oauth` config, and this project is configured to talk to the Val content backend. Pass `oauth` to `initValMcp` with the authorization server's URL and this endpoint's own URL, so callers authorize as themselves."
|
|
982
|
+
})
|
|
983
|
+
});
|
|
976
984
|
case 6:
|
|
985
|
+
if (!(readBearerToken(request) !== null)) {
|
|
986
|
+
_context3.n = 7;
|
|
987
|
+
break;
|
|
988
|
+
}
|
|
989
|
+
return _context3.a(2, {
|
|
990
|
+
status: "refused",
|
|
991
|
+
response: jsonResponse(400, {
|
|
992
|
+
error: "Val: this project is running in local filesystem mode, where there is nothing to authenticate against — the tools read and write this working tree directly. Remove the credential from this MCP client's configuration: a token sent here is checked by nothing."
|
|
993
|
+
})
|
|
994
|
+
});
|
|
995
|
+
case 7:
|
|
996
|
+
return _context3.a(2, {
|
|
997
|
+
status: "ok",
|
|
998
|
+
tools: setup.tools,
|
|
999
|
+
ctx: {
|
|
1000
|
+
auth: null,
|
|
1001
|
+
sessionId: sessionId
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
case 8:
|
|
1005
|
+
_context3.n = 9;
|
|
1006
|
+
return verifyValAccessToken(request, oauth);
|
|
1007
|
+
case 9:
|
|
977
1008
|
verified = _context3.v;
|
|
978
1009
|
if (!(verified.status === "refused")) {
|
|
979
|
-
_context3.n =
|
|
1010
|
+
_context3.n = 10;
|
|
980
1011
|
break;
|
|
981
1012
|
}
|
|
982
1013
|
// 401 for a missing or bad token, 403 once the token is good but does
|
|
@@ -999,7 +1030,7 @@ function initValMcp(valModules, config, opts) {
|
|
|
999
1030
|
}
|
|
1000
1031
|
})
|
|
1001
1032
|
});
|
|
1002
|
-
case
|
|
1033
|
+
case 10:
|
|
1003
1034
|
return _context3.a(2, {
|
|
1004
1035
|
status: "ok",
|
|
1005
1036
|
tools: setup.tools,
|
|
@@ -1008,23 +1039,6 @@ function initValMcp(valModules, config, opts) {
|
|
|
1008
1039
|
sessionId: sessionId
|
|
1009
1040
|
}
|
|
1010
1041
|
});
|
|
1011
|
-
case 8:
|
|
1012
|
-
pat = readBearerToken(request);
|
|
1013
|
-
return _context3.a(2, {
|
|
1014
|
-
status: "ok",
|
|
1015
|
-
tools: setup.tools,
|
|
1016
|
-
ctx: {
|
|
1017
|
-
// Passed through unverified, deliberately: without an `oauth` config
|
|
1018
|
-
// this app has no key to check anything against, so it is not the
|
|
1019
|
-
// authority on what the token may do and the registry sends it to the
|
|
1020
|
-
// backend that is. See `docs/plans/mcp.md` D.2.
|
|
1021
|
-
auth: pat === null ? null : {
|
|
1022
|
-
type: "pat",
|
|
1023
|
-
pat: pat
|
|
1024
|
-
},
|
|
1025
|
-
sessionId: sessionId
|
|
1026
|
-
}
|
|
1027
|
-
});
|
|
1028
1042
|
}
|
|
1029
1043
|
}, _callee3, null, [[0, 2]]);
|
|
1030
1044
|
}))();
|
|
@@ -1042,7 +1056,8 @@ function initValMcp(valModules, config, opts) {
|
|
|
1042
1056
|
* that is unauthenticated write access to the site's content for anyone who
|
|
1043
1057
|
* can reach the port. There is no configuration that makes it safe, so there
|
|
1044
1058
|
* is no flag to turn this off — a project that wants MCP in production wants
|
|
1045
|
-
* proxy mode, where every call carries
|
|
1059
|
+
* proxy mode with an `oauth` config, where every call carries an access
|
|
1060
|
+
* token this app verified itself.
|
|
1046
1061
|
*
|
|
1047
1062
|
* 2. **A browser driving the local server.** A page on any origin can `fetch`
|
|
1048
1063
|
* `http://localhost:3000/api/mcp` while a developer has the app running, and
|
|
@@ -1099,9 +1114,9 @@ var LOOPBACK_HOSTNAMES = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
|
1099
1114
|
*
|
|
1100
1115
|
* The cost is that behind a proxy that rewrites `Host`, a *browser* request
|
|
1101
1116
|
* whose `Origin` is the public name no longer matches. That is acceptable: such
|
|
1102
|
-
* a request carries no
|
|
1103
|
-
*
|
|
1104
|
-
*
|
|
1117
|
+
* a request carries no access token, so proxy mode refuses it anyway, and a
|
|
1118
|
+
* non-browser MCP client sends no `Origin` and never reaches the comparison.
|
|
1119
|
+
* Trusting the forwarded header would need an explicit trusted-proxy
|
|
1105
1120
|
* configuration, which is a bigger thing than this needs.
|
|
1106
1121
|
*/
|
|
1107
1122
|
function requestHost(request) {
|