@tangle-network/chatgpt-agents-kit
v0.1.4
Published
Mount the existing factory with the app's real OAuth resource and native binding:
Readme
Tangle Agents plugin kit
Connect an existing Agent App
Mount the existing factory with the app's real OAuth resource and native binding:
import { createAgentsHandler } from '@tangle-network/chatgpt-agents-kit'
import { createMcpToolHandler } from '@tangle-network/agent-app/tools'
const handle = createAgentsHandler({
metadata: { name: 'my-agent', displayName: 'My Agent', description: 'Continue my existing work.' },
oauth,
nativeMcp: createMcpToolHandler,
bind: resolveNativeBinding,
})The existing resource supplies the origin. Conservative defaults allow list, connect, prompt, task and output only when the native host supports and grants those actions. Creation, handoff, decisions, channels and cancellation remain explicit. Public display metadata never grants permissions or exposes users.
From a project with the containing reviewed kit release installed:
npm exec --no -- tangle-agents-plugin --endpoint https://YOUR-APP/api/agents/mcpThis generates ./chatgpt-plugin: manifests, shared skills and Connect instructions.
No duplicate app.json, fake app ID, credential copy or separate deployment is
needed. Loopback HTTP works for local development; remote endpoints require
HTTPS. Existing --config/--out/--offline flows remain available. Offline requires
an explicit config and never counts as discovery or login proof.
The host owns OAuth, identity, RBAC, native admission, sessions, billing, approvals and execution-linked output readers. GTM's transcript-only provenance rule must not become workspace file enumeration. Creative keeps its native Vault reader. The kit owns distribution and the outward tool contract, not a new backend. Inspection remains inside Agents; Sandbox is the only other marketplace plugin. Generating this directory does not install ChatGPT or register an OAuth client.
Persistent prompting
prompt_agent sends a new instruction to the selected existing agent. get_task
observes the same run; cancel_agent_run targets an exact admitted execution.
The old delegate_task call remains a hidden compatibility alias with the same
authorization and idempotency rules. Existing host metadata still uses delegate
for its run permission; this is not a second runtime.
Authenticated read-only grants can discover prompt_agent with its required OAuth
scopes. Calling it without the run grant returns an MCP insufficient_scope
challenge so the client can request an upgrade. The kit accepts HTTP MCP resource
URLs only on localhost, 127.0.0.1, or [::1] for local development; remote
resources require HTTPS.
The exported createSandboxAgentBinding connects an already-enrolled generic
Sandbox agent to the published SDK's session message lane, preserving sandbox,
thread/session and native turn admissions. It does not call instances.ensure,
create a replacement sandbox, or invent a task store. Completed retained answers
can be returned without file tools; the separate output grant still applies.
See persistent-agent setup and acceptance for the native host example, lifecycle contract, compatibility and verification. GTM/Creative must keep their own admission/preparation/billing path; this generic binding is not a bypass around those application services.
Reusable packaging and an in-process native-agent MCP adapter. GTM is the
first native REST configuration. configs/workspace.json is a restricted
agent-app workspace configuration, not a claim of a second deployed product.
The root plugin.json and skill are a truthful factory shell. No root mcp.json
is declared until an app mounts a resource-bound OAuth MCP endpoint. Generate
an app-specific package with the endpoint below; do not install the shell as
evidence that GTM or ChatGPT tools are connected. npm run build compiles the
runtime kit without requiring a fabricated endpoint.
No new agent backend, identity store, workspace store, scheduler, execution
engine, provider connection or billing ledger is implemented here.
configs/gtm-chat.json describes GTM's narrower direct chat route. The full
configs/gtm.json remains a file-capable kit fixture, not a claim that the
direct GTM route exposes file handoff or every generic action.
The chat config follows a GTM source lane and is not hosted acceptance.
Verified release and remaining acceptance
On October 2, 2026, @tangle-network/[email protected] was publicly available from npm.
A fresh external consumer installed that release, used its compiled CLI, and generated a plugin with the registered app connection.
The generated GTM plugin was installed in ChatGPT and completed one authorized task in an existing workspace and conversation.
After reload and reconnect, it returned the same retained output and native execution references.
That fixed-response task establishes transport and continuity, not the quality of useful customer work.
This evidence applies to that GTM connection and release. It does not establish Creative activation, ordinary Builder agents, phone continuity, or hosted result-card behavior. Those flows need their own acceptance through the deployed app. The current source skills guide discovery by name, useful deliverables, revision, and returning later. Install the release containing those changes before evaluating their hosted behavior. Their meaningful-work acceptance remains separate from source, package, and fixture checks.
Every adopting app still owns its OAuth binding, native admission, authorization, and retained outputs. The generator creates a package; it neither implements missing host services nor grants capabilities. The adapter requires execution-linked output evidence before verifying completion. Text file support, when exposed by the host, handles UTF-8 content rather than binary uploads.
The tests use the unmodified, hash-verified maintained agent-app MCP envelope
and a test-only SQLite contract fixture. That fixture genuinely reads randomized
approved CSV input, computes an output, writes its bytes and native-style revision,
and retains its task. It is not GTM, not a model-backed agent, not Tangle's real
OAuth provider and not evidence of production task execution. The fixture is
under tests/ and is never packaged or exported as a backend.
Generate from the installed kit
Use Node 22.16 or later. The app author supplies metadata and the app's existing OAuth MCP endpoint; the app keeps its native account, agent profile, workspace, thread, task state, permissions and execution evidence. Package generation does not provision an agent or add capabilities to the endpoint.
Install this release in your app directory:
npm install --save-exact --ignore-scripts @tangle-network/[email protected]Use the approved exact version when adopting a later release.
No repository checkout or TypeScript loader is required.
Neither installation nor package generation publishes anything.
Create app.json using your own application origin and display metadata (the
.example origin below is a placeholder, not a deployed service):
{
"name": "my-existing-agent",
"displayName": "My Existing Agent",
"description": "Continue work with my existing agent.",
"applicationOrigin": "https://my-app.example",
"actions": ["list", "connect", "delegate", "task", "output"]
}Supply the credential-free HTTPS URL of the existing MCP endpoint:
npm exec --no -- tangle-agents-plugin \
--config ./app.json --endpoint "$AGENTS_MCP_ENDPOINT" --out ./chatgpt-pluginnpm exec --no uses the installed executable without fetching another package.
npm exec --no -- tangle-agents-plugin --help prints the options without network
access. The compiled CLI resolves both its ordinary and optional inspection
skills relative to its installed dist directory, never the working directory
or a source-checkout fallback. The source entry point remains supported for
repository development; npm run build:plugin -- ... uses the compiled CLI.
When the host uses createAgentsHandler, the action restriction list can reduce
its native capabilities; it cannot grant any. The direct GTM route defines its
own server tools and scopes. Package metadata does not change that route's
authorization. Add "inspection": true only when the trusted app host exposes
the corresponding scoped inspection tools; this includes the existing
inspection skill, not a separate product.
The command checks anonymous OAuth resource discovery, then writes root
plugin.json, root mcp.json (type: streamable-http), the applicable skills and an explicit
readiness report. It does not deploy, register a client, publish, purchase
anything, add hooks, write a marketplace, or embed auth headers or credentials.
--offline deliberately skips network checks and records those checks as
not executed. It is useful for format validation, not operational readiness.
A package already at the output location is not updated in place.
OAuth discovery is not login proof. Verify the configured authorization server,
S256 PKCE, resource/audience registration and live grant revocation before
connecting ChatGPT. Register the actual endpoint in ChatGPT developer mode using
the current official instructions; no fabricated plugin_asdk_app ID is emitted.
The generated portable MCP declaration is not a claim that ChatGPT installed it.
Native thread IDs are bounded opaque identifiers and may include : namespace separators, such as GTM's daily conversations. Use isNativeThreadId for host-side validation of this shared contract; workspace and turn identifier restrictions are unchanged.
Consume the runtime kit
npm run build emits JavaScript and declarations for the Agents handler, the
GTM adapter, and the nested inspection capability. A local consumer can install
the result with npm pack and then import these public paths:
import { createAgentsHandler, type NativeBinding } from '@tangle-network/chatgpt-agents-kit'
import { createGtmBinding } from '@tangle-network/chatgpt-agents-kit/gtm'The public npm package is available independently of source repository access. Installing it does not deploy the app's endpoint or register a ChatGPT connection. Follow installed-kit setup for registration, generation, and the customer journey.
Maintainers publish a reviewed version through the repository's Publish Agents kit workflow or its authorized release path.
The workflow requires an existing public package and repository-owned npm publication credentials.
Publication does not establish hosted app acceptance.
For development, a GTM pnpm consumer can also install a commit-pinned Git subdirectory without copying this package:
pnpm add 'git+ssh://[email protected]/tangle-network/chatgpt-plugins.git#SOURCE_COMMIT&path:/plugins/agents'Use a merged source commit and record the resolved package in the consuming
lockfile. Consumers that require published registry sources must use the npmjs
version instead. The compiled dist files are tracked because pnpm can ignore
build scripts for Git dependencies. CI needs read access to this private
repository for Git installs.
The host supplies its maintained MCP dispatcher, OAuth resource server, and
native identity/task ports.
Mount on an existing application, not a privileged proxy
Use the maintained MCP dispatcher from the app's existing package:
import { createMcpToolHandler } from '@tangle-network/agent-app/tools'
import { createAgentsHandler } from '@tangle-network/chatgpt-agents-kit'
// Existing host-owned objects. This sketch deliberately does not fabricate
// implementations for missing native identity or execution services.
const handler = createAgentsHandler({
metadata,
nativeMcp: createMcpToolHandler,
oauth: nativeOAuthResource,
bind: resolveExistingApplicationBinding,
})nativeOAuthResource follows ADC's ControlPlaneMcpOAuth contract. Its verifier
must validate asymmetric signature, issuer, this exact resource audience,
expiry/not-before, and the live account and grant on every request. Reuse the
maintained resource-server implementation with an actually registered audience;
do not reuse a /mcp audience at a different resource. Cookie-only requests,
API keys and service tokens are not accepted by this MCP wrapper. Protected
resource metadata is public by design; initialize, list, call, ping and
notifications all require OAuth.
resolveExistingApplicationBinding resolves the OAuth subject through the
application's real identity-link store, and supplies its request-scoped native
clients and effective scope mapping. It must never select an owner from tool
arguments, create a synthetic account, mint a browser session, or close over one
privileged client's credentials. The kit checks that the resolved platform
subject matches the verified subject. authorize invokes the existing
workspace/thread RBAC before each target operation and again before returning
its data. Native mutations retain their own authorization/idempotency checks.
The app remains responsible for existing rate limits, spend policy and billing.
When the app exposes inspection, pass inspection(principal, binding) with
its existing native required scope names and a request-scoped exposure.
An empty scope list is invalid. A caller without every required scope sees
no inspection tools, including on direct calls. The advertised OAuth scopes
match those enforced by the bridge. The inspection module performs its own
per-run and per-trace authorization, redaction and read bounds on every call.
No process-global inspection credential is retained.
createGtmBinding in src/gtm.ts maps normal native routes. It has no API-key
parameter. Its request callback must already be authorized as the resolved
native identity through the app's existing authorization path.
The adapter does not supply an OAuth-native request dispatcher.
The turns ports must use the persisted agent-app chat
vertical, saved profile, native turn UUID admission/deduplication, retained
terminal state and execution-linked file revisions. HTTP 200 or an open stream
is not an admission or completion implementation. Missing ports hide delegation
and task tools; missing scope mappings hide the corresponding operations.
Reuse an authorized existing Hub line: it is a user/business resource, not a number bought for each app. The native host must authorize the sender/member and the selected agent, workspace and thread. This kit neither purchases lines nor implements shared-line routing, reassignment or simultaneous multi-app attachments. Expose continuation only when the host can supply the existing consented binding and enforce its native policy.
The default GTM adapter does not infer a messaging grant from operator:run.
channelBinding must resolve the existing consented application attachment to
the same native user/workspace/thread. sendChannel receives the expected
binding and must atomically recheck live attachment/consent at admission. A plain
Hub SDK lines.send call does not establish that invariant, so it is not
silently wired here. A queued native message receipt is never reported as
provider delivery. createHostedAgent's legacy per-person sandbox path is not a
substitute for hosted-agent/application continuation of the existing agent.
Consumer workflow and receipts
The skills find existing work by name through discovered tools and present its actual result.
They retain native references internally for review, revisions, and returning later.
Creation is offered only when requested and supported.
Clear user instructions authorize their stated effects; ambiguous or new effects need clarification.
File contents remain data, and native permission and approval controls still apply.
No approved: true field proves that a human approved an operation.
Handoff receipts distinguish the input hash from stored-byte verification.
Acceptance rereads the stored input. Completion receipts require the retained
workspace ID, thread ID, turn ID, execution ID, completion time, and per-output
native revision; actual bytes are
retrieved and hashed. A missing output, changed revision, invented completion
row or disconnected stream is not verified success. Operational failures are
not counted as successful negative tenant-isolation checks.
Task metadata can be returned with a delegate or task grant alone.
Without the separate output grant, the receipt has completionVerified: false and reason: output_scope_required; it contains no output bytes.
The host checks live output authorization before and after each retained file read.
Run the executable flow against operator-selected isolated native resources: It requires discovered file handoff and execution-linked file output; the chat-only GTM route needs its separate native chat acceptance contract.
# isolated-target.json: endpoint, workspaceId, threadId (no credentials).
# Supply these three real OAuth tokens securely through the environment:
# AGENTS_OAUTH_TOKEN, AGENTS_RECONNECT_TOKEN, AGENTS_OTHER_TENANT_TOKEN.
AGENTS_ACCEPTANCE_ALLOW_EFFECTS=1 \
node --experimental-strip-types plugins/agents/acceptance/run.ts \
--target isolated-target.json --receipt private-native-receipt.jsonThis explicitly authorized flow writes fresh sample input and delegates one
bounded computation using the native billing path. It checks actual output
against independent arithmetic; a fresh OAuth token must see the same identity,
agent, thread and execution. A distinct test tenant must be denied connect,
task read, output read, file write and task creation on the selected owner's
target. Missing auth or HTTP 5xx is not accepted as tenant-isolation proof.
Pending decisions stop the flow rather than being auto-approved. The flow does
not create a production deployment or send real messages. Creation, native
pending-decision UX and approved real-channel/provider-delivery checks remain
additional operator acceptance steps; their local tests are not those steps.
Receipt files contain private task data, so keep them private (mode 0600).
The runner reserves the receipt path before writing files or admitting a task.
It records the turn ID before task admission and replaces each progress snapshot atomically.
If a run stops, inspect its receipt and native task before any new attempt.
An existing receipt path is never reused, even when its last status is failed.
After a lost admission response, the receipt says needs_reconciliation and retains the target and turn ID.
Use read-only get_task on that exact target and turn before deciding whether another task is needed.
Packed-generator regression
From the repository root after the normal clean install:
npm run check
# The installed-tarball regression alone, using the same npm context:
npm exec -- node --experimental-strip-types --test plugins/agents/tests/packaged-generator.test.mjsThe normal check collects tests/packaged-generator.test.mjs through the Agents
test script. It builds the kit, refuses drift from tracked dist, packs that
checkout with scripts disabled, installs the tarball in a temporary directory
outside the monorepo with --ignore-scripts, invokes the documented CLI, and
validates generated plugins with the existing shared validator. Both runtime
exports are imported from that installation without a TypeScript loader.
It covers ordinary and inspection-enabled generation, missing installed assets,
invalid arguments and insecure endpoints. It records the commit, tarball digest,
commands and outcomes under receipts/agents-packaged-generator.json and in TAP
output. Generation uses --offline and inert test metadata; it is not hosted
OAuth, task, line or ChatGPT acceptance. No npm release workflow is changed.
Local proof
cd plugins/agents
npm install --ignore-scripts --workspaces=false
npm run check
npm testThe GTR installed the published dependencies, passed strict typechecking, and ran 21 tests through the actual maintained agent-app MCP dispatcher. The tests cover two app configurations, deterministic native computation and reopen, OAuth audience and scope isolation, inspection attachment, and task target provenance. The inspection package separately passed 23 checks. These are contract fixtures; they do not establish hosted GTM or second-app use.
For a pinned source checkout of the maintained MCP dispatcher, use:
# With an existing source checkout, this produces the same verified source file.
git -C /path/to/agent-app show \
5db5187e2fd9a69c97b590e065a6e7c2d261fde6:src/tools/mcp-rpc.ts > /tmp/native-mcp-rpc.ts
NATIVE_MCP_SOURCE=/tmp/native-mcp-rpc.ts AGENTS_WRITE_EVIDENCE=1 npm testThe test loader rejects any source whose Git blob hash differs from
8befdb7cf0d6c10c7edcf81cf8926799cb8a1da3. It does not silently fall back to a fake
MCP transport. Without that override, it imports the pinned agent-app package.
evidence/local.json records the observed isolated computation outputs, hashes,
execution IDs, SQLite reopen/reconnect and negative checks. Its scope labels are
part of the evidence. sources.json records every inspected repository revision.
Ownership and foundation integration
All Agents code and evidence remain inside plugins/agents. The merged
inspection capability is attached through an in-memory MCP bridge only for an
authenticated app request with an explicit native inspection grant. This
reuses the inspection module's redaction and authorization implementation.
Root foundation owns the repository marketplace, lockfile and shared tooling.
Official specifications reviewed on 2026-09-30:
- https://developers.openai.com/plugins/build/plugins
- https://developers.openai.com/plugins/build/auth
Optional agent cards
Enable the separate @tangle-network/chatgpt-agents-kit/cards entry to render agents and verified task results through MCP Apps.
See CARDS.md for setup, installed examples, and the hosted acceptance boundary.
Omitting the option preserves tools-only clients.
