@miruzero/zgpt 0.1.3 → 0.1.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Zero ChatGPT
2
2
 
3
- `M:\Zero_ChatGPT` is the standalone ChatGPT runtime and the only default owner of ChatGPT state.
3
+ `@miruzero/zgpt` is the standalone ChatGPT SDK and CLI package. `M:\Zero_ChatGPT` is the developer checkout path, **not** a module import path for npm users.
4
4
 
5
5
  ## Scope
6
6
 
@@ -12,9 +12,9 @@ This package contains only ChatGPT-specific runtime code:
12
12
  - ChatGPT connector operations
13
13
  - ChatGPT Web protocol mechanics
14
14
  - direct HTTP/SSE transport
15
- - ChatGPT mutable state under `M:\Zero_ChatGPT\state`
15
+ - ChatGPT mutable state in the runtime's configurable `state/` directory (`ZERO_CHATGPT_STATE_DIR`)
16
16
 
17
- It contains no Zero Core, MCP, Agent orchestration, CLI adapter, or generic device/task runtime.
17
+ It contains no Zero Core, MCP, Agent orchestration, or generic device/task runtime. The CLI is a thin adapter over the same public SDK exports.
18
18
 
19
19
  ## CLI
20
20
 
@@ -25,32 +25,133 @@ npm install -g @miruzero/zgpt@latest
25
25
  zgpt
26
26
  ```
27
27
 
28
- For a project-local installation, use `npx`:
28
+ For a project-local installation using the published package name:
29
29
 
30
30
  ```sh
31
31
  npm install @miruzero/zgpt@latest
32
32
  npx zgpt
33
33
  ```
34
34
 
35
+ If you want the **short JavaScript import** `require('zgpt')`, install the published scoped package with an npm alias:
36
+
37
+ ```sh
38
+ npm install zgpt@npm:@miruzero/zgpt@latest
39
+ ```
40
+
41
+ ```js
42
+ const chatgpt = require('zgpt');
43
+ ```
44
+
45
+ The two installation forms are alternatives. If you installed `@miruzero/zgpt` under its original name, import it using that same name:
46
+
47
+ ```js
48
+ const chatgpt = require('@miruzero/zgpt');
49
+ ```
50
+
51
+ The npm package name and the CLI binary name are independent; installing **only** `@miruzero/zgpt` does not create a local `node_modules/zgpt` alias.
52
+
35
53
  The package exposes the `zgpt` executable through npm's `bin` field. A local `npm install` does not add `node_modules/.bin` to the parent shell's PATH, so use `npx zgpt` for local installs or install globally for the bare `zgpt` command.
36
54
 
55
+ ### Hierarchical SDK → CLI automatic command discovery
56
+
57
+ The CLI discovers top-level public SDK namespaces at runtime, and groups the methods under each namespace. New namespaces and methods appear automatically without a second command registry. Use `zgpt help`, `zgpt help profile`, or `zgpt api families` to browse:
58
+
59
+ ```sh
60
+ zgpt help profile
61
+ zgpt profile getMe
62
+ zgpt profile getAuraIdentity
63
+ zgpt conversation get conversation-id
64
+ zgpt api models
65
+ zgpt api models getModels
66
+ zgpt api invoke "GET /public-api/conversation_limit"
67
+ ```
68
+
69
+ - Preferred: `zgpt <namespace> <method> [arguments...]` dispatches to the same SDK owner function. Use `--args JSON_ARRAY` for structured parameters. Older `zgpt call namespace.function` remains compatible.
70
+ - `zgpt api <family> <methodName>` groups the API catalog by `family` without duplicating routes. `zgpt api invoke "METHOD /route"` remains available, and supports `--path-values`, `--query`, `--options`, and `--body` for JSON input.
71
+ - Explicit non-read operations need `--allow-write` and required arguments. The generic adapter does not invent request payloads or permissions.
72
+ - Results are JSON and credentials in recognized sensitive fields are redacted for CLI output; direct JS callers receive unmodified objects.
73
+ - On this host, `npm link` points to `M:\Zero_ChatGPT`, so source changes take effect in the next CLI process. For a separately installed or published npm package, its installed version must be updated to receive changes.
74
+
75
+
37
76
  ## Public API
38
77
 
78
+ After `npm install zgpt@npm:@miruzero/zgpt@latest`:
79
+
39
80
  ```js
