🥞PancakeJS

Publishing to App Directories

Building a great chat app is only half the journey. Publishing it to AI host directories like the ChatGPT App Store gives your app access to hundreds of millions of users. This guide covers the submission process, requirements, and best practices for getting your app approved.

The Opportunity

AI assistants have rapidly become primary interfaces for millions of users:

  • ChatGPT alone has over 800 million weekly active users
  • Claude and other AI assistants are growing rapidly
  • Users are increasingly comfortable completing tasks through conversation

Getting your app into these directories means reaching an audience that's actively looking for tools to help them accomplish goals, without the friction of traditional app discovery.

Unlike traditional app stores where users browse and download, AI app directories work differently. Users discover your app when the AI suggests it for relevant tasks, or when they explicitly invoke it.

Preparation Checklist

Before starting the submission process, ensure you have everything ready:

Technical Requirements

  • Production MCP Server: Hosted remotely on HTTPS
  • Domain Verification: Ability to place verification tokens
  • OAuth Integration: If your app requires authentication
  • Tool Annotations: Proper metadata on all tools
  • Content Security Policy: Declared domains for network access
  • Privacy Policy: Publicly accessible URL
  • Terms of Service: Publicly accessible URL
  • Support Contact: Email or page for user support
  • Business Verification: Platform account verification

Assets

  • App Logo: Multiple sizes, light and dark variants
  • Screenshots: 3-4 high-quality images of your widget
  • Demo Video: Showing app capabilities in action
  • Description Copy: Short and long form descriptions

Testing

  • Positive Test Cases: 5+ scenarios showing intended use
  • Negative Test Cases: 3+ scenarios showing boundary behavior
  • Test Account: If authentication is required

Submission Process

Configure Your MCP Server for Production

Ensure your server is production-ready:

import { createUniversalServerApp } from '@pancakeapps/server';

const app = createUniversalServerApp({
  name: 'your-app',
  version: '1.0.0',
  // Production settings
  auth: {
    type: 'oauth2',
    clientId: process.env.OAUTH_CLIENT_ID,
    authorizationUrl: 'https://your-service.com/oauth/authorize',
    tokenUrl: 'https://your-service.com/oauth/token',
    scopes: ['read', 'write'],
  },
});

// Ensure all tools have proper annotations
app.tool({
  name: 'get_user_data',
  description: 'Fetch user profile and preferences',
  annotations: {
    readOnlyHint: true,        // Doesn't modify data
    openWorldHint: false,      // Only accesses your service
    destructiveHint: false,    // No destructive actions
  },
  inputSchema: userDataSchema,
}, handler);

Add Domain Verification

Host platforms require you to verify domain ownership. You'll need to place a verification token at a well-known path:

// Add verification endpoint
app.get('/.well-known/openai-apps-challenge', (req, res) => {
  res.send(process.env.VERIFICATION_TOKEN);
});

Or if using the PancakeJS server:

const app = createUniversalServerApp({
  name: 'your-app',
  verification: {
    openai: process.env.OPENAI_VERIFICATION_TOKEN,
    // Add other platforms as they become available
  },
});

Prepare Tool Annotations

Every tool needs proper annotations that honestly describe its behavior:

AnnotationMeaningExample
readOnlyHintTool doesn't modify its environmentFetching weather data
openWorldHintTool interacts with external entitiesWeb search, public APIs
destructiveHintTool performs destructive actionsDeleting files, canceling orders
app.tool({
  name: 'delete_item',
  description: 'Remove an item from the user\'s collection',
  annotations: {
    readOnlyHint: false,      // Modifies data
    openWorldHint: false,     // Only your service
    destructiveHint: true,    // Destructive action
  },
  inputSchema: z.object({
    itemId: z.string(),
  }),
}, async (input) => {
  await deleteItem(input.itemId);
  return textResult('Item deleted successfully');
});

Be honest with annotations. Reviewers verify these claims, and misrepresentation can result in rejection or removal.

Create Test Cases

Prepare comprehensive test cases that reviewers will use to validate your app:

Positive Test Cases (5+ required)

Each case needs:

  • Scenario description
  • Exact user prompt
  • Expected tool invocation
  • Expected output format
{
  "positive_cases": [
    {
      "scenario": "Search for Italian restaurants",
      "prompt": "Find Italian restaurants near Times Square under $50",
      "expected_tool": "search_restaurants",
      "expected_output": {
        "restaurants": [
          {
            "name": "string",
            "cuisine": "Italian",
            "price_range": "$$",
            "location": "string"
          }
        ]
      }
    },
    {
      "scenario": "Make a reservation",
      "prompt": "Book a table for 4 at Carmine's tomorrow at 7pm",
      "expected_tool": "make_reservation",
      "expected_output": {
        "confirmation": "string",
        "restaurant": "Carmine's",
        "party_size": 4,
        "time": "string"
      }
    }
  ]
}

Negative Test Cases (3+ required)

Show what's outside your app's scope:

{
  "negative_cases": [
    {
      "scenario": "Request outside domain",
      "prompt": "Find hotels near Times Square",
      "reason": "App only handles restaurant searches, not hotels"
    },
    {
      "scenario": "Unsupported action",
      "prompt": "Cancel my Uber ride",
      "reason": "App doesn't integrate with Uber"
    }
  ]
}

