Skip to content

[Tracking] ChatGPT plugin: list docs.plus in the OpenAI Plugin Directory #388

Description

@HMarzban

Goal

List docs.plus in the OpenAI Plugin Directory, so any ChatGPT user can find it and add it in one click.

We build no new server. A ChatGPT plugin is a plugin.json package that points at the MCP connector we already run (https://prodback.docs.plus/api/mcp). OpenAI reviews the package once. Then the plugin appears in the directory, on every plan and on mobile.

What exists today

Old ChatGPT plugins (ai-plugin.json) closed in 2024. Nothing from them applies. The current format is the 2026 Plugin Directory package described below.

Before you start (agents)

  • Read AGENTS.md, then apps/hocuspocus.server/CLAUDE.md §MCP Connector.
  • Bun only. Never run npm, npx, yarn or pnpm.
  • Do not commit, push or open a PR unless the maintainer asks.
  • Do not add a password sign-in path. Do not bring back passkeys. Do not add a tool that replaces a whole section or page. These are maintainer rulings in CLAUDE.md and apps/hocuspocus.server/CLAUDE.md §MCP Connector.
  • Never write reviewer credentials into the repo, an issue, or a commit. They go only into the OpenAI dashboard form.
  • Do not claim audience binding anywhere. Supabase always sets aud to authenticated. The token's client_id claim is the gate.

Rulings needed (maintainer)

Rule R2 and R3 before the first submission. After publication, a hint change waits for OpenAI's daily scan, and the old hint stays live until then.

R1. How does the OpenAI reviewer sign in?

The Submit page wants a reviewer account that works "without MFA approval, email or SMS codes, magic links, or private-network access". docs.plus signs in with Google or an email link only. That rules out the email link.

Option Fits OpenAI Fits docs.plus rules
A. A dedicated Google account with 2-Step Verification off Yes, unless Google challenges a new device Yes. No code
B. A password account, or a separate reviewer login route Yes No. It overturns the rule "Never add a password sign-in path"
C. A separate review server No. A listing has one MCP URL n/a

Recommendation: A. Test it the way a reviewer would. Use a fresh browser on a desktop, on a network other than the maintainer's usual one. If Google shows a device challenge, A fails, and the maintainer must rule on B.

  • R1 ruled

R2. openWorldHint on the five read tools

Today all five read tools set false. OpenAI says to use true for "public or open-ended entities", and that connectivity alone does not decide it. find_documents with scope: "public" searches anyone's public documents. The other four read tools can open those documents too.

Recommendation: true on all five.

  • R2 ruled

R3. destructiveHint on post_chat_message

Today it is false. OpenAI uses true for irreversible sends, and says undo alone does not justify false. A post can notify members who are away, and a notification cannot be recalled.

Recommendation: true. ChatGPT then asks the person to confirm before a post that other people will see.

create_document notifies no users. append_to_document, edit_blocks and replace_text produce batched digest notices to followers through the normal save path. That is the same path a person's edit takes, so this issue changes nothing for them.

  • R3 ruled

Work plan

Each step has an owner: M (maintainer), C (code agent), O (ops).

Step 0. Ship what is built

Done when ChatGPT lists edit_blocks and replace_text, and all three live calls pass.

Step 1. Prove the connector in ChatGPT

  • M Run the ChatGPT part of Test the MCP connector in three AI apps, then finish its connect guide #357. Remove the <!-- PENDING-HOST-TEST: ChatGPT --> marker in docs/mcp/README.md (§Connect in ChatGPT) when it passes.
  • M Make one write call on the maintainer's own plan. Two OpenAI pages disagree on whether Plus and Pro can call write tools in developer mode. Only a live call settles it.

Done when every tool has run once in ChatGPT, and the plan's write limit is known.

Step 2. Code work (C)

Start only after the #329 fix is on main. Until then, main still has replace_section, and these files do not match this issue.

Tool hints (after R2 and R3). No test asserts a hint today. typecheck is the only automated check.

  • apps/hocuspocus.server/src/modules/mcp/tools/documentTools.ts: openWorldHint on find_documents, get_outline and read_document.
  • apps/hocuspocus.server/src/modules/mcp/tools/chatTools.ts: openWorldHint on list_chat_rooms and read_chat_thread. Set destructiveHint on post_chat_message, and rewrite the comment above it ("A post only adds…").
  • Update every doc that states the hints:
    • docs/mcp/reference.md: the hints prose, the Hints column, and the post_chat_message note.
    • apps/hocuspocus.server/API.md: the tool table and the Hints. paragraph.
    • apps/hocuspocus.server/CHANGELOG.md: the Tool hints follow the MCP and OpenAI definitions. paragraph under ## [Unreleased]. It is not published yet, so edit it in place.

Plugin package.

  • Add a folder integrations/openai-plugin/ with plugin.json, mcp.json and assets/logo.png. The folder sits outside the workspace globs and outside docs/. Add no package.json.
  • Copy the logo from apps/webapp/public/icons/icon-192x192.png. Do not use a maskable_* icon.
  • Do not add an apps field, a .app.json file, lifecycle hooks, test_credentials or reviewer_instructions. OpenAI refuses a package that has any of them. Plugin Creator output contains .app.json, so do not submit it as it is.
  • Run bun run check once, to confirm the lint and format gates accept the new JSON. If Prettier fails, run bun run format:fix, then check again.

Package skeleton (only 1 positive and 1 negative case shown; the full set is below):

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "docs-plus",
  "version": "1.0.0",
  "description": "Find, read, create and edit your docs.plus documents and their heading chats.",
  "extensions": {
    "com.openai": {
      "interface": {
        "displayName": "docs.plus",
        "shortDescription": "Read and edit your documents",
        "longDescription": "<at most 4000 characters>",
        "developerName": "<must match the verified OpenAI identity>",
        "category": "Productivity",
        "websiteURL": "https://docs.plus",
        "supportURL": "https://github.com/docs-plus/docs.plus/issues",
        "privacyPolicyURL": "https://docs.plus/privacy",
        "termsOfServiceURL": "https://docs.plus/terms",
        "defaultPrompt": ["Find my docs.plus document called Launch plan and show me its outline."],
        "logo": "./assets/logo.png"
      },
      "review": {
        "test_cases": {
          "positive": [
            {
              "description": "Find a document and show its outline",
              "prompt": "Find my docs.plus document called Launch plan and show me its outline.",
              "tools_triggered": "find_documents, get_outline",
              "expected_behavior": "Shows the heading tree of Launch plan."
            }
          ],
          "negative": [
            { "description": "No document is needed", "prompt": "Write a short poem about autumn." }
          ]
        },
        "demo_recording_url": "<public video URL>"
      },
      "publication": { "release_notes": "First release." }
    }
  }
}
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "docs-plus": { "type": "streamable-http", "url": "https://prodback.docs.plus/api/mcp" }
  }
}