40
- const chatgpt = require('M:/Zero_ChatGPT');
81
+ const chatgpt = require('zgpt');
41
82
 
83
+ async function main() {
84
+ // Configure ZERO_CHATGPT_STATE_DIR and authenticate before these calls.
85
+ // Session acquisition can be requested via chatgpt.session.acquire() if needed.
42
86
  await chatgpt.auth.ensure();
43
- await chatgpt.session.acquire();
44
- await chatgpt.conversation.get(id);
45
- await chatgpt.conversation.send(id, message);
46
- await chatgpt.project.listProjects(options);
47
- await chatgpt.connector.listConnectors(options);
87
+ const conversation = await chatgpt.conversation.get('YOUR_CONVERSATION_ID');
88
+ const projects = await chatgpt.project.list();
89
+ const connectors = await chatgpt.connector.listConnectors();
90
+
91
+ // Mutations happen only when explicitly invoked:
92
+ // await chatgpt.conversation.send('YOUR_CONVERSATION_ID', 'Hello');
93
+ // await chatgpt.conversation.create('New conversation');
94
+ // await chatgpt.project.create('My project');
95
+
96
+ // Profile and Chat settings (only when entitled; writes require explicit bodies)
97
+ await chatgpt.profile.getMe();
98
+ await chatgpt.profile.getCreator();
99
+ // await chatgpt.profile.updateCreator({ body: { display_name: 'Developer' } });
100
+ await chatgpt.settings.getUser();
101
+ await chatgpt.settings.getConsent();
102
+ await chatgpt.settings.getNotifications();
103
+ await chatgpt.profile.getAuraIdentity(); // GET /backend-api/aura/identity
104
+
105
+ // ChatGPT Web API catalog: saved Web evidence plus verified supplemental routes.
106
+ // Generic routes require appropriate account permissions and exact request contracts.
107
+ console.log(chatgpt.api.summary.total); // 1291 (includes provisional paths)
108
+ const route = chatgpt.api.find({ method: 'GET', route: '/api/auth/session' });
109
+ const authSession = await chatgpt.api.invoke(route.key);
110
+ const limits = await chatgpt.api.invoke('GET /public-api/conversation_limit');
111
+ // Never log authSession: it can contain authentication credentials.
112
+
113
+ // Parameterized route and explicit one-shot writes (only with a verified payload):
114
+ // await chatgpt.api.invoke('POST /backend-api/hosting/sites/{id}/access',
115
+ // { pathValues: [siteId], body: verifiedBody });
116
+ }
117
+
118
+ main().catch(error => {
119
+ console.error(error.message);
120
+ process.exitCode = 1;
121
+ });
48
122
  ```
49
123
 
124
+ Saved web evidence is stored in `src/api/discovered.json`, while the four authenticated Browser Network GET discoveries are in `src/api/browser-observed.json`.
125
+ Historical endpoints remain in `src/api/catalog.json`; the runtime combines all three catalogs. Runtime query contracts are stored separately in `src/api/contracts.json`.
126
+ `api.byKey`, `api.functions` and `api.groups` provide typed route-name dispatch.
127
+ This is an **undocumented Web endpoint catalog**, not a guarantee of API stability,
128
+ authorization, correct mutation payloads, or complete browser-feature parity.
129
+
50
130
  ## Runtime rules
51
131
 
52
132
  - Direct ChatGPT Web transport is the only conversation transport.
53
133
  - Session exchange transport must be supplied explicitly; no browser/CDP transport is implicit.
54
134
  - 429 opens shared cooldown and is not amplified by retries.
55
135
  - No hardcoded credentials or secret-bearing diagnostics.
56
- - Default writable state lives only under `M:\Zero_ChatGPT\state`.
136
+ - By default, state is stored in `state/` relative to the installed package. For an npm-installed/global package, configure `ZERO_CHATGPT_STATE_DIR` to a **writable, user-owned directory outside `node_modules`** before authenticating. Never commit or publish this state.
137
+
138
+ ## API verification and request contracts (source checkout)
139
+
140
+ A catalog entry is **not** a proof of a working API. The local verification report classifies all 1,287 routes, and the bounded auditor uses a known-safe GET allowlist, with no mutations, retries, response bodies, cookies, or credentials persisted.
141
+
142
+ ```powershell
143
+ npm run api:audit
144
+ npm run api:audit:live -- --start 0 --max 32
145
+ npm run api:audit:live -- --start 32 --max 25
146
+
147
+ zgpt api models getModelsTrailingSlash
148
+ zgpt api images getImagesPromptItems --query surface=sketch_followups
149
+ zgpt api apps getAppsDirectoryBrowse --query category=productivity
150
+ zgpt api composer getComposerItems --query 'entrypoint=chat&limit=10'
151
+ ```
152
+
153
+ The `--query` flag accepts shell-friendly `name=value` or `name=value&name2=value2`, as well as a JSON object. For GET routes requiring query parameters, see `zgpt api show "GET /backend-api/..."` and `src/api/contracts.json`. The auditor and capture scanners are developer scripts in this source checkout and are not bundled in the npm package. Version `0.1.5` includes the release-ready SDK/CLI changes described above once published.
154
+
155
+ ### Custom MCP server CRUD and action refresh
156
+
157
+ The connector namespace supports MCP server creation, updates, deletion, OAuth metadata discovery, action refresh and `disconnectConnectorLink` (unlink a connected account without deleting the server definition). Discover exact SDK methods with `zgpt help connector`. **Live verified:** tunnel listing, OAuth discovery, and linked-action refresh (4 actions returned). **Mock verified only:** server create/edit/delete and connector unlink (no live destructive actions). Creating an OAuth-enabled connector auto-discovers metadata unless explicitly overridden. Refresh and unlink take a `linkId`, not a server definition ID. See the included `docs/custom-mcp-management-api.md` for request contracts and validation boundaries.
@@ -7,7 +7,7 @@
7
7
  ## Runtime
8
8
 
9
9
  ```text
