plugin.json and mcp.json, with .codex-plugin/plugin.json and .mcp.json
retained for compatibility. The portable manifest deliberately omits
extensions.com.openai, so the existing OpenAI presentation overlay remains
active in full. Portable version is omitted; Release Please continues to own the
compatibility manifest’s version. No legacy ai-plugin.json is used.
Capability and security gates
Current OpenAI docs describe portable Agent Plugins as the authoring format,
MCP Apps as the shared UI bridge, and OpenAI MCP Extensions as optional host
surfaces. Existing plugin functionality remains available while Free/Go web
extensions are coming soon. Do not infer availability on every plan, mobile
client, or host from a successful desktop example. See
packaging,
extensions,
UI reference, and
changelog.
Local read bridge
This is a local stdio server using the official MCP Python SDK’s maintained FastMCP API, pinned tomcp==1.28.0; SDK v2 is now stable and needs a separately
validated migration. It is not a hosted ChatGPT connector. Public MCP submission
requires a remote HTTPS endpoint. The server binds to no network port and exposes:
list_workspaces: only workspace IDs and bounded names.list_workspace_tasks: one page of open task IDs and bounded names with an explicit workspace UUID, limit 1–50 and offset 0–10000. Default CLI status filtering still applies. Personal external placements fail closed.get_workspace_navigation: a canonical Tasks or Calendar workspace link; does not launch a browser or fetch events.
outputSchema. A CLI call times out after 20 seconds and its parsed
response is capped at 1 MiB; temporary output is deleted after each call.
Setup is deliberate and separate from installation of repository dependencies:
python3 command. A repo-local virtualenv is not copied into plugin
caches. Codex’s compatibility overlay explicitly forwards only
TUTURUUU_MCP_READS_ENABLED via .mcp.json env_vars; start/restart the host
with that variable after review. No manifest hardcodes enablement. Both manifests
use contained plugin-relative cwd: "./" and mcp/server.py arguments.
The portable schema has literal env, not env_vars; generic portable hosts
must explicitly configure opt-in forwarding, otherwise reads remain disabled.
Codex uses the existing OpenAI compatibility overlay.
Loader rules were checked against pinned official Codex source
plugin_config.rs
and agent_plugin_config.rs.
The legacy loader joins relative cwd to the package root and does not expand
${PLUGIN_ROOT} in arguments. Tests launch the actual packaged manifests using
these path/forwarding contracts and the real Python SDK; they do not execute the
Rust loader or prove live host installation.
Local discovery also fails closed while its actor-bound Hidden reader is
unavailable: it returns no workspaces. The installed CLI currently has no owner
Hidden read command. The trusted integration seam must read the owner-only route
with the current CLI whoami identity and expectedActorId, without token export,
admin fallback, or caching. Missing/malformed authority or an actor switch returns
no discovery rows. Hidden never removes canonical membership: explicit authorized
task reads and navigation still work. Production wiring of that seam remains a gate. Do not place tokens in either manifest or enable reads globally without
understanding the host’s data handling. Reinstall/refresh the plugin cache after
source changes; cached packages do not follow source edits automatically.
Offline verification (synthetic responses; does not authenticate or call APIs):
Smallest staged rollout and owned paths
- Local read slice:
plugins/tuturuuu/{plugin.json,mcp.json,.mcp.json},.codex-plugin/plugin.json,plugins/tuturuuu/mcp/, the plugin validator, and this existing documentation page, and.github/workflows/codex-plugin.yamlfor offline protocol/security tests. No mobile, workspace picker, Calendar UI, database, SDK, or live API files change. - Hosted read adapter: propose isolated
packages/mcp/transport/auth modules andapps/web/src/app/api/mcp/only after OAuth design review. Keep Rust/API migration registration in step under repository rules. Reuse existing user-authorized API reads; never introduce a service-role bypass. Gate calendar reads on verified per-user/provider visibility and bounded time ranges. - MCP App: a workspace/task view built on the standard bridge, then optional sidebar/panel entrypoints and desktop composer mentions when supported.
- Writes and publication: independent review and approval; use explicit proposed changes and server-enforced confirmation/idempotency, then host testing, privacy/support/terms, test-account and review materials, metadata scan and directory publication. No stage silently enables another.
Corrected hosted boundary plan
Reconciled against verified remote maine819953329392db746bb22e2e918f3c8bbb06579 on October 1, 2026. The local stdio
implementation above is Codex/desktop groundwork, not completion of the requested
hosted ChatGPT integration. Portable packaging supports local stdio, but public
ChatGPT MCP distribution needs a remote HTTPS endpoint and its own authorization
contract. No placeholder remote URL or registered connection ID is advertised.
Current source boundaries to reuse:
packages/internal-api/src/workspaces.tsandtasks.tsown typed user-facing read requests;client.tsowns API transport. Do not wrap every API operation.packages/tasks-api/src/server/tasks/route.tsowns task visibility and membership checks; the current handler has admin-backed branches. A hosted adapter must not treat a verified MCP token as permission to use those branches without checking the actor, workspace, private board and guest boundaries.apps/web/src/lib/api-auth.tsandapi-auth-audiences.tsown gateway session, audience, abuse and step-up decisions. ItsallowAppSessionAuthpath explicitly uses an admin-backed client. Do not enable that path for MCP as an RLS substitute.packages/auth/src/cli-session.tsgrants broadcli:access; it is not the hosted token contract.app-session.tshandles internal target-app sessions. Neither token is returned to ChatGPT or accepted as an MCP access token.apps/web/src/app/api/v1/auth/app-token/exchange/route.tshandles external-app secrets, scopes, workspace checks and rotation. Reuse its authorization and refresh principles; do not send ChatGPT a cross-app token or app secret.apps/web/src/lib/auth/oauth-providers.tsconfigures incoming account sign-in providers. The audit did not find a complete MCP OAuth authorization server in this source. Outbound Google/SePay OAuth is unrelated. Issuer capability, client registration, consent storage and audience binding remain explicit design gates.
- ChatGPT discovers the MCP protected-resource document and the approved issuer’s discovery document. No account-specific data is available anonymously.
- Authorization code + S256 PKCE enters the existing Tuturuuu sign-in boundary. A Tuturuuu-owned consent screen chooses one accessible workspace and read scopes for workspace discovery/task summaries/navigation. Preserve required MFA and deny suspended users. Bind client, exact redirect, resource, workspace and granted scopes to a single-use code; never infer consent from sign-in alone.
- The approved issuer produces a resource-bound OAuth user access token with subject, expiry, client and revisioned MCP grant claims. ChatGPT receives this restricted credential. Ordinary account, CLI, internal-app and refresh tokens are rejected as tool-access credentials and never appear in tool output.
- A stateless Streamable HTTP request verifies issuer/signature or introspection, audience/resource, expiry, grant revocation, scopes and actor on every POST. Reject browser cookie-only requests, unsafe Origin/Host, oversized JSON/batches and unsupported methods. Missing auth returns the discoverable 401 challenge. Apply shared gateway abuse/rate limits and redacted correlation-only logging.
- Construct a request-scoped typed read client using
packages/internal-api. The adapter uses the verified OAuth user JWT on three fixed resource-read GET paths plus the owner-private Hidden GET at canonical platform/Tasks/Calendar origins. Release requires those gateways to enforce the MCP audience, client, domain grant and read-only user authority. Ordinary Supabaseauthenticatedaudience acceptance is insufficient. If gateway/RLS compatibility cannot be established safely, keep this adapter disabled and implement the narrow actor-aware boundary first. No process CLI identity, workspace API key or service-role client is constructed by MCP. - Recheck selected-workspace membership and operation-specific task visibility; return only projected summaries and canonical allowlisted links. No MCP cache in the first hosted slice; later cache keys include issuer/subject/grant/workspace and scopes, and never bypass revocation. Names remain untrusted content.
- Start without widgets or writes. The prepared Calendar adapter preserves the
current
manage_calendarrequirement and projects event ID/title/times only, within a seven-day interval and 100-event cap. It does not weaken Calendar permissions or return guests, descriptions or provider credentials. Add MCP Apps UI only after this read path passes isolation tests; use standard bridge/resource CSP before optional OpenAI sidebar/panel/desktop composer surfaces.
Prepared hosted source slice
The source has one connected composition root and remains unregistered. The shipping web package pins the official@modelcontextprotocol/sdk@1.31.0 in
apps/web/package.json and the root bun.lock. Package-manager generation added
only that workspace dependency and eight new SDK-related lock records; existing
package records, other workspaces and lock settings did not change. Existing JOSE,
Zod and internal-api dependencies support the source core.
A bounded local FIFO run passed all 37 focused tests, including three real official
SDK client/server Streamable HTTP tests. It exercised initialize/initialized,
typed tools/list, task/navigation tools/call and forged-workspace/cross-tenant
rejection through JWT, provider and typed API boundaries. Test identities, signing
keys and upstream provider/API responses are synthetic; no live grants, credentials,
public endpoint, database or application build was used. This proves the source
read workflow, not deployed OAuth/RLS authority or production readiness.
Exact owned paths:
No route, route-override, mobile, workspace selector, existing API, database or
Calendar lane file is changed. Route registration and any Rust gateway mirror
remain required before deployment, using the repository’s normal ownership rules.
Provider, consent and release gates
Current Supabase documentation describes a managed OAuth 2.1/OIDC server with authorization-code PKCE, custom consent and user grant revocation. It is a candidate issuer, not evidence that the Tuturuuu project has enabled it. The provider handles codes, token issuance and refresh; do not implement custom OAuth cryptography. Use its authorization-details and approval/denial APIs from a trusted authenticated consent boundary with existing MFA/account rules, same-origin CSRF protection and exact approved client/redirect checks. Persist actor/client/resource/selected workspaces/read scopes before approval in an atomic revisioned grant store. No consent page, grant store, access-token hook or OAuth configuration was created. Supabase OAuth flows. Supabase’s default audience isauthenticated; OAuth tokens carry client_id.
Its OIDC scopes are not Tuturuuu task/Calendar permissions. The prepared
mcp:*:read values are a local domain grant contract, not a claim that the provider
supports arbitrary OAuth scopes. A reviewed provider hook must bind the MCP
resource audience and grant ID/revision. Restrictive RLS and gateway checks must
prevent this JWT from gaining ordinary write or unrelated workspace access via
another API. No RLS, signing key, issuer, hook or gateway security configuration
was changed. Supabase token security.
The current user API wrappers can enter administrator proxy paths and some task
and Calendar handlers use admin queries after authorization. Their existing
membership/private-board gates must be proved for OAuth user tokens; MCP does not
enable app-session fallback or construct a service-role client. Raw public-key
Supabase identity access is required at the provider seam. The installed
@supabase/auth-js@2.117.1 differs from the public flow page examples: it exposes
oauth.listGrants() and rows with client.id. That SDK method requires a local
refreshable session, even with global bearer headers. The prepared stateless
provider reader therefore uses its two fixed read endpoints (/user and
/user/oauth/grants) with the verified request JWT and public publishable key;
it does not fabricate a refresh session or credential vault. getUser and JWKS
verification alone do not satisfy the live-session/account/MFA policy contract.
The parallel workspace lane defines owner-only HIDDEN_WORKSPACE = true rows in
user_workspace_configs, with absent rows visible and an actor-bound owner GET.
The verified base does not yet contain that lane’s route. The prepared reader
returns visible, hidden or unknown; Hidden/unknown are excluded from discovery
and consent choices. Explicit granted reads and authorized navigation preserve
canonical membership, matching that lane’s documented deep-link rule: hiding is
not permission revocation. The route must be integrated and its OAuth user behavior
proved before deployment. This lane does not edit or copy its preference writes.
There is no MCP data cache or cross-user session cache. Task API responses that
include external placements or lack the workspace relation are rejected in full;
native-only API query behavior remains a compatibility gate.
No OAuth grant, secret, client registration, public endpoint, database/security
configuration or marketplace action occurs during this source slice. Before runtime
wiring, resolve issuer, consent/grant storage, live session policy, Hidden visibility
and gateway/RLS authority; before installs or tests, use bounded FIFO admission.
Prepared synthetic tests cover wrong issuer/audience,
expired/revoked grants, refresh-as-access, account switching, forged workspace IDs,
guest workspace access, Origin/Host confusion and hostile names. Private-board API
fixtures, real signature/key-rotation tests, real SDK initialize/list/call tests,
provider refresh/revocation, restrictive RLS and gateway compatibility tests remain
required. Delivery evidence also needs actual Streamable HTTP host tests and
parent-approved permitted-account reads. Writes require separately reviewed
confirmation/idempotency; widgets require standard MCP Apps bridge/CSP review;
marketplace publication remains a later parent-approved stage.
Remaining authority design against existing contracts
The runtime’s required policy/store callbacks are seams, not a deployed authority. No environment loader supplies them and no public route invokes the workflow. KeepsecurityReviewComplete false until these boundaries are implemented and
reviewed with the provider and gateway behavior.
packages/supabase/src/next/auth-session-user.tsrevalidates identity withgetUser()after checking claims. Reuse that identity principle, but do not equate identity/JWKS success with an authoritative active OAuth session. No existing source contract inspected here proves owner-bound livesession_idand client revocation together. A narrow reviewed provider/session adapter remains required; never query unrestricted auth tables via an MCP admin client or fabricate a local refresh session to obtain SDK grant methods.packages/utils/src/required-mfa-policy.tsowns the serverapp_metadatapolicy and verified AMR/session proof helpers:readRequiredMfaPolicy,mfaProofFromVerifiedClaimsandsatisfiesRequiredMfaPolicy. A future adapter must carry already-verified claims and current server-owned metadata in request context, bind proof to the same session, and preserve recovery/primary-proof cutoffs. The current(userId, sessionId)callback is intentionally unwired; enrich its verified context before implementing MFA policy. Refreshiat, browser flags and editableuser_metadatado not establish fresh MFA.packages/utils/src/abuse-protection/user-suspension.tsowns suspension reads. Some existingapps/web/src/lib/api-auth.tsbranches catch suspension lookup errors and continue. Do not inherit that fail-open behavior for MCP: unavailable policy or unknown account/session state must deny access.- The persistent grant store must uniquely bind user/client/provider authorization ID, resource, redirect, selected workspace IDs and domain read scopes. Reserve consent atomically; activate only after trusted provider approval; the token hook reads only active grants. Never reuse generic editable user configuration as grant authority. Revisioned revoke/change commits must reject old JWTs before returning tool data. Provider revocation is a separate distributed side effect: use durable reconciliation/outbox semantics rather than claiming an atomic database/provider transaction. No schema, RPC, privileged policy or hook is created by this slice.
Focused validation and SDK provenance
From an installed checkout, run the non-build Node tests with one worker:ttr resources run --. The focused config isolates
unrelated TypeScript project references and never loads application environment
files. It resolves the shipping SDK from the web package. An explicitly owned
isolated validation installation can be selected with TUTURUUU_MCP_SDK_DIR; that
option changes only test module resolution, not runtime authorization or API origins.
workflow.test.ts uses an explicitly synthetic dispatcher to isolate the source
boundary; sdk-protocol.test.ts uses the actual official Client, Streamable HTTP
client transport, McpServer and Web Standard Streamable HTTP server transport.
Both share real JOSE-signed synthetic identities and the actual internal-api client.
No stub dispatcher is used to claim SDK protocol compatibility.
The official registry’s compatible v1 package @modelcontextprotocol/sdk@1.31.0
was published September 28, 2026 at 18:59:36 UTC. It exceeded this repository’s
minimumReleaseAge = 86400; MCP has no exemption. The newer generation uses
separate v2 packages; this source targets the maintained v1 API. See the
official v1 release.
The SDK lock integrity matches the registry:
sha512-UvTMgnNlnIBO/22ob2RcVGDlcvOslQs8T59+FTGdA0L27a39fdGF/EDETNtDVK4DZGpwomlsYpRdA8UXcVL/pw==.
Local SDK installation used an owned isolated directory/cache, exact pin, disabled
lifecycle scripts and normal FIFO admission. The shipping manifest/lock were
package-manager-generated in a manifest-only workspace copy with unchanged existing
patch/vendor inputs, then inspected before export. No donor/global dependency or
credential mutation occurred. Focused evidence does not replace exact-commit CI
lint/type/build checks, live provider refresh/revocation, private-board/RLS fixtures
or permitted-account delivery checks; the parent owns integration and monitoring.
Provider consent must prove the authorization transaction was issued for the exact
MCP resource before grant reservation. The installed provider SDK currently omits
that resource field, so its unaugmented authorization details intentionally fail
closed. A reviewed provider resource-binding integration is still required before
activation; the source factory does not infer audience from configuration or user input.
The packaged local bridge uses python3 (Python 3.10 or newer), with a generated
transitive dependency hash lock and pip cache in CI. A missing trusted Hidden
discovery reader returns an empty workspace list without launching the CLI. Local
CLI output is bounded while reading the pipe; oversized output terminates the child
before it can accumulate in a temporary file.