Field rules from the Submit page:

  • name: at most 64 characters. Lowercase letters, numbers and single hyphens.
  • displayName and shortDescription: at most 30 characters each. longDescription: at most 4000. developerName: at most 80.
  • The display name must not add "MCP" or "Plugin". Do not list it as "docs.plus for ChatGPT", because that can read as an OpenAI endorsement.
  • tools_triggered is one string, not an array.
  • defaultPrompt: up to 3, at most 128 characters each, with no @ mentions.
  • Leave out screenshots. That field is only for plugins that return UI.
  • Leave out publication.countries on the first upload.

Review test cases. The first review needs exactly 5 positive and 3 negative cases. These are drafts for the maintainer to approve. They assume the reviewer account owns a Launch plan document with Budget, Risks and Timeline headings. The Timeline body holds the text Q3 exactly once. The Timeline chat room holds a few messages.

# Prompt tools_triggered
P1 Find my docs.plus document called Launch plan and show me its outline. find_documents, get_outline
P2 Summarize the Risks section of my Launch plan document. find_documents, read_document
P3 Create a docs.plus document called Meeting notes with the headings Agenda and Actions. create_document
P4 In Launch plan, change "Q3" to "Q4" in the Timeline section, and add a short risk at the end of Risks. find_documents, read_document, replace_text, edit_blocks
P5 What did people say in the Timeline chat of Launch plan? find_documents, list_chat_rooms, read_chat_thread
N1 Write a short poem about autumn. none
N2 What is the capital of France? none
N3 Open my Google Doc called Budget. none

