machine-bridge-mcp 1.0.3 → 1.0.5
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 +14 -0
- package/README.md +9 -1
- package/browser-extension/manifest.json +2 -2
- package/docs/ARCHITECTURE.md +3 -0
- package/docs/CLIENTS.md +2 -2
- package/docs/GETTING_STARTED.md +1 -1
- package/docs/OPERATIONS.md +2 -0
- package/docs/TESTING.md +2 -2
- package/package.json +1 -1
- package/src/local/cli.mjs +10 -4
- package/src/local/state.mjs +11 -1
- package/src/worker/http.ts +10 -1
- package/src/worker/index.ts +5 -5
- package/wrangler.jsonc +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.5 - 2026-07-14
|
|
4
|
+
|
|
5
|
+
### Built-in ChatGPT and Grok origins
|
|
6
|
+
|
|
7
|
+
- Allow the exact first-party browser origins used by ChatGPT (`https://chatgpt.com` and legacy `https://chat.openai.com`) and Grok (`https://grok.com` and `https://x.com`) directly in Worker origin validation. Users no longer need to run Wrangler or edit Cloudflare variables to complete OAuth from those clients.
|
|
8
|
+
- Keep `MBM_ALLOWED_ORIGINS` as an additive exact-origin extension point, preserve same-origin and no-Origin requests, reject unrelated and `null` origins, and apply one predicate to preflight and actual requests. Integration tests exercise every built-in origin alongside a configured custom origin.
|
|
9
|
+
|
|
10
|
+
## 1.0.4 - 2026-07-14
|
|
11
|
+
|
|
12
|
+
### Windows first-run workspace
|
|
13
|
+
|
|
14
|
+
- Keep the first interactive workspace question on Windows, but default it to `%USERPROFILE%\MachineBridge` instead of the Command Prompt current directory. Pressing Enter creates, canonicalizes, and remembers that folder, so users do not need `cd` or directory knowledge and an elevated prompt cannot accidentally select `C:\Windows\System32`.
|
|
15
|
+
- Preserve explicit `--workspace` semantics for automation, while allowing an interactively entered Windows workspace folder to be created when it does not yet exist. The installed zero-argument startup test now verifies the remembered platform default.
|
|
16
|
+
|
|
3
17
|
## 1.0.3 - 2026-07-14
|
|
4
18
|
|
|
5
19
|
### Code-scanning and supply-chain integrity
|
package/README.md
CHANGED
|
@@ -97,7 +97,13 @@ npm install
|
|
|
97
97
|
|
|
98
98
|
## Remote MCP for ChatGPT
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
After a global installation, `machine-mcp` can be launched from any Command Prompt or terminal; the package installation directory is not the workspace. On the first interactive Windows start, the CLI asks:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
Workspace folder [C:\Users\Alice\MachineBridge] (press Enter to use the default):
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Press Enter to create and remember `%USERPROFILE%\MachineBridge`. No `cd` command or directory selection is required. Enter another folder when desired; an interactively selected Windows folder is created if it does not yet exist. Later starts reuse the remembered workspace. Advanced users and automation may still select an existing workspace explicitly:
|
|
101
107
|
|
|
102
108
|
```sh
|
|
103
109
|
machine-mcp --workspace /path/to/project
|
|
@@ -132,6 +138,8 @@ MCP Server URL: https://<worker>.<account>.workers.dev/mcp
|
|
|
132
138
|
|
|
133
139
|
During OAuth authorization, enter the name and password of a Machine Bridge account. The first start creates `owner` and prints its generated password once. Additional accounts are managed with `machine-mcp account`. The authorization flow uses PKCE S256, exact redirect/resource binding, expiring hashed access tokens, per-account version checks, and a deployment-wide token version for emergency bulk revocation.
|
|
134
140
|
|
|
141
|
+
The Worker accepts the exact first-party browser origins used by ChatGPT (`https://chatgpt.com` and the legacy `https://chat.openai.com`) and Grok (`https://grok.com` and its X-hosted surface at `https://x.com`). Users do not need to run Wrangler or edit Cloudflare variables. `MBM_ALLOWED_ORIGINS` remains an operator-only, comma-separated extension point for other exact origins; it is additive and does not replace the built-in set. Wildcards and `null` are not accepted.
|
|
142
|
+
|
|
135
143
|
### Multiple clients and accounts
|
|
136
144
|
|
|
137
145
|
One Worker supports several named accounts and OAuth clients. Accounts have independent passwords, roles, active state, versions, codes, and tokens. The roles are `reviewer`, `editor`, `operator`, and `owner`; their effective authority is intersected with the connected daemon policy and enforced in both the Worker and local runtime. Role changes, suspension, password rotation, and removal revoke only the affected account.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Machine Bridge Browser",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.5",
|
|
5
5
|
"description": "Connects the current Chromium browser profile to the local Machine Bridge runtime for user-authorized automation.",
|
|
6
6
|
"permissions": [
|
|
7
7
|
"tabs",
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"action": {
|
|
31
31
|
"default_title": "Machine Bridge Browser"
|
|
32
32
|
},
|
|
33
|
-
"version_name": "1.0.
|
|
33
|
+
"version_name": "1.0.5"
|
|
34
34
|
}
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -19,6 +19,7 @@ No transport is treated as a sandbox. Both transports invoke the same local runt
|
|
|
19
19
|
### CLI and state layer
|
|
20
20
|
|
|
21
21
|
The CLI canonicalizes workspaces, resolves policy profiles, maintains per-workspace state and credentials, serializes startup/deploy/rotation with process-identity locks, deploys the Worker, installs optional platform-native autostart, and starts either remote daemon or stdio mode.
|
|
22
|
+
On a first interactive Windows start, workspace selection remains explicit but offers `%USERPROFILE%\MachineBridge` as a dedicated default; accepting it creates and remembers the folder instead of inheriting the shell current directory. Non-Windows interactive starts retain the current-directory default, and explicit `--workspace` paths remain strict existing-path inputs.
|
|
22
23
|
|
|
23
24
|
A canonical workspace receives an independent profile, Worker name, secret set, resource registry, managed-job directory, daemon/startup locks, and state file. State schema version 6 records named accounts, policy origin/revision, and local resource metadata in addition to the capability fields. `exclusive-file.mjs` owns complete-before-visible exclusive claims and flushed atomic replacement. `process-identity.mjs` owns PID liveness, process start-time comparison, bounded command-line inspection, and PID-reuse classification. `service-lifecycle.mjs` owns the fail-closed stop-daemons-before-remove state machine shared by service removal and full uninstall.
|
|
24
25
|
|
|
@@ -234,6 +235,8 @@ Removal first acquires a state-root maintenance lock that blocks new profile/sta
|
|
|
234
235
|
|
|
235
236
|
OAuth metadata is pruned on access. Expired codes/tokens, old throttling records, and inactive clients without active credentials are removed. Source identities are deployment-keyed HMAC values, not stored source addresses or reversible unsalted hashes.
|
|
236
237
|
|
|
238
|
+
Browser-origin validation accepts requests without an `Origin` header, the Worker's own origin, and a fixed first-party set for ChatGPT (`https://chatgpt.com`, `https://chat.openai.com`) and Grok (`https://grok.com`, `https://x.com`). `MBM_ALLOWED_ORIGINS` contributes optional exact comma-separated additions. It cannot remove the built-in origins, and wildcard or `null` origins are not accepted. Both preflight and actual requests use the same predicate.
|
|
239
|
+
|
|
237
240
|
## Observability
|
|
238
241
|
|
|
239
242
|
Public health exposes only server identity and version. Authenticated `server_info` exposes bounded runtime status, policy origin/revision, managed-job counts, resource alias names without paths or values, daemon/relay-advertised tool counts, relay route state without endpoint details, and privacy-preserving capability-routing evidence. It explicitly reports that the host-exposed subset is unknown to the server. `diagnose_runtime` runs fixed local probes and explicitly reports that its own request reached the daemon.
|
package/docs/CLIENTS.md
CHANGED
|
@@ -114,7 +114,7 @@ args = ["/absolute/path/to/machine-mcp.mjs", "stdio", "--workspace", "/path/to/p
|
|
|
114
114
|
|
|
115
115
|
Codex CLI, the Codex IDE extension, and supported ChatGPT Desktop Codex hosts can share MCP configuration on the same Codex host. ChatGPT web does not read local Codex configuration files; web use requires a hosted plugin/connector or a reachable remote MCP endpoint.
|
|
116
116
|
|
|
117
|
-
## Remote ChatGPT connection
|
|
117
|
+
## Remote ChatGPT and Grok connection
|
|
118
118
|
|
|
119
119
|
Run:
|
|
120
120
|
|
|
@@ -122,7 +122,7 @@ Run:
|
|
|
122
122
|
machine-mcp --workspace /path/to/project
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
Enter the printed `/mcp` URL in the remote MCP connector. During OAuth authorization, verify the displayed client name and redirect URI before entering a Machine Bridge account name and password.
|
|
125
|
+
Enter the printed `/mcp` URL in the remote MCP connector. During OAuth authorization, verify the displayed client name and redirect URI before entering a Machine Bridge account name and password. The Worker has exact built-in CORS support for `https://chatgpt.com`, legacy `https://chat.openai.com`, `https://grok.com`, and the X-hosted Grok surface at `https://x.com`; no direct Wrangler command or Cloudflare variable edit is required.
|
|
126
126
|
|
|
127
127
|
Several OAuth clients and named accounts can coexist. Accounts have independent passwords, roles, active state, versions, and targeted revocation. Their effective tool sets are intersected with the connected daemon policy. All accounts still share one daemon and OS user, so hard tenant isolation requires separate deployments; see [MULTI_ACCOUNT.md](MULTI_ACCOUNT.md).
|
|
128
128
|
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -204,7 +204,7 @@ Current ChatGPT developer-mode flow, as documented in OpenAI's [Connect from Cha
|
|
|
204
204
|
7. Enter the Machine Bridge account name and password only after those values are recognized.
|
|
205
205
|
8. Create a new chat and enable the app for that conversation.
|
|
206
206
|
|
|
207
|
-
ChatGPT navigation labels can change. The invariant is that the client must connect to the public `/mcp` endpoint and complete the OAuth authorization page served by the Worker.
|
|
207
|
+
ChatGPT navigation labels can change. The invariant is that the client must connect to the public `/mcp` endpoint and complete the OAuth authorization page served by the Worker. The same public `/mcp` URL can be entered in Grok where remote MCP configuration is available. Machine Bridge accepts the exact `https://grok.com` and `https://x.com` browser origins as well as ChatGPT's current and legacy origins without requiring a Wrangler command.
|
|
208
208
|
|
|
209
209
|
## 8. Verify the first connection
|
|
210
210
|
|
package/docs/OPERATIONS.md
CHANGED
|
@@ -99,6 +99,8 @@ machine-mcp --verbose
|
|
|
99
99
|
|
|
100
100
|
`Unknown cli config "--allow-scripts"` proves the package installation ran under npm 11 or older. `Invalid property "node"` or `Invalid property "devEngines.node"` means npm parsed an outdated `devEngines` object; inspect the npm debug log to identify its source rather than assuming it belongs to Machine Bridge. The published package declares both Node.js 26 and npm 12 in `engines`, and `machine-mcp doctor` checks both active versions. Keep `--omit=optional` in the install command. Without it npm may resolve optional `fsevents` and warn that its install script was not included in `allowScripts`; Machine Bridge does not require that development-time watcher at runtime.
|
|
101
101
|
|
|
102
|
+
After global installation, Windows users may open any `cmd.exe` window and run `machine-mcp`; they do not need to navigate to a project or package directory. On the first interactive start, the CLI asks for a workspace folder and displays `%USERPROFILE%\MachineBridge` as the default. Pressing Enter creates and remembers that folder. This avoids inheriting an arbitrary Command Prompt current directory such as `C:\Windows\System32`. Typing another folder in the prompt creates that folder when necessary. Explicit `--workspace PATH` remains a strict automation interface and requires an existing path.
|
|
103
|
+
|
|
102
104
|
## Version 1 upgrade convergence
|
|
103
105
|
|
|
104
106
|
Version 1 advertises only MCP protocol `2025-11-25`. Upgrade the MCP client/host if it cannot negotiate that version; Machine Bridge does not retain an obsolete protocol dispatcher. The current local state schema is unchanged from the final 0.18.x release, so do not delete the state root merely to upgrade.
|
package/docs/TESTING.md
CHANGED
|
@@ -53,7 +53,7 @@ The suite includes:
|
|
|
53
53
|
- deterministic property tests over hostile browser-protocol byte strings, canonical/custom policy combinations, argv bounds/NULs, and a real direct process proving shell metacharacters remain literal argv;
|
|
54
54
|
- CLI parsing, policy profiles, and client configuration boundaries;
|
|
55
55
|
- live stdio MCP initialization with session instructions, capability resolution, discovery, calls, rich content, sessions, cancellation, managed-job acceptance, and a detached job/finally phase that survives stdio shutdown;
|
|
56
|
-
- live local Worker OAuth registration, consent, URL-constructed `303` callbacks including the ChatGPT redirect URI and encoded state, PKCE, token replay rejection, throttling,
|
|
56
|
+
- live local Worker OAuth registration, consent, URL-constructed `303` callbacks including the ChatGPT redirect URI and encoded state, PKCE, token replay rejection, throttling, exact built-in ChatGPT/Grok browser origins, additive custom origins, unrelated/opaque-origin rejection, protocol negotiation, HMAC-bound MCP session issuance, two-session same-id concurrency, sessionless same-id independence, session-scoped cancellation isolation, same-session duplicate rejection, daemon-backed session bootstrap, dynamic tool advertisement, rich content, daemon replacement, cancellation, malformed daemon JSON/non-object rejection, duplicate hello rejection, and unknown-message closure.
|
|
57
57
|
- local runtime proof that one blocked tool handler does not serialize an independent handler, plus relay fault injection proving an undeliverable terminal result interrupts the ambiguous socket and enters reconnect backoff.
|
|
58
58
|
|
|
59
59
|
## Opt-in live desktop and browser validation
|
|
@@ -89,7 +89,7 @@ npm run version:check
|
|
|
89
89
|
npm run release-impact:check
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
GitHub Actions executes the main suite on Linux, macOS, and Windows using the pinned Node 26/npm 12 baseline. Because Node 26 currently bundles npm 11, CI downloads the exact npm 12.0.1 tarball from the canonical registry, rejects redirects, verifies its recorded SHA-512 SRI, and exposes that verified CLI through `GITHUB_PATH` before any project-local npm command can trigger strict `devEngines`. Checkout fetches version tags so the release-impact gate can compare the branch with the latest release. A separate package-audit job scans reachable Git history, audits both the complete dependency graph and the production-only graph, verifies registry signatures and attestations, validates a CycloneDX SBOM written under the runner temporary directory, exercises the documented isolated global installation, then performs a dry-run package build. Separate pinned workflows validate governance titles, review dependency changes, run CodeQL over JavaScript/TypeScript and GitHub Actions, and run OpenSSF Scorecard. The SARIF gate fails closed when rule metadata is absent, CodeQL permits only one exact, expiring non-shell process-boundary result, and Scorecard permits only exact reviewed governance/time-dependent findings; new dependency-pinning, fuzzing, or other supply-chain results fail before upload. Scorecard's signed analysis job contains only pinned `uses` steps, while a dependent gate job downloads the SARIF, enforces the accepted inventory, and uploads it to code scanning. Security property tests use a `.js` `fast-check` suite with deterministic seeds because the pinned Scorecard scanner recognizes JavaScript property testing only in `*.js`/`*.jsx`. The macOS matrix job also runs the installation smoke test because Wrangler's optional `fsevents` resolution is platform-specific. Third-party Actions are pinned to immutable 40-character commit SHAs; architecture tests reject movable tags, and Dependabot monitors both action and dependency updates. Source release creation additionally requires successful push-triggered CI, CodeQL, Governance, and Scorecard runs for the exact `main` commit.
|
|
92
|
+
GitHub Actions executes the main suite on Linux, macOS, and Windows using the pinned Node 26/npm 12 baseline. Because Node 26 currently bundles npm 11, CI downloads the exact npm 12.0.1 tarball from the canonical registry, rejects redirects, verifies its recorded SHA-512 SRI, and exposes that verified CLI through `GITHUB_PATH` before any project-local npm command can trigger strict `devEngines`. Checkout fetches version tags so the release-impact gate can compare the branch with the latest release. A separate package-audit job scans reachable Git history, audits both the complete dependency graph and the production-only graph, verifies registry signatures and attestations, validates a CycloneDX SBOM written under the runner temporary directory, exercises the documented isolated global installation, then performs a dry-run package build. Separate pinned workflows validate governance titles, review dependency changes, run CodeQL over JavaScript/TypeScript and GitHub Actions, and run OpenSSF Scorecard. The SARIF gate fails closed when rule metadata is absent, CodeQL permits only one exact, expiring non-shell process-boundary result, and Scorecard permits only exact reviewed governance/time-dependent findings; new dependency-pinning, fuzzing, or other supply-chain results fail before upload. Scorecard's signed analysis job contains only pinned `uses` steps, while a dependent gate job downloads the SARIF, enforces the accepted inventory, and uploads it to code scanning. Security property tests use a `.js` `fast-check` suite with deterministic seeds because the pinned Scorecard scanner recognizes JavaScript property testing only in `*.js`/`*.jsx`. The installed zero-argument startup smoke test also verifies that Windows creates and remembers `%USERPROFILE%\MachineBridge` while other platforms retain the package-free current directory. The macOS matrix job also runs the installation smoke test because Wrangler's optional `fsevents` resolution is platform-specific. Third-party Actions are pinned to immutable 40-character commit SHAs; architecture tests reject movable tags, and Dependabot monitors both action and dependency updates. Source release creation additionally requires successful push-triggered CI, CodeQL, Governance, and Scorecard runs for the exact `main` commit.
|
|
93
93
|
|
|
94
94
|
## Test design rules
|
|
95
95
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "machine-bridge-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Cross-client MCP bridge for local agent context, structured browser and application automation, files, Git, processes, resources, and durable jobs over stdio or OAuth relay.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/local/cli.mjs
CHANGED
|
@@ -26,8 +26,10 @@ import {
|
|
|
26
26
|
acquireStartupLockWithWait,
|
|
27
27
|
appName,
|
|
28
28
|
daemonLockPathForState,
|
|
29
|
+
defaultFirstRunWorkspace,
|
|
29
30
|
defaultStateRoot,
|
|
30
31
|
ensureWorkerSecrets,
|
|
32
|
+
ensureWorkspaceDirectory,
|
|
31
33
|
expandHome,
|
|
32
34
|
loadGlobalConfig,
|
|
33
35
|
loadState,
|
|
@@ -95,15 +97,19 @@ async function chooseWorkspace(args, { promptOnFirstRun, save, allowPositional =
|
|
|
95
97
|
const remembered = selectedWorkspace(stateRoot);
|
|
96
98
|
if (remembered) return resolveWorkspace(remembered);
|
|
97
99
|
|
|
98
|
-
const fallback = process.cwd();
|
|
100
|
+
const fallback = promptOnFirstRun ? defaultFirstRunWorkspace() : process.cwd();
|
|
99
101
|
if (!promptOnFirstRun || !process.stdin.isTTY) {
|
|
100
|
-
const workspace =
|
|
102
|
+
const workspace = promptOnFirstRun && process.platform === "win32"
|
|
103
|
+
? ensureWorkspaceDirectory(fallback)
|
|
104
|
+
: resolveWorkspace(fallback);
|
|
101
105
|
if (save) setSelectedWorkspace(workspace, stateRoot);
|
|
102
106
|
return workspace;
|
|
103
107
|
}
|
|
104
108
|
|
|
105
|
-
const answer = await ask(`Workspace
|
|
106
|
-
const workspace =
|
|
109
|
+
const answer = await ask(`Workspace folder [${fallback}] (press Enter to use the default): `);
|
|
110
|
+
const workspace = process.platform === "win32"
|
|
111
|
+
? ensureWorkspaceDirectory(answer.trim() || fallback)
|
|
112
|
+
: resolveWorkspace(answer.trim() || fallback);
|
|
107
113
|
if (save) setSelectedWorkspace(workspace, stateRoot);
|
|
108
114
|
return workspace;
|
|
109
115
|
}
|
package/src/local/state.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
-
import { existsSync, lstatSync, realpathSync, rmSync, unlinkSync, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, realpathSync, rmSync, unlinkSync, readdirSync, statSync } from "node:fs";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -35,6 +35,16 @@ export function resolveWorkspace(input = process.cwd()) {
|
|
|
35
35
|
return realpathSync.native ? realpathSync.native(resolved) : realpathSync(resolved);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export function defaultFirstRunWorkspace({ platform = process.platform, home = os.homedir(), cwd = process.cwd() } = {}) {
|
|
39
|
+
return path.resolve(platform === "win32" ? path.join(home, "MachineBridge") : cwd);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function ensureWorkspaceDirectory(input) {
|
|
43
|
+
const requested = path.resolve(expandHome(input));
|
|
44
|
+
mkdirSync(requested, { recursive: true });
|
|
45
|
+
return resolveWorkspace(requested);
|
|
46
|
+
}
|
|
47
|
+
|
|
38
48
|
export function defaultStateRoot() {
|
|
39
49
|
if (process.platform === "win32") {
|
|
40
50
|
const base = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
|
package/src/worker/http.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
const UNSAFE_DISPLAY_CONTROLS = /[\u0000-\u001f\u007f\u200B-\u200F\u202A-\u202E\u2066-\u2069\uFEFF]/g;
|
|
2
2
|
|
|
3
|
+
export const BUILT_IN_BROWSER_ORIGINS = Object.freeze([
|
|
4
|
+
"https://chatgpt.com",
|
|
5
|
+
"https://chat.openai.com",
|
|
6
|
+
"https://grok.com",
|
|
7
|
+
"https://x.com",
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
const BUILT_IN_BROWSER_ORIGIN_SET = new Set(BUILT_IN_BROWSER_ORIGINS);
|
|
11
|
+
|
|
3
12
|
export class HttpError extends Error {
|
|
4
13
|
readonly status: number;
|
|
5
14
|
readonly code: string;
|
|
@@ -233,7 +242,7 @@ function appendVary(headers: Headers, value: string): void {
|
|
|
233
242
|
}
|
|
234
243
|
|
|
235
244
|
function isConfiguredOrSameOrigin(origin: string, base: string, configured: string): boolean {
|
|
236
|
-
if (isDefaultAllowedOrigin(origin, base)) return true;
|
|
245
|
+
if (isDefaultAllowedOrigin(origin, base) || BUILT_IN_BROWSER_ORIGIN_SET.has(origin)) return true;
|
|
237
246
|
const allowed = configured.split(",").map((item) => item.trim()).filter((item) => item && item !== "null");
|
|
238
247
|
return allowed.includes(origin);
|
|
239
248
|
}
|
package/src/worker/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "./http";
|
|
23
23
|
|
|
24
24
|
const SERVER_NAME = String(serverMetadata.name);
|
|
25
|
-
const SERVER_VERSION = "1.0.
|
|
25
|
+
const SERVER_VERSION = "1.0.5";
|
|
26
26
|
const MCP_PROTOCOL_VERSION = String(serverMetadata.protocolVersion);
|
|
27
27
|
const MCP_SUPPORTED_PROTOCOL_VERSIONS = serverMetadata.supportedProtocolVersions.map((value) => String(value));
|
|
28
28
|
const JSONRPC_VERSION = "2.0";
|
|
@@ -90,11 +90,11 @@ export class BridgeRoom extends DurableObject<BridgeEnv> {
|
|
|
90
90
|
|
|
91
91
|
async fetch(request: Request): Promise<Response> {
|
|
92
92
|
const base = baseUrl(request);
|
|
93
|
-
const
|
|
93
|
+
const extraOrigins = this.env.MBM_ALLOWED_ORIGINS ?? "";
|
|
94
94
|
let response: Response;
|
|
95
|
-
if (!validateOrigin(request, base,
|
|
96
|
-
else if (request.method === "OPTIONS" && request.headers.has("Origin")) response = corsPreflight(request, base,
|
|
97
|
-
else response = applyCors(await this.handleRequest(request, base), request, base,
|
|
95
|
+
if (!validateOrigin(request, base, extraOrigins)) response = json({ error: "origin_not_allowed" }, 403);
|
|
96
|
+
else if (request.method === "OPTIONS" && request.headers.has("Origin")) response = corsPreflight(request, base, extraOrigins);
|
|
97
|
+
else response = applyCors(await this.handleRequest(request, base), request, base, extraOrigins);
|
|
98
98
|
this.observability.requestFinished(response.status);
|
|
99
99
|
return response;
|
|
100
100
|
}
|