10
- auth / session / conversation / project / connector / file / memory / settings / share
10
+ auth / session / conversation / project / connector / file / memory / settings / profile / share / api
11
11
  |
12
12
  protocol
13
13
  sentinel / proof / conduit / payload / SSE
@@ -43,7 +43,9 @@ The state directory is the only default writer for ChatGPT runtime state.
43
43
  - `connector` owns ChatGPT Chat connector discovery, app metadata, system hints, actions, refresh, and mention resolution.
44
44
  - `file` owns Chat composer file reservation, file-entry creation, upload processing, and reservation finalization.
45
45
  - `memory` owns Chat memory reads used by the normal Chat surface.
46
- - `settings` owns normal Chat user settings and explicit user-setting mutations.
46
+ - `settings` owns normal Chat user settings, consent, notifications, voice options, locale and explicit model-preference mutations.
47
+ - `profile` owns profile reads including the Chrome extension's Aura identity GET, GPT creator profile writes and explicitly addressed account user profile updates; no implicit account mutation.
48
+ - `api` exposes an evidence-backed route catalog (historical and supplemental), with a shared direct transport and proper `/public-api` routing; it is not a separate independent Core/Agent or a promise that each route is an implemented or supported feature. Work-only candidate routes carry explicit scope/evidence flags.
47
49
  - `share` owns normal Chat conversation share lifecycle.
48
50
  - `protocol` owns ChatGPT Web payload, Sentinel, conduit, and SSE mechanics.
49
51
  - `transport` owns HTTP, headers, retries, cooldown, and session-cookie persistence.
@@ -72,6 +74,4 @@ conversation is the only owner of stream diagnosis and repair. Callers request a
72
74
  5. External ChatGPT responses are validated before state mutation.
73
75
  6. This package owns only ChatGPT runtime state.
74
76
  7. No Zero Core, MCP, Agent, device, task, or adapter implementation lives here.
