@valbuild/next 0.121.0 → 0.123.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/client/dist/valbuild-next-client.cjs.dev.js +3 -4
  3. package/client/dist/valbuild-next-client.cjs.prod.js +3 -4
  4. package/client/dist/valbuild-next-client.esm.js +1 -2
  5. package/dist/{ValApp-e17eb734.esm.js → ValApp-074c8289.esm.js} +1 -1
  6. package/dist/ValApp-17eb6e93.cjs.js +7 -0
  7. package/dist/{ValApp-90c4171d.cjs.prod.js → ValApp-17eb6e93.cjs.prod.js} +1 -1
  8. package/dist/{ValApp-c1c3ef55.cjs.dev.js → ValApp-2bdb460a.cjs.dev.js} +1 -1
  9. package/dist/{ValNextProvider-f206d2ea.cjs.dev.js → ValNextProvider-016a494b.cjs.dev.js} +1 -1
  10. package/dist/{ValNextProvider-588f2ff0.esm.js → ValNextProvider-32156acd.esm.js} +1 -1
  11. package/dist/ValNextProvider-72d3561b.cjs.js +7 -0
  12. package/dist/{ValNextProvider-bd3f89d3.cjs.prod.js → ValNextProvider-72d3561b.cjs.prod.js} +1 -1
  13. package/dist/declarations/src/server/index.d.ts +1 -1
  14. package/dist/declarations/src/server/initValMcp.d.ts +19 -54
  15. package/dist/{fallbackColors-5ead2c26.esm.js → fallbackColors-77aeedf8.esm.js} +2 -2
  16. package/dist/{fallbackColors-d4a5b0da.cjs.prod.js → fallbackColors-8842243c.cjs.prod.js} +2 -2
  17. package/dist/{fallbackColors-9a2ac53a.cjs.dev.js → fallbackColors-a491e700.cjs.dev.js} +2 -2
  18. package/dist/{routeFromVal-bd69625f.esm.js → routeFromVal-263eec96.esm.js} +11 -2
  19. package/dist/{routeFromVal-8032f5f7.cjs.prod.js → routeFromVal-8ac2f984.cjs.prod.js} +15 -5
  20. package/dist/{routeFromVal-7df20dfe.cjs.dev.js → routeFromVal-b48a454a.cjs.dev.js} +15 -5
  21. package/dist/valbuild-next.cjs.dev.js +2 -2
  22. package/dist/valbuild-next.cjs.prod.js +2 -2
  23. package/dist/valbuild-next.esm.js +2 -2
  24. package/package.json +7 -6
  25. package/rsc/dist/valbuild-next-rsc.cjs.dev.js +2 -3
  26. package/rsc/dist/valbuild-next-rsc.cjs.prod.js +2 -3
  27. package/rsc/dist/valbuild-next-rsc.esm.js +1 -2
  28. package/server/dist/valbuild-next-server.cjs.dev.js +14 -1014
  29. package/server/dist/valbuild-next-server.cjs.prod.js +14 -1014
  30. package/server/dist/valbuild-next-server.esm.js +15 -1015
  31. package/dist/ValApp-90c4171d.cjs.js +0 -7
  32. package/dist/ValNextProvider-bd3f89d3.cjs.js +0 -7
  33. package/dist/declarations/src/server/valAccessToken.d.ts +0 -93
  34. package/dist/declarations/src/server/valMcpMetadata.d.ts +0 -47
  35. package/dist/typeof-16428c61.cjs.prod.js +0 -13
  36. package/dist/typeof-a1531d8f.esm.js +0 -11
  37. package/dist/typeof-b568f48f.cjs.dev.js +0 -13
package/CHANGELOG.md CHANGED
@@ -1,5 +1,166 @@
1
1
  # @valbuild/next
2
2
 
