Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions docs/resources/(resources)/codex-app.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: codex-app
description: A reference page for the codex-app resource
---

The codex-app resource installs the [Codex desktop app](https://developers.openai.com/codex/app) — OpenAI's "Codex command center" for managing coding agent threads, projects, and worktrees. It is a thin wrapper around the Homebrew cask install; the app shares its login, configuration, and MCP servers with the [`codex`](/docs/resources/codex/codex) CLI and IDE extension via `~/.codex/config.toml`.

This resource is **macOS only**. The Codex desktop app is also available on Windows via the Microsoft Store, but is not yet available on Linux.

## Parameters

This resource has no configurable parameters — it manages installation only.

## Example usage

```json title="codify.jsonc"
[
{
"type": "codex-app",
"os": ["macOS"]
}
]
```

### Install the CLI and the desktop app together

```json title="codify.jsonc"
[
{
"type": "codex",
"os": ["macOS"]
},
{
"type": "codex-app",
"os": ["macOS"]
}
]
```

## Notes

- Installed via `brew install --cask codex-app` to `/Applications/Codex.app`.
- The desktop app, CLI, and IDE extension all read and write `~/.codex/config.toml` and share the same login session — use the [`codex`](/docs/resources/codex/codex) resource to manage settings and MCP servers declaratively.
110 changes: 110 additions & 0 deletions docs/resources/(resources)/codex-project.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: codex-project
description: A reference page for the codex-project resource
---

The codex-project resource manages **per-project** Codex configuration. It writes a project-scoped `AGENTS.md`, settings, and MCP servers under a specific directory — leaving global configuration untouched. Use it alongside the [`codex`](/docs/resources/codex/codex) resource, which handles installation.

## Parameters

- **directory**: *(string, required)* Path to the project directory. Configuration files are written relative to this path:
- `<directory>/AGENTS.md`
- `<directory>/.codex/config.toml`

- **agentsMd**: *(string, optional)* Content for `<directory>/AGENTS.md`. Accepts inline text, an `https://` URL, or a `codify://documentId:fileId` cloud URL. Codex walks from the project root down to the current working directory and concatenates any `AGENTS.md` files it finds, using them as project-specific instructions.

- **config**: *(object, optional)* Key-value pairs to merge into `<directory>/.codex/config.toml`. On apply, the declared keys are written; on destroy, only the declared keys are removed. Supports the same keys as the global config, e.g. `model`, `approval_policy`, `sandbox_mode`, `sandbox_workspace_write`.
- Note: Codex ignores `model_provider`, `openai_base_url`, `notify`, `otel`, and `profiles` in project-level config files for security reasons.

- **mcpServers**: *(array, optional)* MCP servers to register for this project under `[mcp_servers]` in `<directory>/.codex/config.toml`. Each entry requires a `name` and `type`, plus transport-specific fields:
- **stdio**: `{ name, type: "stdio", command, args?, env?, envVars?, cwd?, startupTimeoutSec?, toolTimeoutSec? }` — local process server
- **http**: `{ name, type: "http", url, bearerTokenEnvVar?, httpHeaders? }` — remote streamable-HTTP server

## Example usage

### Per-project AGENTS.md and sandbox policy

```json title="codify.jsonc"
[
{
"type": "codex-project",
"directory": "~/projects/my-api",
"agentsMd": "# Project Instructions\n\nThis is a Node.js API. Always use async/await.\nRun `npm test` before committing.",
"config": {
"sandbox_mode": "workspace-write",
"approval_policy": "on-request"
}
}
]
```

### Per-project AGENTS.md with an MCP server

```json title="codify.jsonc"
[
{
"type": "codex-project",
"directory": "~/projects/my-api",
"agentsMd": "# Project Instructions\n\nAlways check types with `npm run typecheck` before submitting.",
"mcpServers": [
{
"name": "project-db",
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
}
]
}
]
```

### Per-project AGENTS.md from a remote URL

```json title="codify.jsonc"
[
{
"type": "codex-project",
"directory": "~/projects/my-api",
"agentsMd": "codify://my-document-id:my-file-id"
}
]
```

Or from a public HTTPS URL:

```json title="codify.jsonc"
[
{
"type": "codex-project",
"directory": "~/projects/my-api",
"agentsMd": "https://raw.githubusercontent.com/my-org/dotfiles/main/AGENTS.md"
}
]
```

### Global install + per-project config together

```json title="codify.jsonc"
[
{
"type": "codex",
"config": {
"model": "gpt-5.1-codex"
}
},
{
"type": "codex-project",
"directory": "~/projects/my-api",
"agentsMd": "# My API\n\nNode.js + TypeScript. Run `npm test` before any commit."
}
]
```

## Notes

- The `codex` resource must be applied before `codex-project` (it declares a dependency automatically). If Codex is not installed, this resource will report as not present.
- Multiple `codex-project` entries can coexist — each unique `directory` is a separate resource instance.
- Destroying a `codex-project` resource removes only the per-project files (`AGENTS.md` and the `.codex/config.toml` directory). The Codex binary and global configuration are left untouched.
- The `config` parameter merges only the declared top-level keys. Existing project config not in your Codify config is left untouched.
- The `agentsMd` parameter manages the entire `AGENTS.md` file. On destroy, the file is removed.
- MCP servers are stored under `[mcp_servers.<name>]` in `<directory>/.codex/config.toml`. Removing an MCP server from your config removes its table; other servers are untouched.
87 changes: 87 additions & 0 deletions docs/resources/(resources)/codex.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: codex
description: A reference page for the codex resource
---

The codex resource installs the [Codex CLI](https://developers.openai.com/codex) — OpenAI's terminal-based coding agent — and manages its global configuration. It handles installation via the official installer script and gives you declarative control over `~/.codex/config.toml` settings and global MCP servers.

## Parameters

- **config**: *(object, optional)* Key-value pairs to merge into `~/.codex/config.toml`. On apply, the declared keys are written; on destroy, only the declared keys are removed. Common settings include:
- `model` — the model Codex uses (e.g. `"gpt-5.1-codex"`)
- `model_provider` — the model provider (default: `"openai"`)
- `approval_policy` — `"untrusted"` | `"on-request"` | `"never"` (default: `"on-request"`)
- `sandbox_mode` — `"read-only"` | `"workspace-write"` | `"danger-full-access"` (default: `"workspace-write"`)
- `sandbox_workspace_write` — `{ network_access, writable_roots, ... }`
- `model_reasoning_effort` — `"minimal"` | `"low"` | `"medium"` | `"high"` | `"xhigh"`
- `model_reasoning_summary` — `"auto"` | `"concise"` | `"detailed"` | `"none"`
- `web_search` — `"disabled"` | `"cached"` | `"live"` (default: `"cached"`)
- `file_opener` — `"vscode"` | `"cursor"` | `"windsurf"` | `"none"`
- `history` — `{ persistence, max_bytes }`
- `shell_environment_policy` — `{ inherit, set, include_only, exclude }`

- **mcpServers**: *(array, optional)* MCP servers to register globally under `[mcp_servers]` in `~/.codex/config.toml`. Each entry requires a `name` and `type`, plus transport-specific fields:
- **stdio**: `{ name, type: "stdio", command, args?, env?, envVars?, cwd?, startupTimeoutSec?, toolTimeoutSec? }` — local process server
- **http**: `{ name, type: "http", url, bearerTokenEnvVar?, httpHeaders? }` — remote streamable-HTTP server

## Example usage

### Install Codex with custom settings

```json title="codify.jsonc"
[
{
"type": "codex",
"config": {
"model": "gpt-5.1-codex",
"approval_policy": "on-request",
"sandbox_mode": "workspace-write"
}
}
]
```

### Codex with an MCP server

```json title="codify.jsonc"
[
{
"type": "codex",
"mcpServers": [
{
"name": "filesystem",
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
]
}
]
```

### Codex with a remote MCP server

```json title="codify.jsonc"
[
{
"type": "codex",
"mcpServers": [
{
"name": "figma",
"type": "http",
"url": "https://mcp.figma.com/mcp",
"bearerTokenEnvVar": "FIGMA_OAUTH_TOKEN"
}
]
}
]
```

## Notes

- Codex is installed via the official installer (`curl -fsSL https://chatgpt.com/codex/install.sh | sh`) on both macOS and Linux. The binary is placed at `~/.local/bin/codex`.
- The installer adds `~/.local/bin` to your PATH. This entry remains after destroy — remove it manually if you no longer want it.
- The `config` parameter merges only the declared top-level keys of `~/.codex/config.toml`. Existing keys not in your Codify config (including `mcp_servers`) are left untouched.
- MCP servers are stored under `[mcp_servers.<name>]` in `~/.codex/config.toml`. Removing an MCP server from your config removes its table; other servers are untouched.
- For per-project configuration (AGENTS.md, project-scoped settings and MCP servers), see [`codex-project`](/docs/resources/codex/codex-project). For the Codex desktop app, see [`codex-app`](/docs/resources/codex/codex-app).
- Authentication (`codex login`) is interactive and not managed by this resource.
17 changes: 15 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"nanoid": "^5.0.9",
"plist": "^3.1.0",
"semver": "^7.6.0",
"smol-toml": "^1.6.1",
"strip-ansi": "^7.1.0",
"trash": "^10.0.0"
},
Expand Down
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import { MacosSettingsResource } from './resources/macos/macos-settings/macos-se
import { MacportsResource } from './resources/macports/macports.js';
import { ClaudeCodeResource } from './resources/claude-code/claude-code.js';
import { ClaudeCodeProjectResource } from './resources/claude-code/claude-code-project.js';
import { CodexResource } from './resources/codex/codex.js';
import { CodexProjectResource } from './resources/codex/codex-project.js';
import { CodexAppResource } from './resources/codex/codex-app.js';
import { OllamaResource } from './resources/ollama/ollama.js';
import { PgcliResource } from './resources/pgcli/pgcli.js';
import { Pip } from './resources/python/pip/pip.js';
Expand Down Expand Up @@ -122,6 +125,9 @@ runPlugin(Plugin.create(
new TartVmResource(),
new ClaudeCodeResource(),
new ClaudeCodeProjectResource(),
new CodexResource(),
new CodexProjectResource(),
new CodexAppResource(),
new OllamaResource(),
new SyncthingResource(),
new SyncthingDeviceResource(),
Expand Down
68 changes: 68 additions & 0 deletions src/resources/codex/codex-app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
ExampleConfig,
Resource,
ResourceSettings,
getPty,
z,
} from '@codifycli/plugin-core';
import { OS, StringIndexedObject } from '@codifycli/schemas';
import fs from 'node:fs/promises';

const CODEX_APP_PATH = '/Applications/Codex.app';

const schema = z
.object({})
.meta({ $comment: 'https://codifycli.com/docs/resources/codex/codex-app' })
.describe('Codex desktop app installation');

export type CodexAppConfig = z.infer<typeof schema> & StringIndexedObject;

const exampleBasic: ExampleConfig = {
title: 'Install the Codex desktop app',
description: 'Install the Codex desktop app (the "Codex command center") via Homebrew cask.',
configs: [
{
type: 'codex-app',
os: ['macOS'],
},
],
};

export class CodexAppResource extends Resource<CodexAppConfig> {
getSettings(): ResourceSettings<CodexAppConfig> {
return {
id: 'codex-app',
operatingSystems: [OS.Darwin],
schema,
exampleConfigs: {
example1: exampleBasic,
},
};
}

async refresh(): Promise<Partial<CodexAppConfig> | null> {
try {
await fs.access(CODEX_APP_PATH);
} catch {
return null;
}

return {};
}

async create(): Promise<void> {
const $ = getPty();
await $.spawn('brew install --cask codex-app', {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: '1' },
});
}

async destroy(): Promise<void> {
const $ = getPty();
await $.spawnSafe('brew uninstall --cask codex-app', {
env: { HOMEBREW_NO_AUTO_UPDATE: '1' },
});
await $.spawnSafe(`rm -rf "${CODEX_APP_PATH}"`);
}
}
Loading