Skip to content
All articles

Shager in OpenAI Codex: config.toml, bearer_token_env_var and a Tool Allowlist That Keeps Drafts as Drafts

Set up Shager's remote MCP server in Codex CLI via config.toml or codex mcp add, read the key from an env var, restrict tools, and create a first draft.

7 min read

Codex config.toml: an MCP server named shager with its URL and an environment variable holding the key.
The key stays in an environment variable, never in the file.

To connect Shager to OpenAI's Codex CLI, add an [mcp_servers.shager] table to ~/.codex/config.toml with url = "https://app.shager.ai/api/mcp" and bearer_token_env_var = "SHAGER_API_KEY", then export your shgr_live_ key in that variable. Codex speaks streamable HTTP natively and sends the key as a bearer token, so no bridge or local process is needed. You can also do it in one line with codex mcp add shager --url ... --bearer-token-env-var SHAGER_API_KEY.

The rest of this guide is about doing it in a way you won't regret: keeping the key out of the file, limiting which Shager tools Codex can call, and picking a first task that proves the wiring.

What does Codex support for remote MCP servers?

OpenAI's Codex MCP documentation describes streamable HTTP servers configured with a url, plus three ways to authenticate with headers. The configuration reference defines them:

Key What it does
bearer_token_env_var Name of an environment variable whose value is sent as the bearer token
http_headers Static headers included with each request
env_http_headers Headers whose values are read from environment variables

Shager expects Authorization: Bearer shgr_live_..., which is exactly what bearer_token_env_var produces. That is the option to use.

Option A: edit config.toml

Open ~/.codex/config.toml and add:

[mcp_servers.shager]
url = "https://app.shager.ai/api/mcp"
bearer_token_env_var = "SHAGER_API_KEY"

Then put the key in your shell profile, not in the TOML:

export SHAGER_API_KEY="shgr_live_your_key_here"

Note that the config holds the variable's name, not the key itself. That means you can commit or share the snippet freely, and each teammate supplies their own key. Separate keys per person pay off later, because Shager's audit log at https://app.shager.ai/dashboard/agents records every call against the key that made it.

Diagram: an AI agent (Claude, Codex or Cursor) connects to Shager through the MCP server or REST API, and Shager distributes to Facebook Pages, Instagram and YouTube.
The agent decides what to publish. Shager handles connections, checks, staggering and measurement.

Option B: codex mcp add

The CLI writes the same table for you. The Codex source for codex mcp add defines --url for streamable HTTP servers and a --bearer-token-env-var flag that requires it (mcp_cmd.rs on GitHub):

codex mcp add shager \
  --url https://app.shager.ai/api/mcp \
  --bearer-token-env-var SHAGER_API_KEY

If your installed version differs, codex mcp add --help is the source of truth.

Check the result:

codex mcp list

Inside the Codex TUI, /mcp shows active servers and their tools.

Should you use http_headers instead?

You can, but you shouldn't. http_headers = { "Authorization" = "Bearer shgr_live_..." } works, and it puts a live credential in a plain text file that tends to get copied into dotfile repos. If you need a header other than the bearer token, env_http_headers maps a header name to an environment variable name:

[mcp_servers.shager]
url = "https://app.shager.ai/api/mcp"
env_http_headers = { "Authorization" = "SHAGER_AUTH_HEADER" }

With that form, the variable must contain the full value, including the scheme: export SHAGER_AUTH_HEADER="Bearer shgr_live_...". For Shager, bearer_token_env_var is simpler and does the same thing.

How do you limit what Codex can do in Shager?

This is the part most setup guides skip. Codex lets you filter a server's tools with enabled_tools (an allow list) and disabled_tools (a deny list applied after it), both documented in the configuration reference. Combine that with Shager's key scopes and you get two layers that fail closed.

A drafting profile that can read everything and create drafts, but cannot schedule, cancel or create connect links:

[mcp_servers.shager]
url = "https://app.shager.ai/api/mcp"
bearer_token_env_var = "SHAGER_API_KEY"
enabled_tools = [
  "whoami",
  "list_workspaces",
  "list_channels",
  "list_groups",
  "upload_media_from_url",
  "create_post",
  "get_post",
  "list_posts",
  "get_analytics",
]
tool_timeout_sec = 120

create_post stays in the list because without schedule_at it only saves a draft. If the key also lacks the publish scope, Shager rejects any create_post that includes schedule_at with a 403, so even a creative model can't sneak a scheduled post through.

The tool_timeout_sec bump is there because upload_media_from_url downloads the file server side, and a large vertical video can take longer than the default 60 seconds the reference lists.

A first task worth running

Start with a prompt that touches several tools and leaves only a draft behind:

Use the shager MCP server.
1. whoami, then list_workspaces.
2. In workspace "Lakeside Realty", list_channels and list_groups.
3. upload_media_from_url https://example.com/media/open-house.jpg
4. create_post as a draft to group "All agents" with a different caption per
   channel (per_channel), mentioning each agent's neighborhood from the channel
   name. cta_url https://lakesiderealty.example/open-house, campaign
   "open-house-oct", first_comment "Details and RSVP: " followed by the link.
5. get_post and print a table of channel, network, format and state.

What you should see: a post in DRAFT status with one destination per account, each with its format resolved for that network. In Shager, every account gets its own short link and UTM tags for the cta_url, with utm_content naming the account, which is what makes per-account attribution work later. The details are in per-account lead attribution.

Can Codex run this without a human at the keyboard?

Codex has a non-interactive codex exec mode for scripts and CI. How MCP tool approvals behave in a headless run has changed between releases, so test a dry run on your installed version before you put it on a timer. For a job that must run unattended every week, many teams skip the chat layer and call Shager's REST API from a short script, which has no approval prompts to get stuck on. Whichever you choose, give the job its own key, keep the tool allowlist tight, and decide deliberately whether that key carries publish. A routine built around those choices is laid out in the weekly distribution routine.

Troubleshooting

What you see Cause Fix
401 unauthorized Variable not exported in the shell that launched Codex echo $SHAGER_API_KEY in the same terminal, then restart Codex
Tools missing from /mcp Name not in enabled_tools, or listed in disabled_tools Check the spelling against the tool list on /en/agents
403 sandbox_unclaimed Key came from agent self-signup and no human has claimed it Send the claim_url to a human
403 forbidden on scheduling Key lacks publish Expected for a drafting key
429 rate_limited Over 120 requests per minute per key Use groups and one create_post instead of one call per account

FAQ

Does Codex need OAuth to talk to Shager?

No. Codex supports bearer tokens from an environment variable, which is how Shager authenticates today. Shager's OAuth for MCP is coming, and Codex also supports OAuth servers, but you don't need to wait for it.

Is the Shager setup different in the Codex IDE extension?

OpenAI's MCP docs say the ChatGPT desktop app, Codex CLI and IDE extension share this configuration, so the same ~/.codex/config.toml table serves all of them. Make sure the environment variable is visible to the editor process, which on macOS can mean launching the editor from a terminal.

Can I point Codex at the REST API instead of MCP?

Yes, if you're writing code rather than chatting. The OpenAPI document describes the same operations as the MCP tools, with the same scopes and limits.

Next step

With Codex connected, get comfortable with the operations themselves before automating anything. The REST API quickstart walks the full sequence from workspace to tracked post with curl and Python, which also helps you read what Codex is doing when it calls the MCP tools.

Want to try it on your accounts?

Shager distributes, measures and gets client approval, all in one place.