75
- 8. No background polling or hidden retry loop is allowed; recovery work occurs only on the active demand or an explicit retry demand.
76
-
77
-
77
+ 8. Loops, pagination, retry, and polling are allowed when required by the flow; they must have a measurable progress/termination condition, an explicit owner, and bounded failure recovery. Repeated writes must not be replayed without an idempotency guarantee. The current ChatGPT stream recovery remains demand-driven; no blanket prohibition on loops is implied.
@@ -0,0 +1,132 @@
1
+ # Custom MCP Server API — Web Client source audit (2026-10-12)
2
+
3
+ ## Status and scope
4
+
5
+ **Implemented in local source, no remote mutations performed.** The source of truth is existing ChatGPT Web callsites in the captured files `C:\Users\Administrator\Documents\OSSGPT\chatgpt.com\cdn\assets\conversation-small-cyhg2evird2sa17j.js` and `c2675c8c-j30y5ypuebsjl0k8.js`. The `OAI-Product-Sku` header was resolved from an imported constant in `4813494d-k4tqhmof689yx2je.js`; Web sends `OAI-Product-Sku: CONNECTOR_SETTING`.
6
+
7
+ Browser form fields: name, optional description, HTTPS server URL or `tunnel_<32 lowercase letters/digits>`, optional PNG icon (data URL; max 10 KB), authentication selection. The Web flow builds `auth_request` from supported authentication types and OAuth discovery before creating a connector. OAuth connection/linking is a separate operation after creation.
8
+
9
+ | Operation | Web route | Body from Web source | Verification |
10
+ | --- | --- | --- | --- |
11
+ | Create | POST `/backend-api/aip/connectors/mcp` | `{name,description,logo_url,mcp_url OR tunnel_id,custom_headers?,auth_request}` | Static callsite; SDK mocked |
12
+ | Read detail | GET `/backend-api/aip/connectors/{id}` | Path `connector_id` | Static callsite; SDK mocked |
13
+ | Rename | PATCH `/backend-api/aip/connectors/{id}/name` | `{name}` | Static callsite; SDK mocked |
14
+ | Description | PATCH `/backend-api/aip/connectors/{id}/description` | `{description}` | Static callsite; SDK mocked |
15
+ | Icon | PATCH `/backend-api/aip/connectors/{id}/logo` | `{logo_url}` | Static callsite; SDK mocked |
16
+ | Delete | DELETE `/backend-api/aip/connectors/{id}` | Path `connector_id` | Static callsite; SDK mocked |
17
+ | Refresh tools | POST `/backend-api/aip/connectors/mcp/refresh_actions` | `{link_id}` **not** connector ID | Static callsite; SDK mocked; previous SDK wrapper exists |
18
+ | OAuth discovery | POST `/backend-api/aip/connectors/mcp/oauth_config` | `{mcp_url OR tunnel_id,custom_headers}` | **Live SDK and CLI verified using `https://mcps.devteam.sc/core`** |
19
+ | List tunnels | GET `/backend-api/aip/connectors/mcp/tunnels` | None | **Live SDK HTTP 200**; CLI Exit 0 |
20
+
21
+ No confirmed endpoint for editing an existing server's **MCP URL** directly. Do not infer that renaming/reloading edits the transport URL; recreation may be required but was not performed.
22
+
23
+ ## SDK API
24
+
25
+ The public exports from `src/connector/mcp.js` are automatically exposed under `zgpt.connector` and as CLI commands via the existing dispatch logic:
26
+
27
+ ```js
28
+ const zgpt = require('@miruzero/zgpt');
29
+
30
+ // Real GET, with authorized local session:
31
+ const {tunnels} = await zgpt.connector.listCustomMcpTunnels();
32
+
33
+ // Read-only metadata discovery from the authenticated ChatGPT Web backend.
34
+ const discovered = await zgpt.connector.getCustomMcpOAuthConfig(
35
+ 'https://mcps.devteam.sc/core'
36
+ );
37
+ console.log(discovered.oauth_config.type); // OAUTH
38
+ // Only call the next step if you intend to create an actual connector.
39
+ // Default: auto-discover auth and preserve PKCE, scope and registration metadata.
40
+ const created = await zgpt.connector.createCustomMcpServer({
41
+ name: 'DevTeam MCP',
42
+ mcpUrl: 'https://mcps.devteam.sc/core'
43
+ });
44
+ // To bypass discovery, supply a fully configured authRequest explicitly,
45
+ // or set authentication:'NONE' only for intentionally unauthenticated servers.
46
+ await zgpt.connector.renameCustomMcpServer({connectorId:created.connector.id,name:'Renamed MCP'});
47
+ // NOTE: use a linkId returned by the connection/link flow, not created.connector.id:
48
+ // await zgpt.connector.reloadCustomMcpServerActions({linkId:'link_...'});
49
+ // Explicit destructive command only when intended:
50
+ // await zgpt.connector.deleteCustomMcpServer({connectorId:created.connector.id});
51
+ ```
52
+
53
+ **The above example includes mutations and was NOT executed on a live account.** Use only against servers you intend to create/change/delete.
54
+
55
+ ## CLI
56
+
57
+ ```powershell
58
+ zgpt help connector
59
+ zgpt connector listCustomMcpTunnels
60
+ zgpt connector getCustomMcpOAuthConfig https://mcps.devteam.sc/core
61
+ zgpt api show "POST /backend-api/aip/connectors/mcp"
62
+ ```
63
+
64
+ All methods also appear under `zgpt connector <methodName>`. JSON object arguments are passed via `--args JSON_ARRAY` and all non-read methods require `--allow-write`. The general `api` dispatcher also uses the same catalog and enforces required body fields.
65
+
66
+ ## Verification and outstanding work
67
+
68
+ - Unit/contract suite: **196/196 tests passed** (full project tests as of 2026-10-12).
69
+ - Live read: `GET /backend-api/aip/connectors/mcp/tunnels` HTTP 200 and matching CLI operation exited 0.
70
+ - Mutations (POST create, PATCH metadata, DELETE, POST refresh) **not live tested**; their success depends on actual owner permissions, OAuth configuration, valid image input and server capabilities.
71
+ - The create function only creates a connector definition. Completing OAuth and linking a server is a separate browser/client flow. The wrapper deliberately does not invent OAuth registration/scopes or auto-install a connector link.
72
+ - `logo_url` supports HTTPS or a PNG Data URL, matching the browser's FileReader path and 10 KB limit; generated artwork was not uploaded.
73
+ - The source changes are local and **not yet included in published npm 0.1.4**.
74
+
75
+ ## Source paths
76
+
77
+ - `src/connector/mcp.js`
78
+ - `src/connector/write.js`
79
+ - `src/connector/index.js`
80
+ - `src/api/contracts.json`
81
+ - `src/api/index.js`
82
+ - `test/connector-mcp-management.test.js`
83
+
84
+ ## Live OAuth Discovery evidence (2026-10-12, MiruZero)
85
+
86
+ - Actual MCP URL supplied by user: `https://mcps.devteam.sc/core`.
87
+ - Used the existing authenticated SDK session to call `POST /backend-api/aip/connectors/mcp/oauth_config` with `{mcp_url:'https://mcps.devteam.sc/core', custom_headers:[]}` and product SKU `CONNECTOR_SETTING`.
88
+ - **Live verified:** response carried `oauth_config.type=OAUTH`, resource matching the supplied URL, authorization/token/registration endpoints, `pkce_required=true`, `pkce_methods=['S256']`, `scopes_supported=['mcp:read']`, and `token_endpoint_auth_methods_supported=['none']`.
89
+ - CLI `zgpt connector getCustomMcpOAuthConfig https://mcps.devteam.sc/core` returned Exit 0 and the same safe metadata. CLI now preserves public OAuth discovery fields without exposing client secrets, credentials, access tokens or state-bearing authorization URLs.
90
+ - The local `createCustomMcpServer({name,mcpUrl})` defaults to automatic metadata discovery, maps the returned OAuth configuration into `auth_request.supported_auth`, and only then issues the create POST. This sequencing was tested using a stubbed transport, **not performed on the live user account**.
91
+ - Discovery failures and malformed/unsupported OAuth metadata fail closed; the SDK does **not** switch to `NONE` automatically. To intentionally skip discovery, pass either `authentication:'NONE'` or a previously configured `authRequest`.
92
+ - Connector creation does **not** mean OAuth authorization completed. Registration, PKCE redirect/callback, connector link creation, and action refresh are separate operations. They remain untested against this MCP server and are not automatically triggered.
93
+ - Local source changes are **not** included in the npm release `@miruzero/zgpt@0.1.4` until a new version is published.
94
+
95
+ ## MCP action refresh: live SDK + CLI verification (2026-10-12)
96
+
97
+ **VERIFIED for one authorized connection on MiruZero.** A user-supplied cURL trace was treated as evidence of the request shape rather than copied into source or the session store. Existing SDK auth/session logic supplied the access token and cookies; only the `linkId` came from the user's request. Neither bearer token, account ID, device ID nor browser fingerprint headers were hard-coded.
98
+
99
+ Request contract: `POST /backend-api/aip/connectors/mcp/refresh_actions`, body `{link_id}`, `OAI-Product-Sku: CONNECTOR_SETTING`, authenticated via SDK, no automatic HTTP retry. The SDK's legacy `connector.refreshConnectorActions({linkId})` is the single request implementation; `connector.reloadCustomMcpServerActions({linkId})` delegates to it.
100
+
101
+ Verified:
102
+ - JavaScript SDK `connector.reloadCustomMcpServerActions({linkId: '<authorized-link-id>'})`: completed successfully and returned an `actions` array.
103
+ - Windows CLI `zgpt connector reloadCustomMcpServerActions <authorized-link-id> --allow-write`: exit code **0**, response had an `actions` array containing **4 actions**.
104
+ - Added string-argument convenience `connector.reloadCustomMcpServerActions('<authorized-link-id>')`, auto-exposed to CLI via grouped SDK dispatch.
105
+ - Tests cover a single, non-retried POST with exact body, product-SKU header, automatic CLI write guard, both options-object and string argument support.
106
+
107
+ Not verified: automatic OAuth linking, creating a connection link, or behavior for other connector accounts. No secrets were persisted from the sample cURL and no unrelated connectors were modified. The response contents and individual action names were intentionally not logged.
108
+
109
+ ## Connected account unlink — Settings “ยกเลิกการเชื่อมต่อ”
110
+
111
+ **Implemented in SDK and automatically exposed in CLI. The real account link was NOT deleted.**
112
+
113
+ The user-provided browser cURL shows a connected-account operation that is *different* from deleting the MCP server definition:
114
+
115
+ - **Disconnect link:** `DELETE /backend-api/aip/connectors/links/{link_id}` (no JSON body)
116
+ - **Delete MCP definition:** `DELETE /backend-api/aip/connectors/{connector_id}`
117
+ - **Refresh linked actions:** `POST /backend-api/aip/connectors/mcp/refresh_actions` with `{link_id}`
118
+
119
+ `zgpt.connector.disconnectConnectorLink({linkId})` delegates directly to the existing API catalog dispatcher, which binds Zero's current authorization/session and sends the CONNECTOR_SETTING product SKU. It accepts a positional string `linkId` for CLI convenience. It rejects malformed/non-link IDs before executing any HTTP request, and `retry:false` prevents replay of DELETE.
120
+
121
+ ```js
122
+ const zgpt = require('@miruzero/zgpt');
123
+ // Only run to intentionally disconnect an authorized account:
124
+ await zgpt.connector.disconnectConnectorLink({linkId:'link_YOUR_LINK_ID'});
125
+ ```
126
+
127
+ ```powershell
128
+ # Destructive: disconnect a link only when intended:
129
+ zgpt connector disconnectConnectorLink link_YOUR_LINK_ID --allow-write
130
+ ```
131
+
132
+ The CLI refuses the command without `--allow-write`. A 204 No Content response normalizes to `{success:true}`, while non-2xx statuses propagate as errors. Tests verify URL/method/no-body, existing injected auth, missing/wrong ID guards, HTTP 403, one-shot execution and CLI write approval. **Only the request shape and the mock transport behavior are verified; live deletion has deliberately not been attempted.** The supplied Bearer token, cookies, account identifiers and browser fingerprint headers were not inserted into the codebase.
package/package.json CHANGED
@@ -1,13 +1,19 @@
1
1
  {
2
2
  "name": "@miruzero/zgpt",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "commonjs",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "zgpt": "src/cli.js"
8
8
  },
