Load the God's Eye View panel through the MCP server

Hosts serve panels from their own sites and may refuse other addresses;
Codex refuses any address on the user's machine. The panel now never
requests the app's server: it loads the app's panel build and data
through panel_request, a tool only the panel may call, which requests
the path from the app's server. One path in every host; only map
providers load directly.

npm run build:panel writes the panel build to dist/panel, served at
/panel/: one app script, one stylesheet, Cesium's script, and Cesium's
workers as one script Cesium runs from memory. Tools may now be marked
app-only. The panel CORS rules are gone.
This commit is contained in:
Sameh Khamis committed 2026-10-02 18:29:42 -07:00
1 parent b11d54d8b8
commit 996b95eb45
20 files changed
+1265 -437

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
import assert from 'node:assert/strict';
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import test from 'node:test';
import * as PANEL_PATHS from '../tools/globePanel.js';
import {
PANEL_BASE,
PANEL_WORKERS_PATH,
panelBuildConfig,
panelBuildPlugin,
workersEntrySource,
} from '../../build/panel.js';
test('the panel loads the paths the panel build writes', () => {
assert.equal(PANEL_BASE, PANEL_PATHS.PANEL_BASE);
assert.equal(PANEL_WORKERS_PATH, PANEL_PATHS.PANEL_WORKERS_PATH);
});
test('the panel build is one script and one stylesheet under /panel/', () => {
const config = panelBuildConfig({
plugins: [],
build: { chunkSizeWarningLimit: 1500 },
});
assert.equal(config.base, PANEL_BASE);
assert.equal(config.build.outDir, 'dist/panel');
assert.equal(config.build.cssCodeSplit, false);
assert.equal(config.build.rollupOptions.output.inlineDynamicImports, true);
assert.equal(config.build.chunkSizeWarningLimit, 1500);
});
test("Cesium's workers load lazily from one script", () => {
const source = workersEntrySource(['createGeometry', 'decodeDraco'], '/w');
assert.match(source, /^self\.CesiumWorkers = \{/);
assert.match(
source,
/"createGeometry": \(\) => import\("\/w\/createGeometry\.js"\)/,
);
assert.match(
source,
/"decodeDraco": \(\) => import\("\/w\/decodeDraco\.js"\)/,
);
});
test('the dev server serves the panel build and nothing outside it', async () => {
const root = await mkdtemp(join(tmpdir(), 'panel-build-'));
try {
await mkdir(join(root, 'out', 'assets'), { recursive: true });
await writeFile(join(root, 'out', 'index.html'), '<p>panel</p>');
await writeFile(join(root, 'out', 'assets', 'a.js'), 'x');
await writeFile(join(root, 'secret.txt'), 'secret');
let middleware;
panelBuildPlugin({ outDir: 'out' }).configureServer({
config: { root },
middlewares: { use: (fn) => (middleware = fn) },
});
const get = (url) =>
new Promise((resolve) => {
const res = {
statusCode: 200,
headers: {},
setHeader(name, value) {
this.headers[name] = value;
},
end(body) {
resolve({ status: this.statusCode, headers: this.headers, body });
},
};
middleware({ url }, res, () => resolve({ passed: true }));
});
const page = await get('/panel/');
assert.equal(String(page.body), '<p>panel</p>');
assert.equal(page.headers['Content-Type'], 'text/html');
const script = await get('/panel/assets/a.js');
assert.equal(script.headers['Content-Type'], 'text/javascript');
assert.equal((await get('/panel/missing.js')).status, 404);
assert.deepEqual(await get('/panel/..%2Fsecret.txt'), { passed: true });
assert.deepEqual(await get('/other'), { passed: true });
} finally {
await rm(root, { recursive: true, force: true });
}
});
+9 -48
View File
@@ -12,8 +12,7 @@ test('explicit build inputs preserve browser-only defines, plugin order and loop
googleApiKey: 'browser-fixture',
cesiumToken: 'ion-fixture',
});
assert.equal(config.plugins[0].name, 'panel-cors');
assert.equal(config.plugins[3], plugin);
assert.equal(config.plugins[2], plugin);
assert.equal(config.server.host, 'localhost');
assert.equal(config.server.port, 4173);
assert.deepEqual(config.server.allowedHosts, [
@@ -43,45 +42,6 @@ test('explicit build inputs preserve browser-only defines, plugin order and loop
);
});
test('panel origins may read every dev server path, other sites may not', () => {
let middleware;
createBrowserViteConfig().plugins[0].configureServer({
middlewares: { use: (fn) => (middleware = fn) },
});
const request = (origin, method = 'GET') => {
const headers = {};
let ended = false;
let passed = false;
middleware(
{ method, headers: origin ? { origin } : {} },
{
setHeader: (name, value) => (headers[name] = value),
end: () => (ended = true),
},
() => (passed = true),
);
return { headers, ended, passed };
};
const panel = request('https://abc123.claudemcpcontent.com');
assert.equal(
panel.headers['Access-Control-Allow-Origin'],
'https://abc123.claudemcpcontent.com',
);
assert.equal(panel.passed, true);
assert.equal(
request('https://abc123.claudemcpcontent.com', 'OPTIONS').ended,
true,
);
assert.equal(
request('codex-sandbox://mcp-app-ab12.web-sandbox.oaiusercontent.com')
.headers['Access-Control-Allow-Origin'],
'codex-sandbox://mcp-app-ab12.web-sandbox.oaiusercontent.com',
);
const other = request('https://example.com');
assert.deepEqual(other.headers, {});
assert.equal(other.passed, true);
});
test('build helper does not discover environment values or construct local providers', () => {
const before = process.env.GOOGLE_MAPS_API_KEY;
process.env.GOOGLE_MAPS_API_KEY = 'environment-fixture';
@@ -92,8 +52,8 @@ test('build helper does not discover environment values or construct local provi
undefined,
);
assert.deepEqual(
config.plugins.slice(3).map((plugin) => plugin.name),
['embed-framing'],
config.plugins.slice(2).map((plugin) => plugin.name),
['embed-framing', 'panel-build'],
);
} finally {
if (before === undefined) delete process.env.GOOGLE_MAPS_API_KEY;
@@ -106,14 +66,15 @@ test('root config retains existing named exports and standalone provider order',
assert.equal(compatibility[name], value, name);
const config = standaloneConfig({ mode: 'test' });
assert.deepEqual(
config.plugins.slice(3, -3).map((plugin) => plugin.name),
config.plugins.slice(2, -4).map((plugin) => plugin.name),
providers.localProviderPlugins().map((plugin) => plugin.name),
);
assert.equal(config.plugins.at(-4).name, 'gev-key-setup');
assert.equal(config.plugins.at(-5).name, 'gev-key-setup');
// The local MCP route follows every provider and precedes the API fallback.
assert.equal(config.plugins.at(-3).name, 'local-mcp');
assert.equal(config.plugins.at(-2).name, 'api-not-found');
assert.equal(config.plugins.at(-1).name, 'embed-framing');
assert.equal(config.plugins.at(-4).name, 'local-mcp');
assert.equal(config.plugins.at(-3).name, 'api-not-found');
assert.equal(config.plugins.at(-2).name, 'embed-framing');
assert.equal(config.plugins.at(-1).name, 'panel-build');
});
test('build export resolves in Node and has no browser fallback', async () => {