3
+ ## 0.123.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#613](https://github.com/valbuild/val/pull/613) [`c5e7dfd`](https://github.com/valbuild/val/commit/c5e7dfd12aa1371195be642e1c2fb72b6f3e3ce2) Thanks [@freekh](https://github.com/freekh)! - Val's MCP endpoint moves to its own package, and can now upload images
8
+
9
+ Everything that serves Val's content tools over MCP — the tool registry, the
10
+ write path behind it, the request guards and the access-token verification —
11
+ now lives in **`@valbuild/mcp`** instead of being split between
12
+ `@valbuild/server` and `@valbuild/next`.
13
+
14
+ **Nothing changes for an app that already mounts it.** `initValMcp` is still
15
+ exported from `@valbuild/next/server` and behaves exactly as before; it is now a
16
+ ten-line binding over `@valbuild/mcp`, supplying the Next version that
17
+ `initHandlerOptions` asks for. A host that is not Next can call
18
+ `initValMcp` from `@valbuild/mcp` directly.
19
+
20
+ If you built your own host on `createValTools`, import it from `@valbuild/mcp`
21
+ rather than `@valbuild/server`; the tool types moved with it.
22
+
23
+ ## Image uploads
24
+
25
+ An agent can now add an image, with a new `upload_image` tool. It takes a path
26
+ to a file on the machine your app runs on, or the image inline as base64, and
27
+ puts it in an `s.image()` field or an `s.images()` gallery.
28
+
29
+ Uploads are converted **only where the Studio would convert them**: `encode` is
30
+ off unless the schema asks for it (`s.image({ encode: { type: "webp" } })`), and
31
+ when it does, which images are converted, how far they are scaled and when the
32
+ original wins are the same decisions the browser makes — the same code, now
33
+ shared. An upload to a schema without `encode` is stored exactly as it arrived,
34
+ whatever its size.
35
+
36
+ One thing the tool does that the Studio does not: it refuses an image the
37
+ schema's `accept` does not cover, checked on the bytes that would actually be
38
+ stored. The Studio does not need to — its file picker carries `accept` — and
39
+ validation reports a mismatch as server-repairable, so nothing downstream would
40
+ stop it. An agent has no picker. Note the ordering:
41
+ `s.image({ accept: "image/webp", encode: { type: "webp" } })` still takes a PNG,
42
+ because the conversion happens first and it is the result that is checked.
43
+
44
+ It is the one tool you construct yourself, because it needs an image library
45
+ and `sharp` ships a compiled binary per platform. Val does not put one in every
46
+ project that installs it, so you decide:
47
+
48
+ ```sh
49
+ npm install sharp
50
+ ```
51
+
52
+ ```ts
53
+ import sharp from "sharp";
54
+ import { createValImageTools } from "@valbuild/mcp";
55
+ import { sharpImageProcessor } from "@valbuild/mcp/sharp";
56
+
57
+ const { valMcpAuthorize, valMcpTools } = initValMcp(valModules, config, {
58
+ extraTools: createValImageTools(sharpImageProcessor(sharp)),
59
+ });
60
+ ```
61
+
62
+ Leave `extraTools` out and everything else works as before — the agent can read,
63
+ validate and edit content, it just cannot add an image. `sharp` is passed in
64
+ rather than imported, so you can supply another encoder: `ValImageProcessor` is
65
+ two functions, `read` and `encode`.
66
+
67
+ Remotely stored images work too — `s.image().remote()` and
68
+ `s.images({ remote: true })` — and they need nothing extra from the MCP client.
69
+ Adding one does not upload anything to Val's content host: the bytes go into the
70
+ patch store like any other unpublished change, and the push to
71
+ `remote.val.build` happens when you publish, exactly as it does for an image
72
+ added through the Studio. All the tool has to do first is ask the project which
73
+ bucket to name in the ref, and the credential for that is the one your app
74
+ already has — its API key when it has one, and in local development the
75
+ `val login` token in your project, the same one `val validate --fix` uses. If
76
+ you have not logged in, it says so and writes nothing.
77
+
78
+ ## `npm create @valbuild` asks
79
+
80
+ The starter template now ships the MCP endpoint, and `npm create @valbuild`
81
+ asks whether you want it — and, if you do, whether agents should be able to
82
+ upload images, saying that this adds `sharp`. Both default to yes, and both can
83
+ be answered up front for a scripted setup:
84
+
85
+ ```sh
86
+ pnpm create @valbuild my-app --mcp --no-image-uploads
87
+ ```
88
+
89
+ ### Patch Changes
90
+
91
+ - Updated dependencies [[`c5e7dfd`](https://github.com/valbuild/val/commit/c5e7dfd12aa1371195be642e1c2fb72b6f3e3ce2), [`53f670c`](https://github.com/valbuild/val/commit/53f670c0cf2d7a03a6d068c78b7874ce77652c2a)]:
92
+ - @valbuild/mcp@0.123.0
93
+ - @valbuild/server@0.123.0
94
+ - @valbuild/shared@0.123.0
95
+ - @valbuild/ui@0.123.0
96
+ - @valbuild/language-server@0.123.0
97
+ - @valbuild/react@0.123.0
98
+
99
+ ## 0.122.0
100
+
101
+ ### Minor Changes
102
+
103
+ - [#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`
104
+ config, or local filesystem mode.
105
+
106
+ Until now, an MCP endpoint with no `oauth` config accepted whatever bearer token
107
+ a caller presented and relayed it to the Val content backend unread. The
108
+ reasoning was that without an issuer the app has no key to check a token
109
+ against, so it should not pretend to be the authority on what that token may
110
+ do — and that much was right. The shape was not: a credential the app cannot
111
+ check is one it cannot refuse either, so "a deployed endpoint that authenticates
112
+ nobody" was a supported configuration, and an app could serve content-rewriting
113
+ tools without ever being told where its callers should authorize.
114
+
115
+ **If you run Val in proxy mode**, MCP now requires the `oauth` config that
116
+ shipped in `0.120.0`. Callers authorize as themselves against the Val
117
+ authorization server, this app verifies the token's signature, issuer, audience
118
+ and expiry itself, and patches carry the verified profile as their author:
119
+
120
+ ```ts
121
+ initValMcp(valModules, config, {
122
+ oauth: {
123
+ issuer: "https://admin.val.build",
124
+ resource: "https://your-app.com/api/mcp",
125
+ },
126
+ });
127
+ ```
128
+
129
+ Leave it out and the endpoint answers `500` naming the missing config, rather
130
+ than serving the request.
131
+
132
+ **If you run Val in local filesystem mode**, nothing changes. Local development
133
+ still needs no `oauth` config and no authorization server: there is no backend
134
+ to authenticate to, and patches are written with no author. A token presented
135
+ to such a project is still refused rather than ignored — the endpoint answers
136
+ `400` and says to take the credential out of the client's configuration, since
137
+ what it reached was a working tree with no permission check in front of it.
138
+
139
+ Two API changes if you built your own host on `createValTools`:
140
+
141
+ - `ValToolContext.auth` no longer has a `{ type: "pat", pat }` variant.
142
+ `{ type: "verified-profile", profileId, scopes }` is the only credential the
143
+ registry accepts, and `null` still means local filesystem mode.
144
+ - `createValOps` no longer takes an `auth` argument. `ValOpsHttp` still accepts
145
+ a personal access token directly — that is how `val debug` uses the token from
146
+ `val login` — but no server request builds one.
147
+
148
+ Proxy mode also stops keeping one data layer per credential. Each personal
149
+ access token needed its own `ValOpsHttp` to hold it, each of those cached the
150
+ project's evaluated modules, and the bounded cache that kept the memory in
151
+ check turned an eviction into a re-evaluation of every module on the next call.
152
+ Verified callers all share one instance, because they all reach the backend
153
+ under the app's own API key.
154
+
155
+ ### Patch Changes
156
+
157
+ - 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)]:
158
+ - @valbuild/server@0.122.0
159
+ - @valbuild/shared@0.122.0
160
+ - @valbuild/ui@0.122.0
161
+ - @valbuild/language-server@0.122.0
162
+ - @valbuild/react@0.122.0
163
+
3
164
  ## 0.121.0
4
165
 
5
166
  ### Minor Changes
@@ -3,12 +3,11 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  require('client-only');
6
- var _typeof = require('../../dist/typeof-b568f48f.cjs.dev.js');
6
+ var routeFromVal = require('../../dist/routeFromVal-b48a454a.cjs.dev.js');
7
7
  var core = require('@valbuild/core');
8
8
  var stega = require('@valbuild/react/stega');
9
9
  var React = require('react');
10
10
  var ValOverlayContext = require('../../dist/ValOverlayContext-5bd7628b.cjs.dev.js');
11
- var routeFromVal = require('../../dist/routeFromVal-7df20dfe.cjs.dev.js');
12
11
  require('../../dist/createForOfIteratorHelper-0445603c.cjs.dev.js');
13
12
  require('../../dist/unsupportedIterableToArray-c8ab77c9.cjs.dev.js');
14
13
  require('../../dist/objectSpread2-58024783.cjs.dev.js');
@@ -119,7 +118,7 @@ function useDraftModuleSource(moduleFilePath) {
119
118
  * bundled content is used only when there is no draft view.
120
119
  */
121
120
  function draftJsonEntry(draftSource, key) {
122
- if (draftSource === undefined || draftSource === null || _typeof._typeof(draftSource) !== "object" || Array.isArray(draftSource)) {
121
+ if (draftSource === undefined || draftSource === null || routeFromVal._typeof(draftSource) !== "object" || Array.isArray(draftSource)) {
123
122
  return {
124
123
  status: "unavailable"
125
124
  };
@@ -191,7 +190,7 @@ function useValKeyStega(selector, key) {
191
190
  function readCommittedJsonEntry(selector, key) {
192
191
  var _Internal$getValPath;
193
192
  var source = selector && core.Internal.getSource(selector);
194
- var marker = source && _typeof._typeof(source) === "object" ? source[key] : undefined;
193
+ var marker = source && routeFromVal._typeof(source) === "object" ? source[key] : undefined;
195
194
  if (!core.Internal.isJson(marker)) {
196
195
  return undefined;
197
196
  }
@@ -3,12 +3,11 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  require('client-only');
6
- var _typeof = require('../../dist/typeof-16428c61.cjs.prod.js');
6
+ var routeFromVal = require('../../dist/routeFromVal-8ac2f984.cjs.prod.js');
7
7
  var core = require('@valbuild/core');
8
8
  var stega = require('@valbuild/react/stega');
9
9
  var React = require('react');
10
10
  var ValOverlayContext = require('../../dist/ValOverlayContext-d690744f.cjs.prod.js');
11
- var routeFromVal = require('../../dist/routeFromVal-8032f5f7.cjs.prod.js');
12
11
  require('../../dist/createForOfIteratorHelper-d4afcad8.cjs.prod.js');
13
12
  require('../../dist/unsupportedIterableToArray-0d2087a2.cjs.prod.js');
14
13
  require('../../dist/objectSpread2-13f847a9.cjs.prod.js');
@@ -119,7 +118,7 @@ function useDraftModuleSource(moduleFilePath) {
119
118
  * bundled content is used only when there is no draft view.
120
119
  */
121
120
  function draftJsonEntry(draftSource, key) {
122
- if (draftSource === undefined || draftSource === null || _typeof._typeof(draftSource) !== "object" || Array.isArray(draftSource)) {
121
+ if (draftSource === undefined || draftSource === null || routeFromVal._typeof(draftSource) !== "object" || Array.isArray(draftSource)) {
123
122
  return {
124
123
  status: "unavailable"
125
124
  };
@@ -191,7 +190,7 @@ function useValKeyStega(selector, key) {
191
190
  function readCommittedJsonEntry(selector, key) {
192
191
  var _Internal$getValPath;
193
192
  var source = selector && core.Internal.getSource(selector);
194
- var marker = source && _typeof._typeof(source) === "object" ? source[key] : undefined;
193
+ var marker = source && routeFromVal._typeof(source) === "object" ? source[key] : undefined;
195
194
  if (!core.Internal.isJson(marker)) {
196
195
  return undefined;
197
196
  }
@@ -1,10 +1,9 @@
1
1
  import 'client-only';
2
- import { _ as _typeof } from '../../dist/typeof-a1531d8f.esm.js';
2
+ import { g as getJsonEntryStegaRoot, _ as _typeof, a as isJsonValuesRecordSchema, b as getValRouteUrlFromVal, i as initValRouteFromVal } from '../../dist/routeFromVal-263eec96.esm.js';
3
3
  import { Internal } from '@valbuild/core';
4
4
  import { getModuleIds, stegaEncode } from '@valbuild/react/stega';
5
5
  import React from 'react';
6
6
  import { useValOverlayContext } from '../../dist/ValOverlayContext-e42a2e14.esm.js';
7
- import { g as getJsonEntryStegaRoot, a as isJsonValuesRecordSchema, b as getValRouteUrlFromVal, i as initValRouteFromVal } from '../../dist/routeFromVal-bd69625f.esm.js';
8
7
  import '../../dist/createForOfIteratorHelper-5758a730.esm.js';
9
8
  import '../../dist/unsupportedIterableToArray-5baabfdc.esm.js';
10
9
  import '../../dist/objectSpread2-60d1bd93.esm.js';
@@ -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-5ead2c26.esm.js';
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';
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === "production") {
4
+ module.exports = require("./ValApp-17eb6e93.cjs.prod.js");
5
+ } else {
6
+ module.exports = require("./ValApp-17eb6e93.cjs.dev.js");
7
+ }
@@ -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-d4a5b0da.cjs.prod.js');
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-9a2ac53a.cjs.dev.js');
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-9a2ac53a.cjs.dev.js');
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-5ead2c26.esm.js';
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';
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === "production") {
4
+ module.exports = require("./ValNextProvider-72d3561b.cjs.prod.js");
5
+ } else {
6
+ module.exports = require("./ValNextProvider-72d3561b.cjs.dev.js");
7
+ }
@@ -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-d4a5b0da.cjs.prod.js');
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');
@@ -1,4 +1,4 @@
1
1
  import "server-only";
2
2
  export { initValServer } from "./initValServer.js";
3
3
  export { initValMcp } from "./initValMcp.js";
4
- export type { ValMcp, ValMcpAuthorizationResult } from "./initValMcp.js";
4
+ export type { ValMcp, ValMcpAuthorizationResult, ValMcpMetadataHandlers, ValOAuthConfig, ValToolImpl, } from "@valbuild/mcp";
@@ -1,63 +1,28 @@
1
- import { ValConfig, ValModules } from "@valbuild/core";
2
- import { type ValToolContext, type ValTools } from "@valbuild/server";
3
- import { type ValOAuthConfig } from "./valAccessToken.js";
4
- import { type ValMcpMetadataHandlers } from "./valMcpMetadata.js";
1
+ import type { ValConfig, ValModules } from "@valbuild/core";
2
+ import { type ValMcp, type ValToolImpl, type ValOAuthConfig } from "@valbuild/mcp";
5
3
  /**
6
- * Val's tools over MCP, and the two checks that have to happen before a request
7
- * gets to them.
4
+ * Val's tools over MCP, bound to Next.
8
5
  *
9
- * Nothing here imports an MCP SDK. The app owns the transport — which SDK, which
10
- * route, which framework — and this owns the parts that must not be re-decided
11
- * per app: whether the request is allowed to reach the tools at all, and whose
12
- * credential it carries. `docs/plans/mcp.md` Part A has the reasoning; the short
13
- * version is that the SDK reorganised itself once already, and the security
14
- * checks should not move when it does again.
6
+ * The MCP endpoint itself — the tools, the request guards, the access-token
7
+ * verification — lives in `@valbuild/mcp`, which knows nothing about Next. All
8
+ * that is left here is the one thing this package can answer and that one
9
+ * cannot: which version of `@valbuild/next` is running, which
10
+ * `initHandlerOptions` insists on before it will build a proxy-mode config.
11
+ *
12
+ * Kept exported from `@valbuild/next/server` because that is where it has
13
+ * always been. New code can import `initValMcp` from `@valbuild/mcp` directly
14
+ * and pass `versions: { next }` itself; there is no difference in behaviour.
15
15
  */
16
- export type ValMcpAuthorizationResult = {
17
- status: "ok";
18
- tools: ValTools;
19
- ctx: ValToolContext;
20
- } | {
21
- status: "refused";
22
- response: Response;
23
- };
24
- export type ValMcp = {
25
- /**
26
- * Check a request and, if it is allowed, hand back the tools and the context
27
- * to call them with.
28
- *
29
- * Call this per request — both halves are per request. Refusing early is the
30
- * point: a refused request must not reach the protocol layer, let alone a
31
- * tool.
32
- */
33
- valMcpAuthorize: (request: Request | undefined) => Promise<ValMcpAuthorizationResult>;
34
- /**
35
- * The registry itself, for listing tools at startup.
36
- *
37
- * Listing needs no credential — it reads no content — so registering tools
38
- * with an MCP server can happen once rather than per request.
39
- */
40
- valMcpTools: () => Promise<ValTools>;
41
- /**
42
- * The RFC 9728 protected-resource document, for mounting at
43
- * `/.well-known/oauth-protected-resource`.
44
- *
45
- * `null` when no `oauth` config was given: a project that has not been told
46
- * where to authorize must not publish a document claiming it knows.
47
- */
48
- valMcpMetadata: ValMcpMetadataHandlers | null;
49
- };
50
16
  export declare function initValMcp(valModules: ValModules, config: ValConfig, opts?: {
51
17
  formatter?: (code: string, filePath: string) => string | Promise<string>;
52
18
  /**
53
- * Where to authorize, and what audience to expect.
54
- *
55
- * Omit it and nothing changes: the endpoint behaves exactly as it did
56
- * before OAuth existed, which keeps local development a one-liner and keeps
57
- * an app that has not been reconfigured working. Provide it and every call
58
- * needs a verified access token — including in fs mode, where a token is
59
- * refused rather than ignored, because a host that thinks it is
60
- * authenticating should never silently get unauthenticated local access.
19
+ * Where to authorize, and what audience to expect. Required for proxy
20
+ * mode; see `initValMcp` in `@valbuild/mcp` for what omitting it means.
61
21
  */
62
22
  oauth?: ValOAuthConfig;
23
+ /**
24
+ * Tools to serve alongside the built-in ones — the image tool arrives this
25
+ * way. See `createValImageTools` in `@valbuild/mcp`.
26
+ */
27
+ extraTools?: ValToolImpl[];
63
28
  }): ValMcp;
@@ -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 = "#fafafa";
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 = "#ffffff";
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 = "#fafafa";
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 = "#ffffff";
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 = "#fafafa";
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 = "#ffffff";
62
+ var floatLightBg = "#fcfcfc";
63
63
 
64
64
  exports.canvasDarkBg = canvasDarkBg;
65
65
  exports.canvasLightBg = canvasLightBg;
@@ -1,10 +1,19 @@
1
1
  import { _ as _createForOfIteratorHelper } from './createForOfIteratorHelper-5758a730.esm.js';
2
2
  import { _ as _objectSpread2 } from './objectSpread2-60d1bd93.esm.js';
3
3
  import { _ as _slicedToArray } from './slicedToArray-aa291011.esm.js';
4
- import { _ as _typeof } from './typeof-a1531d8f.esm.js';
5
4
  import { RecordSchema, Internal } from '@valbuild/core';
6
5
  import { getNextAppRouterSourceFolder, getPatternFromModuleFilePath, parseRoutePattern } from '@valbuild/shared/internal';
7
6
 
7
+ function _typeof(o) {
8
+ "@babel/helpers - typeof";
9
+
10
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
11
+ return typeof o;
12
+ } : function (o) {
13
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
14
+ }, _typeof(o);
15
+ }
16
+
8
17
  /**
9
18
  * True when the module's schema is a `.jsonValues()` record/router — i.e. each
10
19
  * entry value is a lazily-loaded `c.json(() => import(...))` marker. Used by the
@@ -184,4 +193,4 @@ val) {
184
193
  return actualRoute;
185
194
  }
186
195
 
187
- export { isJsonValuesRecordSchema as a, getValRouteUrlFromVal as b, getJsonEntryStegaRoot as g, initValRouteFromVal as i };
196
+ export { _typeof as _, isJsonValuesRecordSchema as a, getValRouteUrlFromVal as b, getJsonEntryStegaRoot as g, initValRouteFromVal as i };
@@ -3,10 +3,19 @@
3
3
  var createForOfIteratorHelper = require('./createForOfIteratorHelper-d4afcad8.cjs.prod.js');
4
4
  var objectSpread2 = require('./objectSpread2-13f847a9.cjs.prod.js');
5
5
  var slicedToArray = require('./slicedToArray-ce613de6.cjs.prod.js');
6
- var _typeof = require('./typeof-16428c61.cjs.prod.js');
7
6
  var core = require('@valbuild/core');
8
7
  var internal = require('@valbuild/shared/internal');
9
8
 
9
+ function _typeof(o) {
10
+ "@babel/helpers - typeof";
11
+
12
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
13
+ return typeof o;
14
+ } : function (o) {
15
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
16
+ }, _typeof(o);
17
+ }
18
+
10
19
  /**
11
20
  * True when the module's schema is a `.jsonValues()` record/router — i.e. each
12
21
  * entry value is a lazily-loaded `c.json(() => import(...))` marker. Used by the
@@ -61,8 +70,8 @@ val) {
61
70
  if (val === null) {
62
71
  return null;
63
72
  }
64
- if (_typeof._typeof(val) !== "object") {
65
- console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: expected type object, found ").concat(_typeof._typeof(val), " instead)."));
73
+ if (_typeof(val) !== "object") {
74
+ console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: expected type object, found ").concat(_typeof(val), " instead)."));
66
75
  return null;
67
76
  }
68
77
  if (Array.isArray(val)) {
@@ -81,7 +90,7 @@ val) {
81
90
  console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: router is not the Next.js App Router or External URL Page Router)."));
82
91
  return null;
83
92
  }
84
- if (_typeof._typeof(resolvedParams) !== "object") {
93
+ if (_typeof(resolvedParams) !== "object") {
85
94
  console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: params is not an object)."));
86
95
  return null;
87
96
  }
@@ -101,7 +110,7 @@ val) {
101
110
  var parsedPattern = internal.parseRoutePattern(pattern);
102
111
  var missingPatterns = [];
103
112
  var fullPathParts = [];
104
- var missingParamKeys = _typeof._typeof(resolvedParams) === "object" && resolvedParams !== null && !Array.isArray(resolvedParams) ? objectSpread2._objectSpread2({}, resolvedParams) : {};
113
+ var missingParamKeys = _typeof(resolvedParams) === "object" && resolvedParams !== null && !Array.isArray(resolvedParams) ? objectSpread2._objectSpread2({}, resolvedParams) : {};
105
114
  var _iterator = createForOfIteratorHelper._createForOfIteratorHelper(parsedPattern !== null && parsedPattern !== void 0 ? parsedPattern : []),
106
115
  _step;
107
116
  try {
@@ -186,6 +195,7 @@ val) {
186
195
  return actualRoute;
187
196
  }
188
197
 
198
+ exports._typeof = _typeof;
189
199
  exports.getJsonEntryStegaRoot = getJsonEntryStegaRoot;
190
200
  exports.getValRouteUrlFromVal = getValRouteUrlFromVal;
191
201
  exports.initValRouteFromVal = initValRouteFromVal;
@@ -3,10 +3,19 @@
3
3
  var createForOfIteratorHelper = require('./createForOfIteratorHelper-0445603c.cjs.dev.js');
4
4
  var objectSpread2 = require('./objectSpread2-58024783.cjs.dev.js');
5
5
  var slicedToArray = require('./slicedToArray-44036a76.cjs.dev.js');
6
- var _typeof = require('./typeof-b568f48f.cjs.dev.js');
7
6
  var core = require('@valbuild/core');
8
7
  var internal = require('@valbuild/shared/internal');
9
8
 
9
+ function _typeof(o) {
10
+ "@babel/helpers - typeof";
11
+
12
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
13
+ return typeof o;
14
+ } : function (o) {
15
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
16
+ }, _typeof(o);
17
+ }
18
+
10
19
  /**
11
20
  * True when the module's schema is a `.jsonValues()` record/router — i.e. each
12
21
  * entry value is a lazily-loaded `c.json(() => import(...))` marker. Used by the
@@ -61,8 +70,8 @@ val) {
61
70
  if (val === null) {
62
71
  return null;
63
72
  }
64
- if (_typeof._typeof(val) !== "object") {
65
- console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: expected type object, found ").concat(_typeof._typeof(val), " instead)."));
73
+ if (_typeof(val) !== "object") {
74
+ console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: expected type object, found ").concat(_typeof(val), " instead)."));
66
75
  return null;
67
76
  }
68
77
  if (Array.isArray(val)) {
@@ -81,7 +90,7 @@ val) {
81
90
  console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: router is not the Next.js App Router or External URL Page Router)."));
82
91
  return null;
83
92
  }
84
- if (_typeof._typeof(resolvedParams) !== "object") {
93
+ if (_typeof(resolvedParams) !== "object") {
85
94
  console.error("Val: ".concat(methodName, " must be used with a Val Module that is a s.record().router(...) (details: params is not an object)."));
86
95
  return null;
87
96
  }
@@ -101,7 +110,7 @@ val) {
101
110
  var parsedPattern = internal.parseRoutePattern(pattern);
102
111
  var missingPatterns = [];
103
112
  var fullPathParts = [];
104
- var missingParamKeys = _typeof._typeof(resolvedParams) === "object" && resolvedParams !== null && !Array.isArray(resolvedParams) ? objectSpread2._objectSpread2({}, resolvedParams) : {};
113
+ var missingParamKeys = _typeof(resolvedParams) === "object" && resolvedParams !== null && !Array.isArray(resolvedParams) ? objectSpread2._objectSpread2({}, resolvedParams) : {};
105
114
  var _iterator = createForOfIteratorHelper._createForOfIteratorHelper(parsedPattern !== null && parsedPattern !== void 0 ? parsedPattern : []),
106
115
  _step;
107
116
  try {
@@ -186,6 +195,7 @@ val) {
186
195
  return actualRoute;
187
196
  }
188
197
 
198
+ exports._typeof = _typeof;
189
199
  exports.getJsonEntryStegaRoot = getJsonEntryStegaRoot;
190
200
  exports.getValRouteUrlFromVal = getValRouteUrlFromVal;
191
201
  exports.initValRouteFromVal = initValRouteFromVal;
@@ -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-f206d2ea.cjs.dev.js');
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-c1c3ef55.cjs.dev.js');
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-bd3f89d3.cjs.prod.js');
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-90c4171d.cjs.prod.js');
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');