sunpeak 0.18.1 → 0.18.2
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/dist/mcp/index.cjs +145 -11
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +142 -13
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/production-server.d.ts +14 -0
- package/dist/mcp/resolve-domain.d.ts +55 -0
- package/dist/types/resource-config.d.ts +20 -1
- package/package.json +1 -1
- package/template/dist/albums/albums.json +1 -1
- package/template/dist/carousel/carousel.json +1 -1
- package/template/dist/map/map.json +1 -1
- package/template/dist/review/review.json +1 -1
package/dist/mcp/index.cjs
CHANGED
|
@@ -9006,6 +9006,101 @@ function dZ(Z) {
|
|
|
9006
9006
|
return Z.extensions?.[OQ];
|
|
9007
9007
|
}
|
|
9008
9008
|
//#endregion
|
|
9009
|
+
//#region src/mcp/resolve-domain.ts
|
|
9010
|
+
/**
|
|
9011
|
+
* Resolve a domain config to a single string for the given host.
|
|
9012
|
+
*
|
|
9013
|
+
* Lookup order: `map[clientName]` → `map['default']` → `undefined`.
|
|
9014
|
+
* If `domain` is a plain string, it's returned as-is regardless of host.
|
|
9015
|
+
*/
|
|
9016
|
+
function resolveDomain(domain, clientName) {
|
|
9017
|
+
if (domain === void 0) return void 0;
|
|
9018
|
+
if (typeof domain === "string") return domain;
|
|
9019
|
+
if (clientName && domain[clientName]) return domain[clientName];
|
|
9020
|
+
return domain["default"];
|
|
9021
|
+
}
|
|
9022
|
+
/**
|
|
9023
|
+
* Compute the Claude sandbox domain for a given MCP server URL.
|
|
9024
|
+
*
|
|
9025
|
+
* Claude uses the first 32 hex characters of a SHA-256 hash of the server URL
|
|
9026
|
+
* as a subdomain of `claudemcpcontent.com`.
|
|
9027
|
+
*
|
|
9028
|
+
* @example
|
|
9029
|
+
* ```ts
|
|
9030
|
+
* computeClaudeDomain('https://example.com/mcp')
|
|
9031
|
+
* // → 'a904794854a047f6b936c2d62d57a3c0.claudemcpcontent.com'
|
|
9032
|
+
* ```
|
|
9033
|
+
*/
|
|
9034
|
+
function computeClaudeDomain(serverUrl) {
|
|
9035
|
+
return `${(0, node_crypto.createHash)("sha256").update(serverUrl).digest("hex").slice(0, 32)}.claudemcpcontent.com`;
|
|
9036
|
+
}
|
|
9037
|
+
/**
|
|
9038
|
+
* Compute the ChatGPT sandbox domain for a given MCP server URL.
|
|
9039
|
+
*
|
|
9040
|
+
* ChatGPT derives a subdomain from the server URL by replacing non-alphanumeric
|
|
9041
|
+
* characters with hyphens and appending `.oaiusercontent.com`.
|
|
9042
|
+
*
|
|
9043
|
+
* @example
|
|
9044
|
+
* ```ts
|
|
9045
|
+
* computeChatGPTDomain('https://www.example.com/mcp')
|
|
9046
|
+
* // → 'www-example-com.oaiusercontent.com'
|
|
9047
|
+
* ```
|
|
9048
|
+
*/
|
|
9049
|
+
function computeChatGPTDomain(serverUrl) {
|
|
9050
|
+
let hostname;
|
|
9051
|
+
try {
|
|
9052
|
+
hostname = new URL(serverUrl).hostname;
|
|
9053
|
+
} catch {
|
|
9054
|
+
hostname = serverUrl;
|
|
9055
|
+
}
|
|
9056
|
+
return `${hostname.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-|-$/g, "")}.oaiusercontent.com`;
|
|
9057
|
+
}
|
|
9058
|
+
/**
|
|
9059
|
+
* Inject a resolved domain into resource metadata.
|
|
9060
|
+
*
|
|
9061
|
+
* If the `_meta.ui.domain` field is a map (Record), it's resolved to a single
|
|
9062
|
+
* string using `clientName`. If it's already a string or absent, the metadata
|
|
9063
|
+
* is returned unchanged.
|
|
9064
|
+
*/
|
|
9065
|
+
function injectResolvedDomain(meta, clientName) {
|
|
9066
|
+
if (!meta) return meta;
|
|
9067
|
+
const ui = meta.ui;
|
|
9068
|
+
if (!ui) return meta;
|
|
9069
|
+
const domain = ui.domain;
|
|
9070
|
+
if (domain === void 0 || typeof domain === "string") return meta;
|
|
9071
|
+
const resolved = resolveDomain(domain, clientName);
|
|
9072
|
+
const { domain: _removed, ...restUi } = ui;
|
|
9073
|
+
return {
|
|
9074
|
+
...meta,
|
|
9075
|
+
ui: {
|
|
9076
|
+
...restUi,
|
|
9077
|
+
...resolved !== void 0 ? { domain: resolved } : {}
|
|
9078
|
+
}
|
|
9079
|
+
};
|
|
9080
|
+
}
|
|
9081
|
+
/**
|
|
9082
|
+
* Auto-compute a default domain for the connecting host when the resource
|
|
9083
|
+
* metadata has no domain set.
|
|
9084
|
+
*
|
|
9085
|
+
* Returns the metadata unchanged if `_meta.ui.domain` is already present.
|
|
9086
|
+
* Otherwise, computes a host-appropriate domain from the server URL.
|
|
9087
|
+
*/
|
|
9088
|
+
function injectDefaultDomain(meta, clientName, serverUrl) {
|
|
9089
|
+
const ui = meta?.ui ?? {};
|
|
9090
|
+
if (typeof ui.domain === "string") return meta;
|
|
9091
|
+
let domain;
|
|
9092
|
+
if (clientName === "openai-mcp" || clientName?.startsWith("chatgpt")) domain = computeChatGPTDomain(serverUrl);
|
|
9093
|
+
else if (clientName === "claude") domain = computeClaudeDomain(serverUrl);
|
|
9094
|
+
if (!domain) return meta ?? {};
|
|
9095
|
+
return {
|
|
9096
|
+
...meta,
|
|
9097
|
+
ui: {
|
|
9098
|
+
...ui,
|
|
9099
|
+
domain
|
|
9100
|
+
}
|
|
9101
|
+
};
|
|
9102
|
+
}
|
|
9103
|
+
//#endregion
|
|
9009
9104
|
//#region src/mcp/server.ts
|
|
9010
9105
|
var localDevServerUrl = "http://localhost:8000";
|
|
9011
9106
|
var localHmrWsUrl = "ws://localhost:24678";
|
|
@@ -9132,6 +9227,19 @@ function createAppServer(config, simulations, viteMode) {
|
|
|
9132
9227
|
resources: {},
|
|
9133
9228
|
tools: {}
|
|
9134
9229
|
} });
|
|
9230
|
+
let clientName;
|
|
9231
|
+
mcpServer.server.oninitialized = () => {
|
|
9232
|
+
clientName = mcpServer.server.getClientVersion()?.name;
|
|
9233
|
+
for (const [, handle] of resourceHandles) {
|
|
9234
|
+
const currentMeta = handle.metadata?._meta;
|
|
9235
|
+
const resolved = injectResolvedDomain(currentMeta, clientName) ?? currentMeta;
|
|
9236
|
+
const withDefault = injectDefaultDomain(resolved, clientName, localDevServerUrl);
|
|
9237
|
+
if (withDefault !== resolved) handle.update({ metadata: {
|
|
9238
|
+
...handle.metadata,
|
|
9239
|
+
_meta: withDefault
|
|
9240
|
+
} });
|
|
9241
|
+
}
|
|
9242
|
+
};
|
|
9135
9243
|
const registeredUriSet = /* @__PURE__ */ new Set();
|
|
9136
9244
|
const registeredToolNames = /* @__PURE__ */ new Set();
|
|
9137
9245
|
const resourceHandles = /* @__PURE__ */ new Map();
|
|
@@ -9154,7 +9262,8 @@ function createAppServer(config, simulations, viteMode) {
|
|
|
9154
9262
|
_meta: listMeta
|
|
9155
9263
|
}, async (readUri, extra) => {
|
|
9156
9264
|
const prodBuild = needsProdBuild(extra?.requestInfo?.headers ?? {});
|
|
9157
|
-
const
|
|
9265
|
+
const baseMeta = viteMode && !prodBuild ? injectViteCSP(resourceMeta) : resourceMeta;
|
|
9266
|
+
const readMeta = injectDefaultDomain(injectResolvedDomain(baseMeta, clientName) ?? baseMeta, clientName, localDevServerUrl);
|
|
9158
9267
|
let content;
|
|
9159
9268
|
try {
|
|
9160
9269
|
content = getResourceHtml(simulation, viteMode, prodBuild);
|
|
@@ -9549,7 +9658,7 @@ function log(level, msg, extra) {
|
|
|
9549
9658
|
* Resources serve pre-built HTML with their _meta preserved.
|
|
9550
9659
|
*/
|
|
9551
9660
|
function createProductionMcpServer(config) {
|
|
9552
|
-
const { name = "sunpeak-app", version = "0.1.0", serverInfo, tools, resources } = config;
|
|
9661
|
+
const { name = "sunpeak-app", version = "0.1.0", serverInfo, tools, resources, serverUrl } = config;
|
|
9553
9662
|
const mcpServer = new McpServer({
|
|
9554
9663
|
name: serverInfo?.name ?? name,
|
|
9555
9664
|
version: serverInfo?.version ?? version,
|
|
@@ -9565,9 +9674,23 @@ function createProductionMcpServer(config) {
|
|
|
9565
9674
|
resources: {},
|
|
9566
9675
|
tools: {}
|
|
9567
9676
|
} });
|
|
9677
|
+
let clientName;
|
|
9678
|
+
mcpServer.server.oninitialized = () => {
|
|
9679
|
+
clientName = mcpServer.server.getClientVersion()?.name;
|
|
9680
|
+
for (const handle of resourceHandles) {
|
|
9681
|
+
const currentMeta = handle.metadata?._meta;
|
|
9682
|
+
const resolved = injectResolvedDomain(currentMeta, clientName) ?? currentMeta;
|
|
9683
|
+
const withDefault = serverUrl ? injectDefaultDomain(resolved, clientName, serverUrl) : resolved;
|
|
9684
|
+
if (withDefault !== resolved) handle.update({ metadata: {
|
|
9685
|
+
...handle.metadata,
|
|
9686
|
+
_meta: withDefault
|
|
9687
|
+
} });
|
|
9688
|
+
}
|
|
9689
|
+
};
|
|
9568
9690
|
const resourceByName = /* @__PURE__ */ new Map();
|
|
9569
9691
|
for (const res of resources) resourceByName.set(res.name, res);
|
|
9570
9692
|
const registeredResources = /* @__PURE__ */ new Set();
|
|
9693
|
+
const resourceHandles = [];
|
|
9571
9694
|
let toolCount = 0;
|
|
9572
9695
|
for (const tool of tools) {
|
|
9573
9696
|
const makeCallback = () => {
|
|
@@ -9595,15 +9718,20 @@ function createProductionMcpServer(config) {
|
|
|
9595
9718
|
if (res) {
|
|
9596
9719
|
if (!registeredResources.has(res.uri)) {
|
|
9597
9720
|
registeredResources.add(res.uri);
|
|
9598
|
-
fZ(mcpServer, res.name, res.uri, {
|
|
9721
|
+
const handle = fZ(mcpServer, res.name, res.uri, {
|
|
9599
9722
|
description: res.description,
|
|
9600
9723
|
_meta: res._meta
|
|
9601
|
-
}, async () =>
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9724
|
+
}, async () => {
|
|
9725
|
+
const resolved = injectResolvedDomain(res._meta, clientName) ?? res._meta;
|
|
9726
|
+
const readMeta = serverUrl ? injectDefaultDomain(resolved, clientName, serverUrl) : resolved;
|
|
9727
|
+
return { contents: [{
|
|
9728
|
+
uri: res.uri,
|
|
9729
|
+
mimeType: d,
|
|
9730
|
+
text: res.html,
|
|
9731
|
+
_meta: readMeta
|
|
9732
|
+
}] };
|
|
9733
|
+
});
|
|
9734
|
+
resourceHandles.push(handle);
|
|
9607
9735
|
}
|
|
9608
9736
|
const toolConfig = {
|
|
9609
9737
|
title: tool.tool.title,
|
|
@@ -9872,13 +10000,14 @@ function createHandler(config) {
|
|
|
9872
10000
|
}));
|
|
9873
10001
|
}
|
|
9874
10002
|
if (req.method === "POST") {
|
|
9875
|
-
const { name, version, serverInfo, tools, resources } = config;
|
|
10003
|
+
const { name, version, serverInfo, tools, resources, serverUrl } = config;
|
|
9876
10004
|
const server = createProductionMcpServer({
|
|
9877
10005
|
name,
|
|
9878
10006
|
version,
|
|
9879
10007
|
serverInfo,
|
|
9880
10008
|
tools,
|
|
9881
|
-
resources
|
|
10009
|
+
resources,
|
|
10010
|
+
serverUrl
|
|
9882
10011
|
});
|
|
9883
10012
|
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
9884
10013
|
sessionIdGenerator: () => (0, node_crypto.randomUUID)(),
|
|
@@ -10039,12 +10168,17 @@ exports.FAVICON_BUFFER = FAVICON_BUFFER;
|
|
|
10039
10168
|
exports.FAVICON_DATA_URI = FAVICON_DATA_URI;
|
|
10040
10169
|
exports.RESOURCE_MIME_TYPE = d;
|
|
10041
10170
|
exports.RESOURCE_URI_META_KEY = v;
|
|
10171
|
+
exports.computeChatGPTDomain = computeChatGPTDomain;
|
|
10172
|
+
exports.computeClaudeDomain = computeClaudeDomain;
|
|
10042
10173
|
exports.createHandler = createHandler;
|
|
10043
10174
|
exports.createMcpHandler = createMcpHandler;
|
|
10044
10175
|
exports.createProductionMcpServer = createProductionMcpServer;
|
|
10045
10176
|
exports.getUiCapability = dZ;
|
|
10177
|
+
exports.injectDefaultDomain = injectDefaultDomain;
|
|
10178
|
+
exports.injectResolvedDomain = injectResolvedDomain;
|
|
10046
10179
|
exports.registerAppResource = fZ;
|
|
10047
10180
|
exports.registerAppTool = uZ;
|
|
10181
|
+
exports.resolveDomain = resolveDomain;
|
|
10048
10182
|
exports.runMCPServer = runMCPServer;
|
|
10049
10183
|
exports.setJsonLogging = setJsonLogging;
|
|
10050
10184
|
exports.startProductionHttpServer = startProductionHttpServer;
|