9
9
  "scripts": {
10
- "test": "node --test"
10
+ "start": "src/cli.js",
11
+ "test": "node --test",
12
+ "prepublishOnly": "npm test",
13
+ "api:rescan": "node scripts/collect-web-api.js",
14
+ "api:reconcile": "node scripts/reconcile-web-api.js",
15
+ "api:audit": "node scripts/audit-web-api.js",
16
+ "api:audit:live": "node scripts/audit-web-api.js --live"
11
17
  },
12
18
  "engines": {
13
19
  "node": ">=20"
@@ -21,7 +27,8 @@
21
27
  "files": [
22
28
  "src",
23
29
  "README.md",
24
- "docs/architecture.md"
30
+ "docs/architecture.md",
31
+ "docs/custom-mcp-management-api.md"
25
32
  ],
26
33
  "publishConfig": {
27
34
  "access": "public"
@@ -0,0 +1,82 @@
1
+ {
2
+ "source": "Agent Browser v0.39.0 attached to logged-in chatgpt.com, captured read-only HTTP status metadata; no auth headers or payloads persisted",
3
+ "observedAt": "2026-10-12",
4
+ "entries": [
5
+ {
6
+ "key": "GET /backend-api/accounts/check/v4-2023-04-27",
7
+ "method": "GET",
8
+ "client": "Request",
9
+ "route": "/backend-api/accounts/check/v4-2023-04-27",
10
+ "name": "getAccountsCheckV420230427",
11
+ "family": "accounts",
12
+ "scope": "CHATGPT_WEB",
13
+ "evidence": [
14
+ "AGENT_BROWSER_SESSION_NETWORK"
15
+ ],
16
+ "captureCount": 1,
17
+ "statuses": {
18
+ "200": 1
19
+ },
20
+ "verification": "LIVE_BROWSER_HTTP_200",
21
+ "liveStatus": 200,
22
+ "observedAt": "2026-10-12"
23
+ },
24
+ {
25
+ "key": "GET /backend-api/ps/plugins/installed",
26
+ "method": "GET",
27
+ "client": "Request",
28
+ "route": "/backend-api/ps/plugins/installed",
29
+ "name": "getPsPluginsInstalled",
30
+ "family": "ps",
31
+ "scope": "CHATGPT_WEB_PLUGINS",
32
+ "evidence": [
33
+ "AGENT_BROWSER_SESSION_NETWORK"
34
+ ],
35
+ "captureCount": 1,
36
+ "statuses": {
37
+ "200": 1
38
+ },
39
+ "verification": "LIVE_BROWSER_HTTP_200",
40
+ "liveStatus": 200,
41
+ "observedAt": "2026-10-12"
42
+ },
43
+ {
44
+ "key": "GET /backend-api/wham/accounts/check",
45
+ "method": "GET",
46
+ "client": "Request",
47
+ "route": "/backend-api/wham/accounts/check",
48
+ "name": "getWhamAccountsCheck",
49
+ "family": "wham",
50
+ "scope": "WORK_ACCOUNTS",
51
+ "evidence": [
52
+ "AGENT_BROWSER_SESSION_NETWORK"
53
+ ],
54
+ "captureCount": 1,
55
+ "statuses": {
56
+ "200": 1
57
+ },
58
+ "verification": "LIVE_BROWSER_HTTP_200",
59
+ "liveStatus": 200,
60
+ "observedAt": "2026-10-12"
61
+ },
62
+ {
63
+ "key": "GET /backend-api/wham/sites/access",
64
+ "method": "GET",
65
+ "client": "Request",
66
+ "route": "/backend-api/wham/sites/access",
67
+ "name": "getWhamSitesAccess",
68
+ "family": "wham",
69
+ "scope": "WORK_SITES",
70
+ "evidence": [
71
+ "AGENT_BROWSER_SESSION_NETWORK"
72
+ ],
73
+ "captureCount": 1,
74
+ "statuses": {
75
+ "200": 1
76
+ },
77
+ "verification": "LIVE_BROWSER_HTTP_200",
78
+ "liveStatus": 200,
79
+ "observedAt": "2026-10-12"
80
+ }
81
+ ]
82
+ }
@@ -0,0 +1,101 @@
1
+ {
2
+ "GET /backend-api/models/config": {
3
+ "requiredQuery": [
4
+ "slug"
5
+ ],
6
+ "contractEvidence": "STATIC_OSSGPT_QUERY; LIVE_422_MISSING_SLUG",
7
+ "runtimeNotes": "Frontend supplies a model slug; live GET with current model slugs returned 404 in this session, so availability remains unverified."
8
+ },
9
+ "GET /backend-api/gizmos/user_action_settings": {
10
+ "requiredQuery": [
11
+ "gizmo_id"
12
+ ],
13
+ "contractEvidence": "STATIC_OSSGPT_QUERY; LIVE_422_MISSING_GIZMO_ID",
14
+ "runtimeNotes": "Requires a valid GPT identifier. No permitted GPT ID was available in the tested bootstrap response."
15
+ },
16
+ "GET /backend-api/apps/directory/browse": {
17
+ "requiredQuery": [
18
+ "category"
19
+ ],
20
+ "contractEvidence": "STATIC_OSSGPT_QUERY; LIVE_422_MISSING_CATEGORY; LIVE_200_CATEGORY_PRODUCTIVITY",
21
+ "runtimeNotes": "Use a category id from GET /backend-api/apps/directory/apps. Productivity returned HTTP 200 in this session."
22
+ },
23
+ "GET /backend-api/composer/items": {
24
+ "requiredQuery": [
25
+ "entrypoint"
26
+ ],
27
+ "contractEvidence": "STATIC_OSSGPT_QUERY; LIVE_422_MISSING_ENTRYPOINT; LIVE_200_ENTRYPOINT_CHAT",
28
+ "runtimeNotes": "The saved web callsite also sends limit and sometimes timezone; the server required entrypoint. entrypoint=chat&limit=10 returned HTTP 200."
29
+ },
30
+ "GET /backend-api/images/prompt-items": {
31
+ "requiredQuery": [
32
+ "surface"
33
+ ],
34
+ "contractEvidence": "STATIC_OSSGPT_QUERY; LIVE_422_MISSING_SURFACE; LIVE_200_SURFACE_SKETCH_FOLLOWUPS",
35
+ "runtimeNotes": "The web source passes surface=sketch_followups; live result was HTTP 200."
36
+ },
37
+ "POST /backend-api/aip/connectors/mcp": {
38
+ "requiredBodyFields": [
39
+ "name",
40
+ "auth_request"
41
+ ],
42
+ "bodyAnyOf": [
43
+ "mcp_url",
44
+ "tunnel_id"
45
+ ],
46
+ "contractEvidence": "OSSGPT_WEB_ONSUBMIT_CUSTOM_MCP; STATIC_WEB_SAFEPOST",
47
+ "runtimeNotes": "Create connector definition; no write-side effects tested. Browser UI sends name, description, logo_url, either mcp_url or tunnel_id, optional custom_headers, and auth_request with supported_auth/oauth_client_params/default_scopes/oidc_enabled/use_cimd. Linking/OAuth occurs in a subsequent flow."
48
+ },
49
+ "PATCH /backend-api/aip/connectors/{id}/name": {
50
+ "requiredBodyFields": [
51
+ "name"
52
+ ],
53
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEPATCH",
54
+ "runtimeNotes": "Path connector_id, requestBody {name}. Not live-tested against user data."
55
+ },
56
+ "PATCH /backend-api/aip/connectors/{id}/description": {
57
+ "requiredBodyFields": [
58
+ "description"
59
+ ],
60
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEPATCH",
61
+ "runtimeNotes": "Path connector_id, requestBody {description}; empty description is permitted for clearing. No live mutation test."
62
+ },
63
+ "PATCH /backend-api/aip/connectors/{id}/logo": {
64
+ "requiredBodyFields": [
65
+ "logo_url"
66
+ ],
67
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEPATCH",
68
+ "runtimeNotes": "Path connector_id, requestBody {logo_url}; actual upload step is separate. No live mutation test."
69
+ },
70
+ "DELETE /backend-api/aip/connectors/{id}": {
71
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEDELETE",
72
+ "runtimeNotes": "Destructive removal of connector definition; never automatically executed by audit."
73
+ },
74
+ "DELETE /backend-api/aip/connectors/links/{id}": {
75
+ "contractEvidence": "USER_PROVIDED_BROWSER_CURL; SDK_MOCK_TEST",
76
+ "runtimeNotes": "Unlinks a connected account by link_id from ChatGPT Settings. No request body. Requires authenticated session and CONNECTOR_SETTING product SKU. Distinct from deleting the MCP connector definition. Never run against a live link without an explicit unlink instruction."
77
+ },
78
+ "POST /backend-api/aip/connectors/mcp/refresh_actions": {
79
+ "requiredBodyFields": [
80
+ "link_id"
81
+ ],
82
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEPOST; EXISTING_CONNECTOR_TEST",
83
+ "runtimeNotes": "Refresh action list by link_id, NOT connector_id. Side-effecting command; not executed live."
84
+ },
85
+ "POST /backend-api/aip/connectors/mcp/oauth_config": {
86
+ "bodyAnyOf": [
87
+ "mcp_url",
88
+ "tunnel_id"
89
+ ],
90
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEPOST",
91
+ "runtimeNotes": "RequestBody {mcp_url,custom_headers} or {tunnel_id,custom_headers}; response.oauth_config; potentially queries remote server. Not executed live."
92
+ },
93
+ "GET /backend-api/aip/connectors/mcp/tunnels": {
94
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEGET; LIVE_SDK_HTTP_200",
95
+ "runtimeNotes": "Read-only GET returned HTTP 200 with a tunnels array in this session."
96
+ },
97
+ "GET /backend-api/aip/connectors/{id}": {
98
+ "contractEvidence": "STATIC_OSSGPT_WEB_SAFEGET",
99
+ "runtimeNotes": "Read connector by id; requires authorized connector_id and may include actions. Not probed with user ID."
100
+ }
101
+ }