Skip to content

Commit 008951a

Browse files
authored
docs: Add submission checklist and guidelines for ChatGPT MCP Apps (#581)
1 parent b44b750 commit 008951a

7 files changed

Lines changed: 185 additions & 1013 deletions

res/TODO-mcp-apps-migration.md

Lines changed: 0 additions & 57 deletions
This file was deleted.

res/chatgpt-app-submission.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# ChatGPT MCP Apps Submission
2+
3+
Status: **In Progress**
4+
Last updated: 2026-03-12
5+
6+
## Prerequisites
7+
8+
- [ ] Organization verification (individual or business) on [OpenAI Platform Dashboard](https://platform.openai.com/settings/organization/general)
9+
- [ ] Owner role confirmed for submitting org member
10+
- [x] MCP server publicly accessible at `https://mcp.apify.com/`
11+
- [x] Not using local/testing endpoint
12+
- [x] Content Security Policy (CSP) defined (`src/resources/widgets.ts:15-26`)
13+
- [x] Authentication configured — Bearer token + OAuth2 (`src/server_card.ts:30-33`)
14+
15+
## Submission Form Fields
16+
17+
| Field | Status | Value |
18+
|---|---|---|
19+
| App name | Done | `Apify MCP server` |
20+
| Logo | Done | `docs/apify-logo.png` |
21+
| Short description | Done | "Extract data from any website with thousands of scrapers, crawlers, and automations on Apify Store" |
22+
| Long description | Done | "Extract data from any website using thousands of tools from the Apify Store. Apify is the world's largest marketplace of tools for web scraping, data extraction, and web automation." |
23+
| Privacy policy URL | Done | https://docs.apify.com/legal/privacy-policy |
24+
| Company URL | Done | https://apify.com |
25+
| MCP URL | Done | https://mcp.apify.com/ |
26+
| Screenshots | TODO | Need ChatGPT-specific screenshots showing widgets in action |
27+
| Test prompts & responses | TODO | Need 3-5 test cases (see below) |
28+
| Localization / countries | TODO | Define target countries |
29+
30+
## Code Changes Needed
31+
32+
- [ ] Add explicit `destructiveHint: false` to ~19 read-only tools that currently omit it (should be explicit per OpenAI guidelines). Affected tools: all `get_*`, `search_*`, `fetch_*` in `src/tools/common/` and `src/tools/core/`.
33+
34+
## Tool Hint Annotations Audit
35+
36+
Per [OpenAI guidelines](https://developers.openai.com/apps-sdk/deploy/submission), tool annotations must match actual behavior.
37+
38+
### Correctly annotated (no changes needed)
39+
40+
| Tool | readOnlyHint | destructiveHint | openWorldHint | Rationale |
41+
|---|---|---|---|---|
42+
| `call-actor` (both modes) | false | true | true | Runs Actors that can modify external state |
43+
| Dynamic Actor tools | false | true | true | Same as call-actor |
44+
| `abort-actor-run` | false | true | false | Irreversible abort within Apify platform |
45+
| `add-actor` | false | false | true | Reads from public Apify Store, modifies local tool list |
46+
| `get-html-skeleton` | true || true | Reads from arbitrary external URLs via Actor |
47+
| `search-actors` | true || false | Searches Apify Store (read-only) |
48+
| `fetch-actor-details` | true || false | Reads Actor metadata |
49+
| `get-actor-run` | true || false | Reads run status |
50+
| `get-actor-output` | true || false | Reads dataset items |
51+
| `get-dataset-items` | true || false | Reads dataset items |
52+
| `get-dataset` | true || false | Reads dataset metadata |
53+
| `get-dataset-schema` | true || false | Reads items for schema |
54+
| `get-actor-run-log` | true || false | Reads run logs |
55+
| `get-key-value-store-record` | true || false | Reads stored records |
56+
| `get-key-value-store` | true || false | Reads store metadata |
57+
| `get-key-value-store-keys` | true || false | Lists keys |
58+
| `get-user-runs-list` | true || false | Lists runs |
59+
| `get-user-datasets-list` | true || false | Lists datasets |
60+
| `get-user-key-value-stores-list` | true || false | Lists stores |
61+
| `search-apify-docs` | true || false | Searches documentation |
62+
| `fetch-apify-docs` | true || false | Fetches documentation |
63+
64+
> **Note:** "—" in destructiveHint means the field is currently omitted and needs to be explicitly set to `false`.
65+
66+
## Privacy / PII Audit
67+
68+
- [x] No unnecessary PII in tool responses — tools return public resource IDs (runId, datasetId), not internal/private data
69+
- [x] No session/trace/request IDs leaked — `mcpSessionId` is logging-only, never in tool responses
70+
- [x] API tokens never exposed in responses — used internally only
71+
- [x] Skyfire tokens redacted in logs (`src/utils/logging.ts:56-80`)
72+
- [ ] Verify privacy policy explicitly covers all data categories returned by tools (run metadata, dataset items, Actor details)
73+
74+
## Widgets
75+
76+
| Widget | URI | ChatGPT Status | Mobile Status |
77+
|---|---|---|---|
78+
| Search Actors | `ui://widget/search-actors.html` | Confirmed working | TODO |
79+
| Actor Run | `ui://widget/actor-run.html` | TODO | TODO |
80+
81+
- [x] CSP configured for all widgets (`api.apify.com`, `mcp.apify.com`, image CDNs, Google Fonts)
82+
- [x] Pure MCP Apps SDK — no legacy `window.openai` fallbacks
83+
- [x] `openai/toolInvocation/*` UX hints configured (invoking/invoked messages)
84+
- [x] `openai/outputTemplate` intentionally NOT included (breaks MCP Apps renderer detection in MCP Jam)
85+
86+
## Test Cases (TODO)
87+
88+
Need to prepare test prompts with expected responses. Suggested cases:
89+
90+
### Test 1: Search for Actors
91+
- **Prompt:** "Find web scraping tools on Apify"
92+
- **Expected:** Search widget renders with list of relevant Actors (web scraping category)
93+
- **Tools invoked:** `search-actors`
94+
95+
### Test 2: Get Actor details
96+
- **Prompt:** "Tell me about the apify/web-scraper Actor"
97+
- **Expected:** Actor name, description, pricing, input schema summary
98+
- **Tools invoked:** `fetch-actor-details`
99+
100+
### Test 3: Run an Actor
101+
- **Prompt:** "Scrape the homepage of https://example.com using apify/web-scraper"
102+
- **Expected:** Actor Run widget shows run progress, completes with results
103+
- **Tools invoked:** `call-actor` (or dynamic Actor tool)
104+
105+
### Test 4: Get run results
106+
- **Prompt:** "Show me the results from my last run"
107+
- **Expected:** Dataset items displayed
108+
- **Tools invoked:** `get-user-runs-list`, `get-actor-output`
109+
110+
### Test 5: Abort a run
111+
- **Prompt:** "Stop the currently running Actor"
112+
- **Expected:** Run aborted, confirmation message
113+
- **Tools invoked:** `abort-actor-run`
114+
115+
## Common Rejection Reasons (from OpenAI docs)
116+
117+
Watch out for these during testing:
118+
119+
1. **MCP server unreachable** — Ensure `https://mcp.apify.com/` is stable and reachable
120+
2. **Test credentials don't work** — If OAuth is used, provide demo account without MFA
121+
3. **Test cases produce wrong results** — Verify all test cases pass on both web AND mobile
122+
4. **Undisclosed data types in privacy policy** — Audit all tool responses for user-related fields
123+
5. **Tool annotations don't match behavior** — Already audited above, need to add missing `destructiveHint: false`
124+
125+
## Architecture Notes
126+
127+
- Server runs as Apify Actor with Streamable HTTP transport
128+
- Public URL: `https://mcp.apify.com/`
129+
- Package: `@apify/actors-mcp-server` (v0.9.8)
130+
- Server card: SEP-1649 compliant
131+
- Widget metadata: MCP Apps standard (SEP-1865)
132+
- ChatGPT connects with `ui=openai` server mode
133+
- `stripWidgetMeta()` removes `openai/*` and `ui` keys in non-OpenAI mode

res/index.md

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This directory contains useful documents and insights about the repository archi
44

55
## Files
66

7-
### [algolia-analysis.md](./algolia.md)
7+
### [algolia.md](./algolia.md)
88
Technical analysis of Algolia search API responses for each documentation source.
99
- Data structure overview for each doc source (apify, crawlee-js, crawlee-py)
1010
- Field availability patterns (content, hierarchy, anchors)
@@ -31,32 +31,10 @@ Implementation plan for migrating from low-level `Server` to high-level `McpServ
3131
- **Use case**: Reference for implementing the MCP SDK migration
3232

3333
### [mcp_resources_analysis.md](./mcp_resources_analysis.md)
34-
Current MCP resources behavior and constraints (Skyfire readme and OpenAI widgets).
35-
- Handler locations and low-level MCP usage
34+
MCP resources behavior and constraints (Skyfire readme and UI widgets), low-level `Server` API usage.
35+
- Handler wiring and delegation to `resource_service`
3636
- Resource list/read behavior and error handling
37-
- **Use case**: Baseline reference before refactoring resources
38-
39-
### [mcp_resources_refactor_analysis.md](./mcp_resources_refactor_analysis.md)
40-
Refactor plan for modularizing existing resource handling (no new resources).
41-
- Minimal resource service API (list/read/templates)
42-
- Behavior-preserving steps and non-goals
43-
- **Use case**: Step-by-step guide for refactoring without behavior change
44-
45-
### [tool_mode_separation_plan.md](./tool_mode_separation_plan.md)
46-
Implementation plan for separating UI-mode (OpenAI) and normal-mode tool behavior into independent modules.
47-
48-
**Key approach:** Actor Executor pattern + separate tool definitions per mode + shared core logic layer.
49-
50-
**Estimated effort:** 6-10 developer days
51-
52-
- Design decisions table (actor-mcp passthrough, Skyfire freeze, task lifecycle, etc.)
53-
- Three-layer architecture (core → registry → mode-specific tools)
54-
- Actor Executor pattern for direct actor tools (`type: 'actor'`) mode awareness
55-
- Tool definition immutability via `Object.freeze` (Skyfire safety)
56-
- Mode-aware category registry eliminating deep-clone hack
57-
- 5-phase migration plan with chained PR strategy (7 PRs)
58-
- Directory structure and complete file manifest with PR assignments
59-
- **Use case**: Reference for implementing the UI/normal mode tool separation
37+
- **Use case**: Baseline for how resources are exposed and why
6038

6139
### [patterns_for_simplification.md](./patterns_for_simplification.md)
6240
Analysis of patterns from the **official TypeScript MCP SDK** and **FastMCP** framework that could simplify the codebase.
@@ -78,6 +56,14 @@ Analysis of patterns from the **official TypeScript MCP SDK** and **FastMCP** fr
7856
- Benefits for each pattern
7957
- **Use case**: Reference for incremental codebase improvements
8058

59+
### [web-widget-bundle-size.md](./web-widget-bundle-size.md)
60+
Notes on keeping widget bundles small (narrow `@apify/ui-library` imports, markdown stack cost).
61+
- **Use case**: When changing widget dependencies or markdown rendering, re-measure bundle impact
62+
63+
### [chatgpt-app-submission.md](./chatgpt-app-submission.md)
64+
Checklist and notes for ChatGPT MCP Apps store submission (verify line references against current source before relying on them).
65+
- **Use case**: Submission prep and audits
66+
8167
---
8268

8369
## Purpose

res/mcp_resources_refactor_analysis.md

Lines changed: 0 additions & 127 deletions
This file was deleted.

0 commit comments

Comments
 (0)