starmux 0.10.0 → 0.12.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/CONTRIBUTING.md +1 -1
- package/README.md +184 -59
- package/SECURITY.md +3 -3
- package/app/README.md +6 -2
- package/dist/src/access-control.js +23 -20
- package/dist/src/access-control.js.map +1 -1
- package/dist/src/access-dashboard.js +8 -2
- package/dist/src/access-dashboard.js.map +1 -1
- package/dist/src/cli/instances.js +87 -14
- package/dist/src/cli/instances.js.map +1 -1
- package/dist/src/cli/starmux-status.js +122 -0
- package/dist/src/cli/starmux-status.js.map +1 -0
- package/dist/src/cli/starmux.js +222 -49
- package/dist/src/cli/starmux.js.map +1 -1
- package/dist/src/deny-dashboard.js +2 -2
- package/dist/src/deny-dashboard.js.map +1 -1
- package/dist/src/instance-runtime.js +11 -2
- package/dist/src/instance-runtime.js.map +1 -1
- package/dist/src/instance-store.js +3 -1
- package/dist/src/instance-store.js.map +1 -1
- package/dist/src/ops-dashboard.js +4 -4
- package/dist/src/ops-dashboard.js.map +1 -1
- package/dist/src/permissions-dashboard.js +2 -2
- package/dist/src/permissions-dashboard.js.map +1 -1
- package/dist/src/starmux-migration.js +1 -1
- package/dist/src/starmux-migration.js.map +1 -1
- package/docs/ACCESS_CONTROL.md +5 -5
- package/docs/CLIENTS.md +11 -19
- package/docs/CONNECT_CHATGPT.md +4 -6
- package/docs/INSTALL.md +9 -5
- package/docs/INSTANCES.md +5 -2
- package/docs/OAUTH.md +6 -14
- package/docs/PLATFORMS.md +4 -4
- package/docs/README.md +2 -11
- package/docs/REMOTE_SETUP.md +13 -13
- package/docs/SECURITY.md +5 -5
- package/docs/assets/starmux-app-en.png +0 -0
- package/docs/assets/starmux-architecture.svg +315 -0
- package/package.json +1 -1
- package/docs/ARCHITECTURE.md +0 -51
- package/docs/MIGRATION.md +0 -37
- package/docs/RELEASE_STATUS.md +0 -22
- package/docs/TYPESCRIPT_MIGRATION.md +0 -56
- package/docs/VALIDATION_OAUTH.md +0 -79
- package/docs/VALIDATION_TUNNEL.md +0 -39
- package/docs/VALIDATION_WORKBUDDY.md +0 -59
- package/docs/assets/mcp-connection-route.svg +0 -104
- package/docs/assets/mcp-gateway-simple.svg +0 -62
package/docs/VALIDATION_OAUTH.md
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# OAuth validation archive
|
|
2
|
-
|
|
3
|
-
Historical investigation notes. For current setup, see [OAuth](OAUTH.md).
|
|
4
|
-
|
|
5
|
-
## Historical acceptance checkpoints
|
|
6
|
-
|
|
7
|
-
The following entries preserve the investigation chronology. Statements such as “pending” describe that checkpoint only; use the current result and checklist above for present status.
|
|
8
|
-
|
|
9
|
-
### Remote acceptance deployment checkpoint (2026-10-22)
|
|
10
|
-
|
|
11
|
-
A separate macOS acceptance deployment now uses Keycloak 26.8.1 with PostgreSQL 17, a public IPv6 HTTPS ingress, and an OAuth-only Core. This is an infrastructure checkpoint, **not a passed ChatGPT end-to-end acceptance**.
|
|
12
|
-
|
|
13
|
-
Verified on the deployment host:
|
|
14
|
-
|
|
15
|
-
- The public issuer discovery document returns HTTP 200 with normal TLS certificate verification.
|
|
16
|
-
- The Core returns HTTP 401 without a bearer token; protected-resource metadata remains discoverable.
|
|
17
|
-
- The official tunnel-client 0.0.16 reports OAuth discovery complete and ten OAuth targets automatically registered.
|
|
18
|
-
- A real ChatGPT Tunnel connector now automatically discovers the authorization URL, tunneled token endpoint, resource and `gateway:access` scope. The pre-registered client configuration has been prepared; secret submission and login/consent are pending.
|
|
19
|
-
- The existing API-key Core uses a separate port and access store.
|
|
20
|
-
|
|
21
|
-
Operational findings:
|
|
22
|
-
|
|
23
|
-
- Local Fake-IP DNS can break issuer discovery even when direct IPv6 HTTPS works. Correct the deployment host's resolution for the issuer without disabling TLS verification. A host mapping must be updated when the public IPv6 changes.
|
|
24
|
-
- In tunnel-client 0.0.16, trusting an issuer for discovery does not automatically allow registration of its HTTP callout targets. The original loopback MCP URL plus public resource/issuer origin produced `private-host-registration-disabled`. Generic manually configured targets also lacked the OAuth categories/tags used by discovery. The verified fix was to point the tunnel at the same-origin HTTPS MCP endpoint served by the local proxy. The proxy still forwards MCP to the loopback-only Core. Ten typed OAuth targets were then auto-registered, and ChatGPT discovery succeeded. Temporary generic targets and hostname-classification overrides were removed.
|
|
25
|
-
- The HTTPS proxy and valid issuer hostname resolution are now dependencies of the local Tunnel route. This does not require the ChatGPT backend to reach the host over public IPv6: MCP and registered token callouts still traverse the outbound tunnel. Browser login remains a direct HTTPS navigation to the issuer.
|
|
26
|
-
- The final same-origin HTTPS configuration does not enable `--harpoon.allow-plaintext-http`. Keep auto-registered OAuth endpoints behind the narrow proxy allowlist; do not expose authorization-server administration.
|
|
27
|
-
- Run the acceptance Core and authorization server independently of disposable debugging terminals. The test jobs are manually bootstrapped into the current login session, with private logs and no automatic login installation. PostgreSQL data persists; the HTTPS proxy still needs its privileged process to remain running.
|
|
28
|
-
- Keep client secrets, owner credentials, database passwords, access stores, deployment-specific launchers and logs outside the repository.
|
|
29
|
-
|
|
30
|
-
Still required: client-secret submission, login and consent with the exact current callback, token exchange, authenticated tool discovery and a controlled coding call, followed by revocation rejection. A callback displayed in the configuration dialog is not evidence that the authorization redirect has succeeded.
|
|
31
|
-
|
|
32
|
-
Reference: [tunnel-client 0.0.16 configuration](https://github.com/openai/tunnel-client/blob/v0.0.16/docs/configuration.md), including OAuth shim rewriting and Harpoon OAuth target metadata.
|
|
33
|
-
|
|
34
|
-
### Login and token exchange checkpoint
|
|
35
|
-
|
|
36
|
-
The real ChatGPT authorization request used the configured client, exact registered callback, `gateway:access`, and PKCE S256. Owner login and explicit consent completed, and the browser returned to ChatGPT. Client-secret authentication reached Keycloak successfully. This proves the login/callback path, not a usable MCP authorization.
|
|
37
|
-
|
|
38
|
-
The first code-to-token exchange returned HTTP 400: Keycloak reported an invalid/unknown requested resource. ChatGPT's Tunnel discovery had replaced the resource with the exact Tunnel MCP URL; the reference realm knew only the canonical Gateway resource. The deployment now registers that exact Tunnel resource as an additional bearer-only resource client. Core issuer/audience validation remains enabled and unchanged. Successful token exchange and the resulting token audience still need verification; registering a resource alone is not proof of acceptance.
|
|
39
|
-
|
|
40
|
-
Keycloak's default user profile also required an email even though this deployment does not use OIDC email claims. The deployment made email optional instead of inventing a user email. The previous profile configuration was backed up privately.
|
|
41
|
-
|
|
42
|
-
After the failed exchange, ChatGPT's association button remained disabled. The failed plugin installation was removed while preserving its definition and OAuth settings. Reinstallation through the browser remains pending; do not report the plugin as connected until that succeeds. No credential values or authorization codes are recorded here.
|
|
43
|
-
|
|
44
|
-
### Tunnel resource aliases and successful association (2026-10-22)
|
|
45
|
-
|
|
46
|
-
Keycloak 26.8.1's `ResourceIndicatorsPostProcessor` first checks that the requested resource matches an audience granted to the client. Registering a resource client alone is insufficient: add an audience mapper for that resource to the granted scope. It then narrows the token audience to the requested resource URL. The Tunnel shim supplies a different resource URL from the canonical HTTPS endpoint.
|
|
47
|
-
|
|
48
|
-
Core now supports an optional `oauth.resourceAliases` array in the private access configuration: at most eight exact HTTPS resource URLs identifying this same Gateway. Owners must explicitly configure these identifiers; they are never derived from request headers or automatically trusted from discovery. Issuer, signature, client, subject, scope, lifetime and session revocation checks still apply. Protected-resource metadata continues to advertise the canonical resource. Do not add arbitrary service audiences or wildcard hosts. Removing an alias immediately rejects tokens addressed only to that alias.
|
|
49
|
-
|
|
50
|
-
The deployment added an exact Tunnel audience mapper and the matching Core resource alias. Reinstallation of the existing ChatGPT plugin then succeeded without changing the callback. The page now offers “Try in chat”, and Core recorded real `verified-oauth` requests. This proves token exchange and authenticated MCP initialization/discovery; coding and revocation acceptance are tracked separately below.
|
|
51
|
-
|
|
52
|
-
Regression coverage checks default rejection of an unconfigured alias, explicit acceptance, rejection of a neighboring URL, wrong issuer/subject/scope, and rejection after alias removal. Build and the OAuth integration fixture pass.
|
|
53
|
-
|
|
54
|
-
Source: [Keycloak resource indicator processing](https://github.com/keycloak/keycloak/blob/26.8.1/services/src/main/java/org/keycloak/protocol/oidc/resourceindicators/ResourceIndicatorsPostProcessor.java).
|
|
55
|
-
|
|
56
|
-
### Acceptance boundary and network dependency
|
|
57
|
-
|
|
58
|
-
The ChatGPT settings page confirms a connected account using OAuth. The OAuth connector is now independently exposed to the agent, but its first real `health_check` attempt failed before reaching Core: the Tunnel could not complete a token-endpoint call after the host's global IPv6 connectivity was disabled. Keycloak remained healthy on loopback, while the canonical HTTPS issuer was unreachable. This is distinct from the earlier audience mismatch. Do not count this attempt as a successful coding or refresh test.
|
|
59
|
-
|
|
60
|
-
For this IPv6-hosted deployment, keep the issuer reachable from both the user's login browser and the local Tunnel/Core. An outbound Tunnel does not remove the local dependency on the configured HTTPS issuer. If the host address changes, update the proxy bind address, DNS and any local host mapping together; never disable TLS verification to compensate. An IPv4-only deployment instead needs a reachable HTTPS authorization endpoint or a separately designed local HTTPS route.
|
|
61
|
-
|
|
62
|
-
The full `npm test` suite passed after the resource-alias change, including all 20 Node test-runner tests plus the preceding compatibility scripts. Real connector file read/write, process execution, token refresh and remote revocation rejection remain pending.
|
|
63
|
-
|
|
64
|
-
### Real ChatGPT coding and revocation acceptance (2026-10-22 UTC)
|
|
65
|
-
|
|
66
|
-
After IPv6 was restored, the HTTPS issuer returned 200 and the previously configured address was present again. The earlier idle session's refresh token had expired (`Token is not active`); signing in again with the unchanged callback restored the association.
|
|
67
|
-
|
|
68
|
-
A fresh ChatGPT web conversation using only the OAuth plugin completed:
|
|
69
|
-
|
|
70
|
-
- `health_check`, followed by genuine Desktop Commander calls under a new `verified-oauth` connection.
|
|
71
|
-
- `create_directory`, `write_file`, and `read_file` in a dedicated Downloads acceptance directory.
|
|
72
|
-
- `start_process` running the written Python file. Desktop Commander's recorded output contained `GATEWAY_OAUTH_OK_20261022` and process completion. The file was independently checked locally; the local executor did not create or run it as a substitute for the connector.
|
|
73
|
-
- CLI revocation of that exact connection. Subsequent real `tools/call` and `initialize` requests returned HTTP 401. Token-endpoint calls still returned 200, but did not restore access to the revoked session. ChatGPT displayed a reconnect prompt.
|
|
74
|
-
|
|
75
|
-
Evidence was correlated between Core request IDs/`verified-oauth` audit entries, Desktop Commander's per-tool history and Tunnel status codes. No bearer tokens, secrets or private login data are included here. The coding sequence ran at approximately 18:33 UTC, and revocation rejection at 18:34 UTC.
|
|
76
|
-
|
|
77
|
-
Observed limitations: the interactive shell printed Homebrew initialization warnings before successfully executing Python; ChatGPT's final answer/app rendering also displayed loading failures even though the tool calls completed. These UI/environment issues must not be confused with failed tool execution or treated as resolved. Long-idle refresh expiry is expected to require a new login; unattended long-duration session behavior has not been accepted as a release guarantee.
|
|
78
|
-
|
|
79
|
-
Restoration checkpoint (2026-10-23 03:25 UTC): after the interrupted acceptance run, a fresh login using the unchanged callback created a new session. ChatGPT web successfully called `health_check`; Core recorded `verified-oauth` and `DC_BRIDGE_HEALTH_CHECK` with the same request ID. The earlier revoked session remains revoked. The plugin was restored by reauthentication, without undoing the revocation or relaxing access checks. The current Codex thread's dynamically loaded tool handle remained stale after plugin reinstallation, so restoration was verified through the actual ChatGPT web client and Core audit evidence rather than that handle.
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Local Mac via official OpenAI Tunnel: coding acceptance
|
|
2
|
-
|
|
3
|
-
Date: 2026-10-21. Source commit: `be6ed18` (before this report).
|
|
4
|
-
|
|
5
|
-
## Verified path
|
|
6
|
-
|
|
7
|
-
Codex Mac MCP Gateway plugin → existing official OpenAI Tunnel → local loopback port 8793 → current checkout compiled TypeScript Core → Desktop Commander.
|
|
8
|
-
|
|
9
|
-
The existing tunnel targeted port 8793; the saved onboarding profile targeted 18893. Starting the onboarding Core alone did not make the plugin available. The current checkout CLI was then started with `run --profile live`, selecting the existing port configuration while still running the Core from this checkout. No tunnel credentials or network configuration were changed.
|
|
10
|
-
|
|
11
|
-
Runtime identity:
|
|
12
|
-
|
|
13
|
-
- Core: `dist/src/dc-workspace-http.js` in this checkout.
|
|
14
|
-
- Version: 0.9.0; startup digest: `83ba2a27930bdb2d`.
|
|
15
|
-
- Access mode: ingress; workspace read-write; write scope home-only.
|
|
16
|
-
- Developer commands: trusted-project; native access enabled.
|
|
17
|
-
- Plugin health: Desktop Commander upstream healthy, 25 upstream tools discovered.
|
|
18
|
-
|
|
19
|
-
## Actual plugin operations
|
|
20
|
-
|
|
21
|
-
All project creation, source writes, code editing, reads and test execution below used the Mac MCP Gateway plugin, not local terminal substitutions.
|
|
22
|
-
|
|
23
|
-
1. Create an isolated directory under the checkout's ignored `tmp/` directory.
|
|
24
|
-
2. Write a TypeScript basket-total function and three Node tests.
|
|
25
|
-
3. Execute tests with a deliberately incorrect quantity calculation: one passes, two fail with the expected assertions.
|
|
26
|
-
4. Edit the calculation through `edit_block` to multiply price by quantity.
|
|
27
|
-
5. Read the source back through `read_file` to confirm the edit.
|
|
28
|
-
6. Execute tests again: **3 pass, 0 fail**.
|
|
29
|
-
|
|
30
|
-
The test used Node's local TypeScript support. This is a coding workflow test, not a replacement for Gateway's compiled-JavaScript package tests.
|
|
31
|
-
|
|
32
|
-
## Observations and limits
|
|
33
|
-
|
|
34
|
-
- Default zsh startup emitted a Homebrew initialization warning including a denied `/dev/null` operation. Tests still executed. Explicit `/bin/sh` and the absolute Node executable produced a clean passing run; shell initialization compatibility remains a separate issue.
|
|
35
|
-
- One `start_process` request returned a Tunnel network error. A subsequent read worked; repeating the side-effect-free tests succeeded. No exactly-once or sustained network reliability claim is made.
|
|
36
|
-
- This verifies the installed plugin over an existing Tunnel in ingress mode. It does **not** verify ChatGPT web OAuth discovery, consent, refresh or revocation through that Tunnel.
|
|
37
|
-
- No public HTTPS listener, IPv6 ingress, DNS or TLS certificate was configured or tested.
|
|
38
|
-
- No OAuth mode switch or user permission expansion was made.
|
|
39
|
-
- Temporary example files remain under ignored `tmp/tunnel-coding-20261021-1420/` for inspection. They are not shipped or committed.
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# WorkBuddy API-key acceptance over HTTPS and IPv6
|
|
2
|
-
|
|
3
|
-
Date: 2026-10-21. Client: WorkBuddy 5.8.3 on macOS.
|
|
4
|
-
|
|
5
|
-
## Initial same-host result (2026-10-21)
|
|
6
|
-
|
|
7
|
-
WorkBuddy loaded a custom Streamable HTTP MCP configuration with an Authorization Bearer header, initialized the Gateway over HTTPS, and discovered 27 tools. Its own daemon log recorded HTTP 200 and `connection-ready` with 27 tools. An authenticated GET returned 405 because this Core does not offer a standalone SSE stream; initialization and discovery still completed successfully.
|
|
8
|
-
|
|
9
|
-
The test used a domain with only an AAAA record pointing at this Mac, an existing valid Let's Encrypt certificate, and Caddy bound to the Mac's global IPv6 address on port 8443. Port 443 was unavailable to the unprivileged process. Certificate validation was enabled. Only `/mcp` was forwarded to an isolated loopback Core on port 18894; `/dashboard` returned 404.
|
|
10
|
-
|
|
11
|
-
The existing Tunnel Core on port 8793 and its ingress authentication mode were not changed.
|
|
12
|
-
|
|
13
|
-
## Client configuration shape
|
|
14
|
-
|
|
15
|
-
```json
|
|
16
|
-
{
|
|
17
|
-
"mcpServers": {
|
|
18
|
-
"mac-mcp-gateway-ipv6": {
|
|
19
|
-
"type": "streamable-http",
|
|
20
|
-
"url": "https://YOUR_DOMAIN:8443/mcp",
|
|
21
|
-
"headers": { "Authorization": "Bearer YOUR_GATEWAY_KEY" }
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
The real credential was written directly to the user-authorized WorkBuddy configuration file with mode 0600, never committed. Server authentication state is stored separately in a private validation directory; Gateway stores credential hashes. Reload/restart the client after externally editing its configuration, and follow any client-side approval prompt.
|
|
28
|
-
|
|
29
|
-
## Authentication checks
|
|
30
|
-
|
|
31
|
-
- No key: HTTP 401.
|
|
32
|
-
- Incorrect key: HTTP 401.
|
|
33
|
-
- WorkBuddy key: HTTP 200 and 27 tools.
|
|
34
|
-
- Separate temporary key before revocation: HTTP 200.
|
|
35
|
-
- Same temporary key after revocation: HTTP 401.
|
|
36
|
-
- WorkBuddy key after revoking the temporary key: still HTTP 200.
|
|
37
|
-
- TLS verification: passed; actual peer was the Mac's global IPv6 address.
|
|
38
|
-
|
|
39
|
-
## Limits of the initial same-host test
|
|
40
|
-
|
|
41
|
-
The client and server ran on the same Mac. This validates real WorkBuddy protocol/credential compatibility and HTTPS over the host's global IPv6 address, but does not prove external router/firewall reachability from another network. No WorkBuddy AI programming task, reboot persistence, token expiry, OAuth, or unattended certificate renewal was tested in this pass. The test Core and HTTPS proxy are foreground processes, not installed login services. The proxy uses the existing certificate explicitly; this setup is not a permanent certificate-renewal deployment.
|
|
42
|
-
|
|
43
|
-
## Remote-host follow-up (2026-10-22)
|
|
44
|
-
|
|
45
|
-
The owner subsequently tested WorkBuddy from a remote host over public IPv6 and HTTPS. For this follow-up, the owner started the CLI with the dedicated API-key access store and `--profile live` on port 8793, then changed Caddy's upstream and upstream Host header to `127.0.0.1:8793`. This differs from the initial isolated port-18894 test above. Other clients targeting port 8793 now also require a valid key.
|
|
46
|
-
|
|
47
|
-
Evidence and scope:
|
|
48
|
-
|
|
49
|
-
- Owner-reported remote network test; supplied screenshot shows the Gateway connected, 27/27 tools enabled and two Desktop Commander resources discovered.
|
|
50
|
-
- Owner-supplied remote WorkBuddy transcript reports successful `health_check`, with trace ID `5fb9bd4b-139a-4947-a458-d577ad13069f`.
|
|
51
|
-
- The transcript reports reading a 48-line Markdown document from the server Mac's Downloads directory and summarizing it, using only the Gateway connector.
|
|
52
|
-
- The transcript reports writing a 32-line story to the server Mac's Downloads directory, using only the Gateway connector.
|
|
53
|
-
- Independently inspected the resulting `~/Downloads/story.txt` on the server Mac: 1,844 bytes, 32 lines, modified at 2026-10-22 01:19:58 +08:00. Its title and content match the reported lighthouse story. The inspecting agent did not create or modify that file.
|
|
54
|
-
|
|
55
|
-
Conclusion: the owner reports successful remote HTTPS/IPv6/API-key connection and actual file reading/writing; the written artifact is independently confirmed on the server. The inspecting agent did not capture the remote client's network traffic or independently replay its remote read call. No credentials, personal document contents, or story contents are included in this report.
|
|
56
|
-
|
|
57
|
-
Tool-count clarification: the route health result reports 25 upstream tools; the screenshot shows 27 total tools including Gateway tools. The transcript's manually grouped list of 26 omits `list_sessions`; it is not evidence of a routing failure.
|
|
58
|
-
|
|
59
|
-
Remaining acceptance: a remote WorkBuddy edit-and-execute coding workflow, external-client revocation behavior, restart persistence, OAuth, and sustained service operation. Remote file reading/writing does not by itself establish terminal execution or completion of the OAuth roadmap.
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="450" viewBox="0 0 1200 450" role="img" aria-labelledby="title description">
|
|
2
|
-
<title id="title">Starmux: two remote connection routes to one local MCP server</title>
|
|
3
|
-
<desc id="description">Two explicit routes are shown in parallel. Preferred Direct HTTPS: ChatGPT connects to the owner's DNS name, authenticated HTTPS reverse proxy and single Gateway Core. Alternative Secure MCP Tunnel: ChatGPT uses an OpenAI-hosted Tunnel with an outbound client on the Mac. Both routes reach the same Gateway, which forwards MCP calls to the real local Desktop Commander server. Architecture only; external authorization tests remain pending.</desc>
|
|
4
|
-
<defs>
|
|
5
|
-
<linearGradient id="background" x1="0" y1="0" x2="1" y2="1">
|
|
6
|
-
<stop stop-color="#111728"/><stop offset=".57" stop-color="#17233b"/><stop offset="1" stop-color="#0c2631"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="direct" x1="0" y1="0" x2="1" y2="1">
|
|
9
|
-
<stop stop-color="#183b43"/><stop offset="1" stop-color="#153045"/>
|
|
10
|
-
</linearGradient>
|
|
11
|
-
<linearGradient id="tunnel" x1="0" y1="0" x2="1" y2="1">
|
|
12
|
-
<stop stop-color="#292849"/><stop offset="1" stop-color="#1c3151"/>
|
|
13
|
-
</linearGradient>
|
|
14
|
-
<linearGradient id="gateway" x1="0" y1="0" x2="1" y2="1">
|
|
15
|
-
<stop stop-color="#253b60"/><stop offset="1" stop-color="#1a2e4b"/>
|
|
16
|
-
</linearGradient>
|
|
17
|
-
<marker id="arrowGreen" markerWidth="7" markerHeight="7" refX="5.6" refY="3.5" orient="auto">
|
|
18
|
-
<path d="M1 1 L5.7 3.5 L1 6" stroke="#5cddc3" stroke-width="1.8" stroke-linejoin="round" fill="none"/>
|
|
19
|
-
</marker>
|
|
20
|
-
<marker id="arrowBlue" markerWidth="7" markerHeight="7" refX="5.6" refY="3.5" orient="auto">
|
|
21
|
-
<path d="M1 1 L5.7 3.5 L1 6" stroke="#82a9ff" stroke-width="1.8" stroke-linejoin="round" fill="none"/>
|
|
22
|
-
</marker>
|
|
23
|
-
</defs>
|
|
24
|
-
|
|
25
|
-
<rect width="1200" height="450" rx="22" fill="url(#background)"/>
|
|
26
|
-
<rect x="1" y="1" width="1198" height="448" rx="21" fill="none" stroke="#4c607b" stroke-opacity=".68"/>
|
|
27
|
-
<g font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif">
|
|
28
|
-
<text x="34" y="45" fill="#f7fbff" font-size="25" font-weight="750">Two ways to reach your Mac. One Gateway you control.</text>
|
|
29
|
-
<text x="34" y="73" fill="#a5bbd1" font-size="14">Both options use the real local Desktop Commander MCP server — no reimplementation of its tools.</text>
|
|
30
|
-
</g>
|
|
31
|
-
|
|
32
|
-
<!-- One AI client, two explicit paths, one gateway -->
|
|
33
|
-
<g fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
34
|
-
<path d="M234 232 H265 V167 H293" stroke="#5cddc3" stroke-width="2.5" marker-end="url(#arrowGreen)"/>
|
|
35
|
-
<path d="M265 232 V312 H293" stroke="#82a9ff" stroke-width="2.5" marker-end="url(#arrowBlue)"/>
|
|
36
|
-
<path d="M773 167 H800 V232 H823" stroke="#5cddc3" stroke-width="2.5" marker-end="url(#arrowGreen)"/>
|
|
37
|
-
<path d="M773 312 H800 V232" stroke="#82a9ff" stroke-width="2.5"/>
|
|
38
|
-
<path d="M995 232 H1029" stroke="#55cde6" stroke-width="2.7" marker-end="url(#arrowBlue)"/>
|
|
39
|
-
</g>
|
|
40
|
-
<circle cx="265" cy="232" r="4" fill="#b3caff"/>
|
|
41
|
-
<circle cx="800" cy="232" r="4" fill="#b3caff"/>
|
|
42
|
-
|
|
43
|
-
<!-- Source AI client -->
|
|
44
|
-
<rect x="34" y="168" width="200" height="128" rx="17" fill="#29233e" stroke="#7560b0" stroke-opacity=".8"/>
|
|
45
|
-
<g font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" text-anchor="middle">
|
|
46
|
-
<circle cx="134" cy="203" r="19" fill="#9f81f7" fill-opacity=".15"/>
|
|
47
|
-
<path d="M125 194 h17 a5 5 0 0 1 5 5 v9 h-10 l-6 6 v-6 h-6 a5 5 0 0 1 -5 -5 v-4 a5 5 0 0 1 5 -5" stroke="#b496ff" stroke-width="2.2" fill="none"/>
|
|
48
|
-
<text x="134" y="251" font-size="21" font-weight="730" fill="#f7f4ff">ChatGPT</text>
|
|
49
|
-
<text x="134" y="274" font-size="12" fill="#c4b7e0">Remote MCP client</text>
|
|
50
|
-
</g>
|
|
51
|
-
|
|
52
|
-
<!-- Primary route: direct HTTPS -->
|
|
53
|
-
<rect x="295" y="105" width="478" height="125" rx="15" fill="url(#direct)" stroke="#50c9b2" stroke-width="1.8"/>
|
|
54
|
-
<rect x="316" y="123" width="125" height="23" rx="11.5" fill="#245749" stroke="#49c5a5" stroke-opacity=".55"/>
|
|
55
|
-
<text x="378" y="139" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-weight="750" font-size="12" fill="#b6ffe6">01 · PREFERRED</text>
|
|
56
|
-
<text x="454" y="140" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-weight="730" font-size="18" fill="#f3fefd">Direct HTTPS</text>
|
|
57
|
-
<text x="317" y="176" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-size="16" fill="#d8f6ee">DNS A / AAAA → TLS :443 → Auth</text>
|
|
58
|
-
<text x="317" y="201" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-size="13" fill="#94d9c8">Your reachable IP · your domain · your proxy</text>
|
|
59
|
-
<g transform="translate(725 125)" fill="none" stroke="#6de0c6" stroke-width="2.2">
|
|
60
|
-
<path d="M0 10 v-5 a7 7 0 0 1 14 0 v5"/><rect x="-3" y="10" width="20" height="17" rx="3"/>
|
|
61
|
-
<circle cx="7" cy="17" r="1.6" fill="#6de0c6"/><path d="M7 18 v4"/>
|
|
62
|
-
</g>
|
|
63
|
-
|
|
64
|
-
<!-- Secondary route: OpenAI Tunnel -->
|
|
65
|
-
<rect x="295" y="250" width="478" height="125" rx="15" fill="url(#tunnel)" stroke="#637fc4" stroke-width="1.7"/>
|
|
66
|
-
<rect x="316" y="268" width="137" height="23" rx="11.5" fill="#304375" stroke="#7f98e5" stroke-opacity=".65"/>
|
|
67
|
-
<text x="384.5" y="284" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-weight="730" font-size="12" fill="#bed0ff">02 · ALTERNATIVE</text>
|
|
68
|
-
<text x="467" y="285" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-weight="730" font-size="18" fill="#f0f3ff">Secure MCP Tunnel</text>
|
|
69
|
-
<text x="317" y="320" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-size="16" fill="#d7e6ff">OpenAI Tunnel ↔ outbound tunnel-client</text>
|
|
70
|
-
<text x="317" y="345" font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" font-size="13" fill="#a5b7e3">No inbound router port · OpenAI relay required</text>
|
|
71
|
-
<g transform="translate(728 276)" stroke="#97b6ff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" fill="none">
|
|
72
|
-
<path d="M-2 6 h20 m-5 -5 l5 5 -5 5 M18 18 h-20 m5 -5 l-5 5 5 5"/>
|
|
73
|
-
</g>
|
|
74
|
-
|
|
75
|
-
<!-- Single local gateway -->
|
|
76
|
-
<rect x="824" y="168" width="171" height="128" rx="17" fill="url(#gateway)" stroke="#6589dc" stroke-width="1.8"/>
|
|
77
|
-
<g font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" text-anchor="middle">
|
|
78
|
-
<circle cx="910" cy="203" r="18" fill="#73b4f8" fill-opacity=".15"/>
|
|
79
|
-
<g stroke="#a5d6ff" fill="none" stroke-width="2">
|
|
80
|
-
<circle cx="901" cy="198" r="3"/><circle cx="920" cy="198" r="3"/><circle cx="910" cy="213" r="3"/>
|
|
81
|
-
<path d="M904 201 l4 9 m9 -9 l-4 9 m-9 -12 h13"/>
|
|
82
|
-
</g>
|
|
83
|
-
<text x="910" y="251" font-size="17" font-weight="730" fill="#eff7ff">Mac MCP</text>
|
|
84
|
-
<text x="910" y="272" font-size="17" font-weight="730" fill="#eff7ff">Gateway</text>
|
|
85
|
-
<text x="910" y="286" font-size="10" fill="#a8cbed">One local Core</text>
|
|
86
|
-
</g>
|
|
87
|
-
|
|
88
|
-
<!-- Real upstream server -->
|
|
89
|
-
<rect x="1032" y="168" width="145" height="128" rx="17" fill="#13343b" stroke="#54a7b8" stroke-width="1.6"/>
|
|
90
|
-
<g font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif" text-anchor="middle">
|
|
91
|
-
<rect x="1089" y="189" width="30" height="29" rx="4" fill="#5ac1cf" fill-opacity=".12" stroke="#6fdee3" stroke-width="1.8"/>
|
|
92
|
-
<path d="M1095 198 h18 M1095 205 h18 M1095 212 h10" stroke="#6fdee3" stroke-width="1.7"/>
|
|
93
|
-
<text x="1104.5" y="248" font-size="16" font-weight="720" fill="#efffff">Desktop</text>
|
|
94
|
-
<text x="1104.5" y="269" font-size="16" font-weight="720" fill="#efffff">Commander</text>
|
|
95
|
-
<text x="1104.5" y="286" font-size="10.5" fill="#aad2d6">Actual MCP tools</text>
|
|
96
|
-
</g>
|
|
97
|
-
|
|
98
|
-
<!-- Explanatory footer -->
|
|
99
|
-
<path d="M34 405 H1177" stroke="#426078" stroke-opacity=".6"/>
|
|
100
|
-
<g font-family="-apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif">
|
|
101
|
-
<circle cx="42" cy="423" r="4.5" fill="#5cddc3"/>
|
|
102
|
-
<text x="56" y="428" font-size="13" fill="#c2dce8">Both routes reach the same self-hosted Core. External authentication and reachability must be verified separately.</text>
|
|
103
|
-
</g>
|
|
104
|
-
</svg>
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="405" viewBox="0 0 1200 405" role="img" aria-labelledby="title desc">
|
|
2
|
-
<title id="title">Starmux: remote AI clients connect to real Mac tools</title>
|
|
3
|
-
<desc id="desc">One clear flow: compatible remote AI clients, such as ChatGPT, connect over authenticated Direct HTTPS or OpenAI Secure MCP Tunnel to a self-hosted Starmux, which routes approved MCP tool requests to the real Desktop Commander MCP server on that Mac.</desc>
|
|
4
|
-
<defs>
|
|
5
|
-
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#111629"/><stop offset="1" stop-color="#0d2432"/></linearGradient>
|
|
6
|
-
<linearGradient id="cardPurple" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#29223f"/><stop offset="1" stop-color="#201e3c"/></linearGradient>
|
|
7
|
-
<linearGradient id="cardNavy" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#263456"/><stop offset="1" stop-color="#1b2c4a"/></linearGradient>
|
|
8
|
-
<linearGradient id="cardTeal" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#173941"/><stop offset="1" stop-color="#17313b"/></linearGradient>
|
|
9
|
-
<marker id="arrow" markerWidth="7" markerHeight="7" refX="5.5" refY="3.5" orient="auto"><path d="M1 1 L5.8 3.5 L1 6" stroke="#69b5fa" stroke-width="1.8" stroke-linecap="round" fill="none"/></marker>
|
|
10
|
-
</defs>
|
|
11
|
-
<rect x="0" y="0" width="1200" height="405" rx="22" fill="url(#bg)"/>
|
|
12
|
-
<rect x="1" y="1" width="1198" height="403" rx="21" fill="none" stroke="#405675" stroke-opacity=".7"/>
|
|
13
|
-
<g font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif">
|
|
14
|
-
<text x="36" y="47" font-weight="740" font-size="27" fill="#f7fbff">Your AI. Your Mac. Your tools.</text>
|
|
15
|
-
<text x="36" y="76" font-size="15" fill="#a6bed5">Authorized remote MCP calls reach real files, Git and Shell on the Mac you control.</text>
|
|
16
|
-
<!-- Mac region: Gateway and its real upstream remain on the machine -->
|
|
17
|
-
<rect x="588" y="117" width="580" height="214" rx="20" fill="#2b4765" fill-opacity=".13" stroke="#648aac" stroke-opacity=".48" stroke-dasharray="5 6"/>
|
|
18
|
-
<text x="606" y="140" font-weight="750" font-size="11" letter-spacing="1.4" fill="#8fbad8">ON YOUR MAC</text>
|
|
19
|
-
<!-- Client card -->
|
|
20
|
-
<rect x="36" y="157" width="224" height="157" rx="16" fill="url(#cardPurple)" stroke="#63558d"/>
|
|
21
|
-
<g transform="translate(131 175)" fill="none" stroke="#b49aff" stroke-width="2.5" stroke-linejoin="round"><rect width="35" height="25" x="-16" y="0" rx="5"/><path d="M-6 25 v7 l9 -7"/></g>
|
|
22
|
-
<text x="148" y="230" fill="#f5f2fe" font-size="19" font-weight="730" text-anchor="middle">Remote AI client</text>
|
|
23
|
-
<text x="148" y="256" fill="#c1b5de" font-size="14" text-anchor="middle">ChatGPT web</text>
|
|
24
|
-
<text x="148" y="277" fill="#a99fc8" font-size="12.5" text-anchor="middle">or compatible MCP client</text>
|
|
25
|
-
<!-- Connectivity card -->
|
|
26
|
-
<rect x="298" y="157" width="252" height="157" rx="16" fill="#1b2941" stroke="#4d7095"/>
|
|
27
|
-
<text x="424" y="186" fill="#e2efff" font-size="17" font-weight="740" text-anchor="middle">Your connection</text>
|
|
28
|
-
<rect x="316" y="200" width="216" height="43" rx="10" fill="#1b4a47" stroke="#41bda0" stroke-opacity=".8"/>
|
|
29
|
-
<circle cx="333" cy="221" r="5.5" fill="#56e1bd"/>
|
|
30
|
-
<text x="351" y="226" fill="#d9fff5" font-size="15" font-weight="720">Direct HTTPS</text>
|
|
31
|
-
<text x="521" y="225" fill="#99d9c8" font-size="10" text-anchor="end">PREFERRED</text>
|
|
32
|
-
<rect x="316" y="252" width="216" height="43" rx="10" fill="#292c53" stroke="#7584d6" stroke-opacity=".85"/>
|
|
33
|
-
<circle cx="333" cy="273" r="5.5" fill="#9a9dfc"/>
|
|
34
|
-
<text x="351" y="278" fill="#ecebff" font-size="15" font-weight="720">Secure Tunnel</text>
|
|
35
|
-
<!-- Gateway card -->
|
|
36
|
-
<rect x="606" y="157" width="259" height="157" rx="16" fill="url(#cardNavy)" stroke="#7095dd" stroke-width="1.5"/>
|
|
37
|
-
<g transform="translate(719 178)" stroke="#9acaff" stroke-width="2.5" fill="none"><circle cx="0" cy="0" r="5"/><circle cx="22" cy="0" r="5"/><circle cx="11" cy="23" r="5"/><path d="M5 3 l4 15 M17 3 l-4 15 M6 0 h10"/></g>
|
|
38
|
-
<text x="735" y="239" fill="#f5f9ff" font-weight="760" font-size="20" text-anchor="middle">Starmux</text>
|
|
39
|
-
<text x="735" y="265" fill="#bdd5ef" font-size="13.5" text-anchor="middle">Self-hosted entry point</text>
|
|
40
|
-
<text x="735" y="287" fill="#91b1d8" font-size="12.5" text-anchor="middle">Access + routing</text>
|
|
41
|
-
<!-- Upstream card -->
|
|
42
|
-
<rect x="904" y="157" width="245" height="157" rx="16" fill="url(#cardTeal)" stroke="#52a6b2" stroke-width="1.5"/>
|
|
43
|
-
<rect x="1009" y="178" width="32" height="29" rx="5" fill="none" stroke="#70dfdf" stroke-width="2.5"/>
|
|
44
|
-
<path d="M1016 187 h18 M1016 193 h18 M1016 199 h10" fill="none" stroke="#70dfdf" stroke-width="2"/>
|
|
45
|
-
<text x="1026" y="239" fill="#eafaff" font-weight="750" font-size="18" text-anchor="middle">Desktop Commander</text>
|
|
46
|
-
<text x="1026" y="265" fill="#b9dce0" font-size="13.5" text-anchor="middle">Real MCP server</text>
|
|
47
|
-
<text x="1026" y="286" fill="#94c3c9" font-size="12.5" text-anchor="middle">Files · Git · Terminal</text>
|
|
48
|
-
<!-- Flow arrows -->
|
|
49
|
-
<g stroke="#69b5fa" stroke-width="2.7" stroke-linecap="round" fill="none">
|
|
50
|
-
<path d="M264 236 H291" marker-end="url(#arrow)"/>
|
|
51
|
-
<path d="M554 236 H599" marker-end="url(#arrow)"/>
|
|
52
|
-
<path d="M869 236 H897" marker-end="url(#arrow)"/>
|
|
53
|
-
</g>
|
|
54
|
-
<!-- Caveat, small and clear -->
|
|
55
|
-
<path d="M36 348 H1166" stroke="#4c6482" stroke-opacity=".5"/>
|
|
56
|
-
<circle cx="43" cy="369" r="5" fill="#5bddbd"/>
|
|
57
|
-
<text x="56" y="374" fill="#bad5e5" font-size="13">Direct HTTPS: your domain + authentication</text>
|
|
58
|
-
<circle cx="460" cy="369" r="5" fill="#9b9cf2"/>
|
|
59
|
-
<text x="473" y="374" fill="#bad5e5" font-size="13">Tunnel: uses OpenAI forwarding</text>
|
|
60
|
-
<text x="1160" y="374" fill="#799eb9" font-size="12.5" text-anchor="end">One Gateway · One Mac</text>
|
|
61
|
-
</g>
|
|
62
|
-
</svg>
|