npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@4pii4/cordex

v0.1.7

Published

Control OpenAI Codex from Discord with persistent projects, sessions, approvals, and live output

Downloads

1,262

Readme

Cordex turns Discord into a control surface for OpenAI Codex. Each Discord channel maps to a local project, and each thread is a persistent Codex session. Send a message and Codex can read, edit, test, and run commands on the machine hosting Cordex.

[!WARNING] Cordex can read and modify local files, run shell commands, and—when explicitly enabled—run Codex without approvals or sandboxing. Run it on a machine and in a Discord server you control, restrict access to trusted members, and keep the default workspace-write sandbox with on-request approvals unless you fully understand the consequences.

Quick Start

Requires Node.js 22 or newer and Git.

  1. Install the Codex CLI, then authenticate it on the machine that will run Cordex:

    npm install -g @openai/codex
    codex login
    codex --version
  2. Create a Discord application and collect its bot token, application ID, and server ID using the Discord bot setup below.

  3. Start Cordex with one command:

    npx -y @4pii4/cordex@latest

    On the first run, Cordex asks for the three Discord values, saves its config, registers the slash commands, and starts the bot. Keep this process running.

  4. As the Discord server owner, open the managed general channel (#cordex when the bot is named Cordex) and send a task. Cordex creates a thread for the new Codex session. Add an existing repository with /add-project or from another terminal:

    npx -y @4pii4/cordex@latest project add /absolute/path/to/project

For a permanent cordex command, install the package globally:

npm install -g @4pii4/cordex
cordex

What is Cordex?

Cordex maps Discord's project and conversation structure directly onto the local Codex runtime:

| Discord | Local Codex runtime | | --- | --- | | Project channel | Local project directory | | Thread in that channel | Persistent Codex session |

Send a message in a project channel to start a session thread. Continue chatting in that thread to keep working in the same Codex context. Switch projects by switching channels, and switch tasks by switching threads.

Core Features

  • Remote Codex prompting from Discord with persistent, resumable sessions
  • Live responses, compact tool activity, approvals, and structured user questions
  • Dedicated Discord channels for local projects and optional git worktree isolation
  • Project- or session-level model, reasoning, collaboration mode, and permission controls
  • Queued and scheduled prompts with restart recovery
  • Native Codex skill invocation plus MCP, authentication, account, rate-limit, and context diagnostics
  • Reply-aware text and image input, code review, diffs, rollback, and controlled shell execution

Setup

Requirements

  • Node.js 22 or newer
  • A Codex CLI installation with app-server support
  • A Discord application and bot added to a server you control
  • Git (Cordex initializes its managed root repository at startup and also uses Git for project creation and worktree features)

Authenticate Codex on the host before starting Cordex:

codex login
codex --version

Cordex uses Codex's app-server interface, which is currently experimental. A Codex CLI update can therefore require a corresponding Cordex update.

Discord bot setup

  1. Create an application in the Discord Developer Portal.

  2. Open Bot, create the bot user, and enable the Message Content Intent.

  3. In the OAuth2 URL generator, select the bot and applications.commands scopes.

  4. Grant the bot these permissions:

    • View Channels
    • Send Messages
    • Send Messages in Threads
    • Create Public Threads
    • Manage Threads
    • Manage Channels
    • Manage Roles (shown as Manage Permissions in some Discord clients)
    • Read Message History
    • Attach Files

    The combined permission integer is 326686051344. To skip selecting each permission manually, replace APPLICATION_ID in this invite URL:

    https://discord.com/oauth2/authorize?client_id=APPLICATION_ID&permissions=326686051344&scope=bot%20applications.commands
  5. Install the bot into the intended Discord server.

  6. Copy the bot token, application ID, and server ID for cordex init. Enable Discord Developer Mode if you need to copy the server ID.

Treat the bot token like a password. Never commit it, paste it into a Discord channel, or expose it in logs.

Install

Install the published CLI globally:

npm install -g @4pii4/cordex
cordex --version

Or run it without a global install:

npx -y @4pii4/cordex@latest --version
npx -y @4pii4/cordex@latest init
npx -y @4pii4/cordex@latest start

The remaining examples use the global cordex command for brevity. Without a global install, replace it with npx -y @4pii4/cordex@latest.

Initialize and run

If you installed Cordex globally, the explicit setup flow is:

cordex init
cordex doctor
cordex start

cordex init prompts for the Discord bot token, application ID, and server ID. Rerunning it preserves existing settings when prompts are left blank. Changing the server ID clears guild-scoped mappings, sessions, access grants, and direct shell access so state from the previous server cannot carry over. Running bare cordex also initializes the configuration when necessary and then starts the bot. On startup, Cordex registers its slash commands and creates a managed category with a general project channel. Name the Discord bot Cordex to use the default Cordex category and #cordex channel; other bot names are appended so multiple installations can coexist.

Add an existing local project from the terminal:

cordex project add /absolute/path/to/project

Alternatively, use /add-project in Discord. Use /create-new-project to create a new git repository, Discord channel, and initial session together. Then send a normal message in the project channel; Cordex creates a thread and starts Codex.

Useful terminal project commands include:

cordex project add .
cordex project create my-app --projects-dir ~/src
cordex project list --json
cordex project list --all --prune
cordex project open-in-discord
cordex project remove DISCORD_CHANNEL_ID

cordex project remove removes the local mapping without deleting project files. Discord /remove-project deletes the selected managed Discord channel after its safety checks.

While cordex start is running, another local process owned by the same operating- system user can durably submit a prompt to an existing Cordex session thread:

cordex send --thread DISCORD_THREAD_ID "Run the focused tests"
cordex send --thread DISCORD_THREAD_ID --file ./failure.log "Diagnose this failure"
cordex send --thread DISCORD_THREAD_ID --file ./error.log --file ./screenshot.png "Investigate these artifacts"

The daemon reads up to ten repeated --file values itself and accepts mixed UTF-8 text plus PNG, JPEG, GIF, and WebP images within the same per-file and aggregate limits as Discord input. Byte-identical images are sent to Codex once. It listens on a mode-0600 Unix socket under ~/.cordex/ipc and authenticates each request with a per-start mode-0600 token. Accepted prompts enter the durable direct- delivery ledger before the CLI reports success. Safe channel or session creation is not yet exposed by this boundary; use --thread with an existing Cordex thread.

Inside an existing Cordex thread, a message beginning with a mention of another Discord user is stored as passive model context without starting or steering a Codex turn. The next real prompt can use that user-to-user discussion.

For detailed backend logging, run:

cordex start --verbose

Verbose logs can include prompts, tool calls, commands, file paths, and Codex protocol traffic. Store and share them accordingly.

Commands

Slash commands are registered in the configured Discord server.

| Command | Description | | --- | --- | | /add-project | Map an existing local repository to a Discord channel | | /new-session | Start another session, inheriting the current checkout when used in a thread | | /resume | Reopen a previous active or archived Codex session | | /abort | Stop the current Codex turn | | /model | Change the model and reasoning settings for a channel or session | | /permissions | List or select a Codex permission profile for the current session | | /queue | Run a prompt after the current turn finishes | | /btw | Fork the current context into a side session | | /new-worktree | Fork the current session into an isolated Git worktree | | /merge-worktree | Merge a completed worktree back into its target branch | | /diff | Show or attach the complete current Git patch | | /status | Show the active project, session, model, permissions, and queue state |

Commands by area

| Area | Commands | | --- | --- | | Projects | /add-project, /create-new-project, /remove-project, /project | | Sessions | /new-session, /resume, /rename, /fork, /fork-subagent, /btw, /abort, /archive, /compact, /last-sessions, /session-id, /status | | Models and runtime | /model, /model-variant, /unset-model-override, /mode, /fast, /permissions, /add-dir, /verbosity, /context-usage | | Goals | /goal, /clear-goal | | Git and worktrees | /diff, /review, /rollback, /new-worktree, /merge-worktree, /delete-worktree, /toggle-worktrees, /worktrees | | Automation | /queue, /clear-queue, /schedule, /tasks, /cancel-task | | Codex services | /skill, /skills, /skill-toggle, /skill-roots, /mcp, /mcp-status, /mcp-login, /auth-status, /rate-limits, /account-usage, /login | | Host control | /run-shell-command, !command, /yolo |

/diff renders small patches inline and attaches the complete binary-capable patch when it exceeds Discord message limits.

Messages ending in . queue are queued behind the active turn. Removing that suffix in an edit dequeues the message. In an existing session, punctuation followed by a final btw suffix, such as check the API too. btw, forks the message into a side session like /btw. /mcp enable and disable actions update the global Codex configuration, not only the current Discord project. /archive keeps the Discord-to-Codex mapping and session settings so /resume can reopen the same thread; active goals, turns, queued prompts, and scheduled tasks, plus any prompt delivery still awaiting recovery, must be resolved first. /rename keeps the Discord and Codex titles in sync. /skill invokes an enabled skill from the current session directory and accepts an optional prompt; Cordex resolves the skill path from Codex metadata at submission time. /skill-toggle updates a skill's enabled state through Codex configuration, while /skill-roots replaces the runtime-only extra skill discovery directories. /tasks includes bounded Run now, Cancel, and Delete controls. Scheduled occurrences are persisted before execution, retain stable delivery IDs across restart, and do not reappear after a concurrent cancellation or deletion.

Standard MCP form elicitations render in Discord with validated strings, dates, URLs, numbers, booleans, and single- or multi-select enums. Empty approval forms can offer session or permanent persistence when Codex explicitly advertises those choices. MCP URL elicitations require credential-free HTTPS links, with stricter ChatGPT-host validation for Codex Apps. Arbitrary openai/form schemas remain disabled and are declined rather than rendered approximately.

Replies include a bounded quote and the referenced Discord author. Text attachments use a MIME allowlist; PNG, JPEG, GIF, and WebP images are downloaded to a bounded local cache before being sent to Codex. Unsupported, oversized, or timed-out attachments are reported in the session instead of being silently ignored. The final rendered text input also has an independent aggregate character limit so multiple attachments and forwarded context cannot create an unbounded prompt.

Model choices use Codex's model catalog when available. Reasoning effort is validated per model, including max, and /fast selects the model's advertised priority tier instead of assuming one fixed service-tier name. Model, effort, Fast, permission, and YOLO changes are persisted before they are applied to a live Codex thread.

/goal with an objective creates or updates Codex's persistent thread goal. Active goal turns, including continuations started directly by Codex, stream to the linked Discord thread, resume when Cordex restarts, and can accept queued or follow-up messages. Omitted status and token-budget options preserve their existing values.

If the Codex app-server exits unexpectedly, Cordex retries it with bounded exponential backoff, clears controls belonging to the failed process, reloads persistent goal sessions, and resumes eligible queued work. Initialization and RPC watchdogs also recycle a child that remains alive but stops responding. After an ambiguous turn start or steer failure, Cordex checks Codex's persisted client message IDs before retrying so an accepted prompt is not delivered twice. Existing-session messages, /skill, queued prompts, scheduled occurrences, and post-conflict recovery instructions are persisted before Codex delivery and stay recorded until that acceptance is confirmed. Scheduled tasks found in running state after restart retry the same occurrence ID instead of creating a duplicate. Completed Discord output and run footers use a separate durable outbox, so a partial send or bot restart resumes only missing chunks and does not block the next queued turn. Archive and resume operations persist lifecycle intents before mutating Codex and reconcile those intents against complete active and archived thread listings on startup. A crash after either side accepts the operation therefore converges instead of leaving Discord state permanently split from Codex.

At startup, Cordex refetches the Discord messages backing . queue entries so offline edits replace the stored input and offline deletions remove it. Transient Discord or attachment failures retain the last durable input, block that thread's queued delivery, and retry reconciliation with capped backoff.

Discord prompt ingress is serialized per thread. Slash commands acknowledge before waiting behind earlier messages, /abort stays on a priority path, and a deleted thread is tombstoned and interrupted immediately so blocked preprocessing cannot dispatch work after deletion. Startup also removes persisted sessions whose Discord thread disappeared while Cordex was offline. During shutdown, Cordex stops admitting new Discord and local-daemon requests, drains already accepted interactions, scheduled work, Codex requests and notifications, state/outbox queues, and deletion cleanup, then closes Codex and Discord. Concurrent shutdown signals share the same drain instead of racing teardown.

/yolo switches the selected scope to approval-free danger-full-access mode. /run-shell-command and the !command shortcut execute through the host shell in the active project or session directory when allowShellCommands is enabled. That directory may be an isolated worktree. Restrict both capabilities to trusted users.

Starting /new-session inside an existing thread inherits that session's directory and extra workspace roots without claiming ownership of its worktree. Worktree creation refreshes configured remotes, prefers a strictly newer remote ref, and initializes submodules recursively. /merge-worktree blocks while another live or starting session shares the checkout; successful and no-op merges leave the session checkout detached at the merged target commit. /delete-worktree then removes only that exact registered, clean, merged checkout after confirming its feature branch is gone and no active, archived, or starting session still references it. A persisted removal intent lets startup finish an interruption between Git deletion and the final state update, after which the session reloads at the mapped project root.

Troubleshooting

  • Run cordex doctor to confirm the config file, Codex executable, and mapped project directories can be read.
  • Run codex login again if Codex itself reports an authentication failure.
  • Rerun cordex init to update the Discord bot token, application ID, or server ID.
  • Check that Message Content Intent is enabled and the bot has every permission listed in Discord bot setup.
  • Run cordex start --verbose when diagnosing startup, Discord, or Codex app-server failures. Verbose logs can contain prompts, commands, and local file paths.

Configuration

The default home is ~/.cordex. Cordex stores its configuration in ~/.cordex/config.json and runtime state alongside it. Configuration files are written with restrictive filesystem permissions, but they still contain the Discord bot token and must not be shared.

A representative configuration is:

{
  "token": "DISCORD_BOT_TOKEN",
  "applicationId": "DISCORD_APPLICATION_ID",
  "guildId": "DISCORD_SERVER_ID",
  "sandbox": "workspace-write",
  "approvalPolicy": "on-request",
  "approvalTimeoutMinutes": 10,
  "allowAllUsers": false,
  "allowShellCommands": false,
  "allowedUserIds": ["TRUSTED_DISCORD_USER_ID"],
  "allowedRoleIds": ["TRUSTED_DISCORD_ROLE_ID"],
  "projectsDirectory": "/absolute/path/for/new/projects",
  "projects": {}
}

Project mappings are normally managed by Cordex. Optional defaultModel and defaultEffort fields can set initial preferences; available models come from the installed Codex runtime. Valid configured effort values are minimal, low, medium, high, xhigh, max, and ultra. approvalTimeoutMinutes controls how long Discord approval buttons remain active before Cordex denies the request and lets Codex continue; it defaults to 10.

Cordex also persists an internal categoryId after creating its managed Discord category. Do not edit or remove it manually; if it is missing or invalid, Cordex creates a new managed category and re-synchronizes its channels there.

Only one Cordex runtime may use a CORDEX_HOME at a time. A process-lifetime runtime.lock fails fast on duplicate starts and is reclaimed when its recorded process no longer exists.

Environment variables override the corresponding configuration or runtime path. Credential overrides cannot bootstrap a missing config file; create one with cordex init or create the file referenced by CORDEX_CONFIG first.

| Variable | Purpose | | --- | --- | | CORDEX_DISCORD_TOKEN | Discord bot token | | CORDEX_APPLICATION_ID | Discord application ID | | CORDEX_GUILD_ID | Discord server ID | | CORDEX_ALLOWED_USER_IDS | Comma-separated trusted Discord user IDs | | CORDEX_ALLOWED_ROLE_IDS | Comma-separated trusted Discord role IDs | | CORDEX_HOME | Cordex state and configuration directory | | CORDEX_CONFIG | Explicit configuration file path | | CORDEX_PROJECTS_DIR | Default directory for newly created projects | | CORDEX_CODEX_BIN | Alternate Codex executable | | CORDEX_VERBOSE=1 | Enable verbose backend logging |

Supported sandbox values are read-only, workspace-write, and danger-full-access. Supported approval policies are untrusted, on-request, and never.

Direct /run-shell-command and !command execution is disabled by default. Set allowShellCommands to true only when every authorized Cordex operator is also trusted with the full operating-system permissions of the Cordex process.

Access control

By default, only the Discord server owner can use Cordex. Grant access by adding immutable Discord user IDs to allowedUserIds or role IDs to allowedRoleIds. The matching CORDEX_ALLOWED_USER_IDS and CORDEX_ALLOWED_ROLE_IDS environment variables accept comma-separated overrides. Role names are intentionally not an access boundary because they can be renamed or recreated. The @everyone role ID is ignored; use allowAllUsers for an intentional server-wide grant.

Configure non-owner operator IDs before their first use. Restart Cordex after changing access or direct-shell settings; live configuration refresh only reloads project mappings and managed channel metadata.

Cordex-managed categories are private by default. On startup, Cordex synchronizes the category so it is visible to the server owner, the bot, and configured user or role IDs. Discord administrators can still bypass channel visibility rules. Setting allowAllUsers to true removes the managed visibility restriction and lets every server member invoke Cordex. Replies and command results are generally public to anyone who can view the channel, so do not map Cordex to a public channel or weaken the managed category permissions casually.

For safer deployments, run Cordex under a dedicated operating-system account, grant the bot only the required Discord permissions, map only intended projects, and keep backups or version control for writable files.

Development

Install dependencies and run the build plus local test suite:

npm ci
npm run check
npm link

npm link makes the checkout's cordex command available on the current machine.

The live suites launch real Codex integrations and may create Discord messages, channels, sessions, worktrees, files, or account flows:

npm run test:live-all

Run live tests only with an authenticated test account, a dedicated Discord server, and projects where those side effects are acceptable. Individual test:live-* scripts are available for narrower integration checks. Some account diagnostics skip when no compatible ChatGPT login is active.

See CONTRIBUTING.md for contribution expectations and SECURITY.md for private vulnerability reporting guidance.

Limitations

  • Codex app-server is experimental and its protocol can change between CLI versions.
  • Task output is normally public within its channel. Authentication, account, session-ID, and other sensitive diagnostic commands use ephemeral replies.
  • /rollback changes Codex conversation history but intentionally does not restore files.
  • Worktree automation requires mapped projects to be git repositories.
  • MCP enable/disable actions affect the global Codex configuration.
  • Cordex does not currently provide hosted session sharing, voice transcription, screen sharing, browser-hosted VS Code, remote diff hosting, Slack bridging, tunnels, or self-update/restart management.

Kimaki attribution

Cordex ports the core Discord workflow of Kimaki from OpenCode to Codex. Kimaki's original work is MIT-licensed, and its required copyright and license notices are retained with this project. OpenCode-specific providers, plugins, commands, and agents are not presented as Cordex features; Codex supplies its own models, authentication, skills, plugins, MCP servers, and durable sessions.

Cordex is an independent community project and is not affiliated with or endorsed by OpenAI or Discord.

License

Copyright (C) 2026 Cordex contributors. Cordex is licensed under the GNU General Public License version 3 only (GPL-3.0-only). See LICENSE.