Domain token.

  • The maintainer posts the dashboard token on this issue. The file serves it publicly, so it is not a secret. Add it as plain text at apps/webapp/public/.well-known/openai-apps-challenge. apps/webapp/public/.well-known/security.txt is the precedent. apps/webapp/src/proxy.ts already skips .well-known, so do not edit it. A (build): front deploy then serves the file at https://docs.plus/.well-known/openai-apps-challenge.
  • Check that the response is the bare token as text/plain. If Next sends another type, add a header in apps/webapp/next.config.js headers(), as /robots.txt does.

Privacy page.

  • M rules how long the per-call record is kept. C then adds one sentence to apps/webapp/src/pages/privacy.tsx. The page already says a connected app gets name, profile picture and email, and never a phone number.

Before a public listing.

Checks for code agents:

cd apps/hocuspocus.server && env -u REDIS_HOST bun test src/modules/mcp src/modules/document-content/__tests__/unit
bun run --filter @docs.plus/hocuspocus typecheck
bun run check:push

Step 3. Account work (M)

  • Complete individual or business verification in the OpenAI organization. The directory shows the verified name, whatever the package says.
  • Use a project with global data residency. Projects with EU data residency cannot submit MCP plugins for now.
  • Make sure the submitter is an organization owner or holds "Apps Management Write" (api.apps.write on the Review page).
  • Create the reviewer account (R1) and its sample data for P1–P5. Keep both live for later reviews. After each P4 run, change Q4 back to Q3, and remove the added risk.
  • Record the demo video. Show the main tools. OpenAI asks for every supported platform, and a published plugin must work on mobile. Developer mode is web only, so a mobile recording may not be possible before publication. Say so in the review notes.
  • Zip integrations/openai-plugin/ for upload. Check the root layout against Package your plugin.
  • Approve the listing text: description, category, default prompts, release notes.

Done when the dashboard shows no open finding before Submit for review.

Step 4. Submit and review (M)

  • Upload the ZIP at https://platform.openai.com/plugins. Run the tool scan. Enter reviewer credentials in the dashboard form only.
  • Submit. OpenAI publishes no review time. Plan for at least one rejection cycle. To appeal, reply to the rejection email.
  • After approval, press Publish plugin.
  • Post the directory link here. Add it to docs/mcp/README.md. Add it to Settings > Connected apps (apps/webapp/src/components/settings/components/ConnectedAppsSection.tsx) after the brand-rules open question is settled.

After publication, OpenAI scans the server daily. A new tool stays unavailable until it is approved. A change to metadata or assets needs a new ZIP and a new review. A change to the MCP URL needs OpenAI support.

Out of scope

Acceptance

  • R1, R2 and R3 are ruled on this issue.
  • Production lists the positioned-edit tools, and every tool has run once in ChatGPT.
  • The hint changes, the package folder, the domain token and the privacy sentence have landed.
  • The plugin is published, and its directory link is posted here.

Open questions

Question How to settle it
Can Plus and Pro call write tools in developer mode? One write call on the maintainer's plan (Step 1)
Does Google challenge a fresh device for an account with 2-Step Verification off? A live test from a fresh browser, on a network other than the maintainer's usual one
Does Google sign-in work in the ChatGPT mobile OAuth sheet? Probably not testable before publication. Mention it in the review notes
Does OpenAI accept docs.plus as the parent domain of prodback.docs.plus? The dashboard's domain check
Does hosted Supabase Auth advertise CIMD or RFC 9207 iss? Local Auth does not, so ChatGPT uses DCR and a per-connector redirect URI, which works today Read the hosted discovery document
What do OpenAI's brand rules allow for "Add to ChatGPT" wording? Open https://openai.com/brand/ in a browser before changing Settings copy

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions