# Understanding .app.json vs .mcp.json in OpenAI Plugins: Configuration Explained

> Learn the distinct roles of .app.json and .mcp.json in OpenAI plugins. Understand how .app.json handles UI and identity, while .mcp.json manages server endpoints and authentication.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: deep-dive
- Published: 2026-06-27

---

**[`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) defines the connected app's identity and UI metadata, while [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) configures the server endpoints and authentication details required for backend communication.**

The `openai/plugins` repository relies on two distinct manifest files to separate concerns between user-facing app presentation and backend server orchestration. Understanding the difference between [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) and [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) is essential for developers building plugins that bridge ChatGPT with external services. These files work in tandem to provide the Codex runtime with both the visual context and technical specifications needed to execute plugin actions.

## What Does .app.json Configure?

The [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) file describes the **connected app**—the ChatGPT application or third-party service that supplies authentication, permissions, and UI metadata. According to the repository structure, this manifest is loaded by the Codex runtime when a user invokes a plugin to discover the app connector ID and surface the app's icon, name, and other interface elements.

The file contains a top-level `apps` object where each key represents an app name and its value contains the **connector ID**. For example, in [`plugins/github/.app.json`](https://github.com/openai/plugins/blob/main/plugins/github/.app.json):

```json
{
  "apps": {
    "github": {
      "id": "connector_76869538009648d5b282a4bb21c3d157"
    }
  }
}

```

This connector ID links the plugin to a specific app registration in the system, enabling the runtime to resolve permissions and display branding correctly.

## What Does .mcp.json Configure?

The [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) file configures the **MCP (Managed Connector Platform) server**, telling the Codex agent where to find the plugin's backend services and how to authenticate requests. While [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) handles identity, this manifest handles the technical implementation of API communication.

The file structure uses a `mcpServers` map containing server configurations with transport types, URLs, and environment variable references for tokens. As implemented in [`plugins/github/.mcp.json`](https://github.com/openai/plugins/blob/main/plugins/github/.mcp.json):

```json
{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/",
      "bearer_token_env_var": "GITHUB_PAT_TOKEN"
    }
  }
}

```

The `bearer_token_env_var` field specifies which environment variable holds the authentication token, allowing the runtime to inject credentials securely without hardcoding them.

## How the Files Work Together

The Codex runtime orchestrates plugin execution by combining information from both manifests in a specific sequence:

1. **User opens a plugin** – The ChatGPT UI reads [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) to display the app’s name, logo, and description from the `apps` configuration.
2. **Plugin requires backend data** – The runtime queries [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) to locate the correct MCP endpoint URL and determine which environment variable contains the bearer token.
3. **Request execution** – The system resolves the app via [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) to obtain the connector ID, then uses the corresponding [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) entry to issue the HTTP request to the backend service.

This separation ensures that UI concerns remain decoupled from server infrastructure, allowing developers to update endpoint URLs without changing app metadata, or vice versa.

## Implementation Examples

When building skills for the OpenAI Plugins repository, you will reference these files to resolve app identities and execute MCP calls.

### Loading the App Connector ID

To access the connector ID defined in [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json):

```typescript
import fs from 'fs';

const appManifest = JSON.parse(fs.readFileSync('.app.json', 'utf8'));
const githubAppId = appManifest.apps.github.id;
// Returns: "connector_76869538009648d5b282a4bb21c3d157"

```

### Calling an MCP Endpoint

To configure a fetch request using [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json):

```typescript
import fetch from 'node-fetch';
import fs from 'fs';

const mcpConfig = JSON.parse(fs.readFileSync('.mcp.json', 'utf8'));
const github = mcpConfig.mcpServers.github;
const token = process.env[github.bearer_token_env_var];

const response = await fetch(`${github.url}some/endpoint`, {
  method: 'POST',
  headers: { 
    Authorization: `Bearer ${token}`, 
    'Content-Type': 'application/json' 
  },
  body: JSON.stringify({ /* payload */ })
});

```

### Complete Skill Integration

A typical skill combines both manifests to resolve the app context before making server calls:

```typescript
async function listRepos() {
  // Resolve app identity
  const appId = JSON.parse(fs.readFileSync('.app.json', 'utf8')).apps.github.id;
  
  // Load MCP configuration and auth
  const { url, bearer_token_env_var } = JSON.parse(
    fs.readFileSync('.mcp.json', 'utf8')
  ).mcpServers.github;
  const token = process.env[bearer_token_env_var];
  
  // Execute backend call
  const res = await fetch(`${url}repos/list`, {
    method: 'GET',
    headers: { Authorization: `Bearer ${token}` }
  });
  return await res.json();
}

```

### Repository References

These implementation patterns appear throughout the repository:

- **[`plugins/github/.app.json`](https://github.com/openai/plugins/blob/main/plugins/github/.app.json)** – App connector manifest for the GitHub plugin
- **[`plugins/github/.mcp.json`](https://github.com/openai/plugins/blob/main/plugins/github/.mcp.json)** – MCP server configuration for GitHub integration
- **[`plugins/linear/.app.json`](https://github.com/openai/plugins/blob/main/plugins/linear/.app.json)** and **[`plugins/linear/.mcp.json`](https://github.com/openai/plugins/blob/main/plugins/linear/.mcp.json)** – Additional examples for the Linear plugin
- **[`.agents/skills/plugin-creator/references/plugin-json-spec.md`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/references/plugin-json-spec.md)** – Specification showing how [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) references both files via `"apps": "./.app.json"` and `"mcpServers": "./.mcp.json"`

## Summary

- **[`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)** specifies the **identity and UI metadata** of the connected app, including connector IDs used by the ChatGPT interface.
- **[`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json)** defines **server endpoints and authentication** for the MCP (Managed Connector Platform), including URLs and environment variable references for tokens.
- The Codex runtime uses [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) for display and permission resolution, and [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) for executing backend HTTP requests.
- Both files are optional but recommended, and are referenced from the main [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) configuration as defined in the plugin creator specifications.

## Frequently Asked Questions

### Can a plugin function with only one of these configuration files?

Yes, a plugin can operate with only [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) if it only needs to display app metadata without making backend calls, or only [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) if it only needs server configuration without specific app branding. However, most production plugins in the `openai/plugins` repository include both to provide a complete user experience.

### What happens if the bearer token environment variable specified in .mcp.json is missing?

The Codex runtime will fail to authenticate the request, resulting in a 401 or 403 error when attempting to reach the MCP server endpoint. The runtime reads the `bearer_token_env_var` field to locate the token, and if the environment variable is undefined, the HTTP request will be sent without authentication headers or with undefined values.

### How do these manifest files relate to the main plugin.json file?

According to the plugin specification in [`.agents/skills/plugin-creator/references/plugin-json-spec.md`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/references/plugin-json-spec.md), the root [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) file contains references to both manifests: `"apps": "./.app.json"` and `"mcpServers": "./.mcp.json"`. This allows the Codex runtime to discover and load the separate configuration files when initializing the plugin.

### Are .app.json and .mcp.json required for all OpenAI plugins?

No, both files are optional. Simple plugins that do not require third-party app integration or external backend services may omit these files entirely. They are specifically required when you need to connect to a specific app identity (via [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)) or communicate with external MCP servers (via [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json)).