Prepare Visual Assets

App Logo

  • 64×64 pixels minimum
  • Light and dark variants
  • Clear at small sizes
  • No text in logo (use app name instead)

Screenshots

  • 3-4 high-quality screenshots
  • Show your widget in action
  • Don't include chat interface elements (they'll be added)
  • Demonstrate key features

Demo Video

  • Keep it short (60-90 seconds)
  • Show complete workflows
  • Include all platforms (web, mobile if applicable)
  • Demonstrate value proposition quickly

Submit for Review

Access the submission portal for your target platform and complete the form:

App Information

  • App name (this is how users will invoke it)
  • Short description (one-liner for listings)
  • Long description (detailed features and use cases)
  • Category selection
  • Developer name and website

Legal Links

  • Privacy policy URL
  • Terms of service URL
  • Support contact

Technical Configuration

  • MCP server URL
  • Domain verification
  • Test credentials
  • Test cases

Assets

  • Logo uploads
  • Screenshots
  • Demo video link

Review Terms

  • Agree to platform guidelines
  • Confirm no prohibited content
  • Verify business account

Review Guidelines

Platforms review apps across several dimensions:

Safety & Privacy

  • Data handling: What data do you collect? How is it stored?
  • Permissions: Do you request only necessary permissions?
  • Authentication: Is OAuth properly implemented?
  • CSP: Are network permissions appropriately scoped?

Functionality

  • Tool behavior: Do tools work as described?
  • Error handling: Does the app handle edge cases gracefully?
  • Performance: Is the app responsive?
  • Reliability: Does the app consistently work?

User Experience

  • Widget design: Is the UI clear and usable?
  • Theme support: Does the widget respect host themes?
  • Responsiveness: Does the widget work at different sizes?
  • Accessibility: Is the widget accessible?

Content Policies

  • No prohibited content: No illegal, harmful, or deceptive content
  • No ads: Advertising is typically not allowed in widgets
  • Payment restrictions: Digital goods payments may be restricted
  • Age-appropriate: Additional review for children-targeted apps

Best Practices for Approval

Write Clear Descriptions

Your description helps both reviewers and users understand your app:

❌ Bad: "Restaurant app with lots of features"

✅ Good: "Find and book restaurants based on cuisine, 
location, and budget. Search thousands of restaurants, 
read reviews, view menus, and make reservations, 
all without leaving the conversation."

Scope Appropriately

Apps with focused functionality are easier to review and more likely to be approved:

❌ "Do everything" app that tries to handle many domains
✅ "Restaurant finder" that does one thing excellently

Test Thoroughly

Before submitting:

  1. Test all positive scenarios work correctly
  2. Verify negative scenarios are handled gracefully
  3. Check widget renders correctly in light and dark themes
  4. Ensure error states have helpful messages
  5. Validate on different viewport sizes

Provide Clear Test Instructions

Make it easy for reviewers:

Test Account:
- Email: test@example.com
- Password: SecureTestPass123

Test Scenarios:
1. Search for "sushi near downtown Seattle" → Should show ~10 results
2. Click any restaurant → Should show details widget
3. Click "Book Table" → Should show reservation form
4. Submit with party size 2, tomorrow 7pm → Should show confirmation

Platform-Specific Notes

ChatGPT App Directory

Requirements:

  • OpenAI Platform account with business verification
  • Adherence to OpenAI's Apps SDK UI guidelines
  • Video demo required

Restrictions:

  • No ads in widgets
  • Digital goods payments not currently supported
  • Physical goods sales allowed with proper verification

Timeline:

  • Review typically takes 1-2 weeks
  • You'll receive feedback if changes are needed

Submission URL: Access through your OpenAI Platform account dashboard

MCP Apps Ecosystem

MCP Apps is an open standard, so the submission process varies by host:

Claude Desktop:

  • Currently supports local and remote MCP servers
  • No centralized app directory yet
  • Users add servers manually via config

Other Hosts:

  • Check individual host documentation
  • Standards are evolving as the ecosystem matures

Current Best Practice:

  • Build your MCP server following the spec
  • Document installation instructions
  • Distribute through your own channels
  • Monitor for host-specific app stores

Post-Approval

Once your app is approved:

Monitor Performance

  • Track usage patterns
  • Monitor error rates
  • Collect user feedback

Iterate and Update

  • Fix bugs promptly
  • Add requested features
  • Improve based on feedback

Manage Versions

const app = createUniversalServerApp({
  name: 'your-app',
  version: '1.1.0', // Bump for updates
});

Significant updates may require re-review. Minor bug fixes usually don't.

Common Rejection Reasons

Learn from common mistakes:

IssueHow to Avoid
Missing privacy policyEnsure URL is public and accessible
Incorrect tool annotationsVerify annotations match actual behavior
Widget doesn't support dark themeTest in both themes before submitting
Unclear app purposeWrite a specific, focused description
Failed test casesValidate all test scenarios work
Missing error handlingTest edge cases and network failures
CSP too broadRequest only domains you actually need

Next Steps

On this page