Use ChatGPT apps inside OpenClaw.
Prerequisites
- Requires the OpenAI provider with ChatGPT sign-in.
Quickstart
- Clone this repo:
git clone https://github.com/kevinslin/openai-apps.git
cd openai-apps- Install dependencies and the local bundle into OpenClaw:
pnpm install
openclaw plugins install .- Enable the bundle in your OpenClaw config:
- set allow_destructive_actions to
alwaysin order to support write actions (eg. updating google calendar). default isnever
Warning
Enabling write actions (allow_destructive_actions: "always") increases risk. Agent mistakes or prompt-injection attacks can trigger unintended destructive operations (for example, deleting or modifying data in connected apps like email, calendar, or task systems). Keep this set to "never" unless you explicitly accept that risk.
{
"plugins": {
"entries": {
...
"openai-apps": {
"enabled": true,
"config": {
"allow_destructive_actions": "never",
"connectors": {
"*": {
"enabled": true
}
}
}
}
}
}
}- Restart the OpenClaw gateway so plugin config changes are loaded.
- Open your normal OpenClaw chat/TUI session and issue an app-backed request (examples in
Usagebelow).
Usage
summarize my recent emails
add a calendar event reminding me to walk my gerbil tomorrow at 7am for 30 minutes
Configuration
All bundle config lives under plugins.entries["openai-apps"].config.
allow_destructive_actions: Controls destructive app-action elicitations. Use"always"to auto-accept,"on-request"to prompt through the MCP client when supported, or"never"to auto-decline. Defaults to"never".connectors: Per-app enablement map. Use explicit connector ids likegmail,linear, orgoogle_calendar.connectors["*"]: Enables all accessible ChatGPT apps, with explicit connector entries able to disable individual apps.appServer.command/appServer.args: Override how the bundle launchescodex app-server.
Example with one explicitly enabled connector:
{
"plugins": {
"entries": {
"openai": {
"enabled": true
},
"openai-apps": {
"enabled": true,
"config": {
"allow_destructive_actions": "never",
"connectors": {
"gmail": {
"enabled": true
}
}
}
}
}
}
}Wildcard Configuration
To enable all accessible ChatGPT apps, use *:
{
"plugins": {
"entries": {
"openai": {
"enabled": true
},
"openai-apps": {
"enabled": true,
"config": {
"allow_destructive_actions": "never",
"connectors": {
"*": {
"enabled": true
}
}
}
}
}
}
}You can combine wildcard enablement with explicit disables:
{
"plugins": {
"entries": {
"openai-apps": {
"enabled": true,
"config": {
"allow_destructive_actions": "never",
"connectors": {
"*": {
"enabled": true
},
"slack": {
"enabled": false
}
}
}
}
}
}
}Limitations
- Currently, destructive actions do not support on-demand elicitation (dynamic permission prompts). The OpenClaw PI MCP client does not currently support MCP elicitations.
Runtime State
The bundle keeps its runtime state under plugin-runtimes/openai-apps/.
codex-home/: sharedCODEX_HOMEused for both snapshot refresh and per-tool invocationconnectors.snapshot.json: persisted connector records derived fromapp/listrefresh-debug.json: last refresh result/debug payload written by the bundle
Both refresh and invocation launch codex app-server with the same bundle-owned codex-home. Invocation still starts a fresh app-server thread for every tool call, but it now rewrites the derived apps config into the app-server-managed config inside that shared home before starting the turn instead of using a temporary invocation-only home.
Snapshot Shape
The persisted snapshot under plugin-runtimes/openai-apps/connectors.snapshot.json stores
connector-level records derived from app/list. It does not persist raw
inventory or any status payload.
Example:
{
"version": 2,
"fetchedAt": "2026-03-30T18:00:00.000Z",
"projectedAt": "2026-03-30T18:00:00.000Z",
"accountId": "acct_123",
"authIdentityKey": "user@example.com",
"connectors": [
{
"connectorId": "gmail",
"appId": "asdk_app_gmail",
"appName": "Gmail",
"publishedName": "chatgpt_app_gmail",
"appInvocationToken": "gmail",
"description": "Read and send Gmail messages.",
"pluginDisplayNames": ["Gmail"],
"isAccessible": true,
"isEnabled": true
}
]
}Internals
This bundle:
- publishes one local MCP tool per enabled ChatGPT app connector
- uses
codex app-serveras the single authority for both tool publication and invocation - reads OpenClaw-rooted
openai-codexauth and projects it into the spawned app-server session
Published tool names use the chatgpt_app_<connectorId> namespace. Each tool accepts a single natural-language request string and executes the app on a fresh app-server thread.
For more information on plugin internal logic, see flows.
Appendix
Calls to App Server
Setting the developer message
[ { approvalPolicy: { granular: { sandbox_approval: false, rules: false, skill_approval: false, request_permissions: true, mcp_elicitations: true, }, }, developerInstructions: 'You are servicing one OpenClaw connector tool call for Gmail. Use the app mentioned in the user input instead of browsing or relying on unrelated tools. Do not use browser, shell, file, web, image, memory, or unrelated tools. Do not ask follow-up questions. Do not fabricate success. Return only JSON matching the schema {"status":"success|failure","result":"string","error":"string"}.', ephemeral: false, experimentalRawEvents: false, persistExtendedHistory: true, }, ];
Example call
[ { text: "$gmail Summarize my recent emails", text_elements: [], type: "text", }, { name: "Gmail", path: "app://asdk_app_gmail", type: "mention", }, ];