Skills, plugins and connectors in Codex: know what adds access
Codex says it pulled this week's merged tickets from the tracker. The tracker plugin is installed, but nobody ever signed it in. So where did those ticket titles come from?

What you'll make
a four-line capability map for one Codex job, tested with one harmless read, and a result that only claims what Codex could really reach.
What you'll need
Codex in the ChatGPT desktop app, the Codex CLI or the IDE extension, one job that needs an outside service, and about fifteen minutes. Never paste a token or password into a chat or a skill file.
Example result.
| Element | Evidence | Consequence |
|---|---|---|
| Release-notes skill | Listed under $ mentions |
Can shape the notes. Reaches nothing. |
| Tracker plugin | Shown as installed | Says nothing about sign-in. |
| Tracker MCP server | Still offers Authenticate; test read failed | Live tickets are unknown. |
| Ticket export, 9 October | File in the repository | Can support notes for that date. |
Three different things sit behind these words. A skill is a package of instructions and resources for one kind of task. A plugin is an installable bundle that can include skills and MCP servers. An MCP server (the connector) links Codex to a service such as GitHub or a tracker, and it has its own sign-in and permissions. Installing a plugin doesn’t sign anything in. This matters more now that OpenAI is retiring custom GPTs on 11 December 2026 and moving that work to skills and plugins, so these terms are turning up in more business accounts. For the general idea of what a connector can read and change, see Check what an AI connector can read and change.
1. Name the job and the access it needs
Write one sentence: the input, the output and anything that would change outside Codex. For example: “Draft release notes for version 2.4 from tickets merged this week, as a Markdown file in the repository.”
Then split the access. Reading tickets is one permission. Writing a file in the repository is another. Posting the notes back to the tracker would be a third, and this job doesn’t need it.
Why this works: once you’ve named each action, you can check each one, and you’ll notice when a job quietly needs more than you meant to give it.
What you should see: one sentence and a short list of reads and writes, with anything you don’t want marked as out of scope.
2. Look at what’s installed and what’s connected
Each Codex surface shows these in a different place:
- ChatGPT desktop app (Codex): the Plugins tab lists plugins, with an Installed row. Settings › MCP servers shows each server, whether it’s enabled and whether it needs OAuth; a server that still needs sign-in offers Authenticate. Type
/mcpin the composer to see connected servers, and$to pick a skill. - Codex CLI:
/pluginsopens the plugin browser,/skillslists skills and/mcpshows active MCP servers. Outside a session,codex mcp listshows configured servers andcodex mcp login <server-name>starts an OAuth sign-in. - IDE extension: the gear menu › MCP servers shows servers and offers Authenticate.
/skillsor$picks a skill. Plugins aren’t available in the IDE extension; install them in the desktop app or CLI.
A plugin’s skills and tools appear only in a new chat or session after you install it. Then ask Codex for its own view:
For this job: [job sentence from step 1], list the capabilities available in this session. Separate skills, tools from plugins, MCP servers and local file access. For each MCP server, say whether you have completed a successful call in this session. Mark anything you have not tested as unknown. Do not reveal credentials, install anything or change anything outside this folder.
Why this works: the settings screens tell you what’s configured; the prompt tells you what this session thinks it has. Where they disagree, trust the settings.
What you should see: a list that matches what the screens show, with untested connections marked unknown.
3. Test with one small, harmless read
A self-report isn’t proof. Ask for something tiny that only the live service could return:
Using [tracker], list the titles of the three most recently updated tickets in [project]. Do not create, edit or comment on anything. If the call fails, show me the error message instead of guessing.
[tracker] is the plugin or MCP server, and [project] is a project you can already see in the service.
Why this works: real data, or a real error, is evidence. A confident sentence about access isn’t.
What you should see: three titles you recognise from the tracker, or an error. If nothing real comes back, treat access as unknown, whatever step 2 said.
4. Use the smallest route that works
If the test failed and the job needs live data, sign in using the server’s own route (Authenticate, or codex mcp login), accept only the scopes the job needs, then repeat the test read. If you can’t sign in, work from an export:
Use only [export file], dated [export date]. Draft the release notes with sections for New, Fixed and Known issues. State the export date at the top. Keep any ticket whose status is unclear in a "To confirm" list. Do not call the tracker or claim you read it.
Why this works: an export is a fixed snapshot. Saying so keeps the notes honest about what they cover.
What you should see: notes that name the export and its date, with unclear items listed rather than guessed.
Check the result
- Every ticket in the output appears in the test read or the export.
- The output says which source it used, and its date if it’s a snapshot.
- Nothing claims a live read that the test didn’t show.
- No file or service changed beyond what step 1 allowed.
The usual failure: Codex can’t reach the service, so it fills the gap from what’s nearby (branch names, commit messages, earlier chat) and then describes the result as “pulled from the tracker”. Spot it by comparing ticket IDs and titles with the test read or the export. Anything you can’t find there came from somewhere else.
There is no verified access to [service] in this session. Remove every claim that depends on it. Rebuild the result from [export or pasted source] only, stating its date and coverage. List anything that source does not cover as unknown. Do not say or imply that you read the live service.
Worked example: release notes with a tracker nobody signed in
Fictional example. Tomasz maintains a small internal invoicing tool. In the desktop app he installs a tracker plugin and runs his release-notes skill for version 2.4. The plugin’s MCP server still shows Authenticate in Settings › MCP servers.
Codex’s first draft:
Pulled 6 merged tickets from the tracker for 2.4: INV-204 Faster PDF export, INV-207 Fix VAT rounding, INV-209 Dark mode, INV-211 Bulk delete, INV-212 Currency selector, INV-215 Audit log.
His test read returned an authorisation error. The export in the repository says:
tracker-export-2026-10-09.csv (merged this week)
INV-204, Faster PDF export, Done
INV-207, Fix VAT rounding on credit notes, Done
INV-211, Bulk archive for old invoices, Done
INV-212, Currency selector, In review
- The failure. Six “pulled” tickets, but the export has four. INV-209 and INV-215 came from branch names, and “Bulk delete” is a guess at INV-211’s title. Nothing was pulled from the tracker at all.
- The repair. The correction prompt, pointing at the export, produced notes headed “From the 9 October tracker export”. They list INV-204, INV-207 and INV-211 under New and Fixed, and put INV-212 under “To confirm” because it’s still in review.
- Why it held. The test read gave a clear answer before anyone trusted the draft, and the export date makes the notes’ coverage visible.
Task kit for this job: Download (ZIP) · Reusable instructions
Go deeper
Optional training: Separate read and write permission
Being able to read tickets doesn’t mean Codex should change them. For MCP servers you configure yourself, config.toml lets you set how tools from each server are approved: the writes mode asks before any tool that isn’t marked read-only. Before allowing a write, agree the target, the exact action and what you’ll check afterwards. Then look at the service itself: a drafted comment is not a posted one.
Optional training: Keep a skill narrow and current
A skill works best as a method: inputs, steps, checks and exceptions. Keep the changing material (this week’s tickets, this month’s prices) in the task or the connected system, not inside the skill, where it goes stale without anyone noticing. A skill that says “pull tickets from the tracker” doesn’t make the tracker reachable; it only tells Codex to try. Save a useful AI task so you can reuse it covers writing one.