Settings and files
cora-mcp’s settings
Section titled “cora-mcp’s settings”cora-mcp’s settings are yours rather than the project’s. So your user config holds them, never the project’s config:
{ "mcp": { "headless": true, "callTimeout": 120000, "navigationTimeout": 90000 }}mcp.headlessruns the browser without a window: see Headed or headless.mcp.callTimeoutis how long cora-mcp works on a tool call, in milliseconds. Opening the browser, from Chrome’s launch throughbrowser.setup, has the same limit.browser.setupTimeoutapplies tobrowser.setupwithin it, so whichever runs out first ends the opening, and the error names it.mcp.actionTimeoutis how long abrowser_*tool waits for an action on the page, such as a click, in milliseconds.mcp.navigationTimeoutis how long abrowser_*tool waits for a page it navigates to, in milliseconds.
Each key’s reference entry gives its default. The CORA_MCP_* variables override each key, and cora-mcp’s --headless overrides mcp.headless, as Which value wins describes.
cora-mcp reads your user config as it starts, so an edit takes effect when the client restarts cora-mcp. Codex passes a server none of the CORA_MCP_* variables your shell sets, unless the entry names them. So the user config is the place that reaches cora-mcp under every client. The logging settings work the same way: see More detail from cora-mcp.
When a call runs out of time
Section titled “When a call runs out of time”A browser tool or a scan that runs past mcp.callTimeout fails with mcp.browser-timeout, naming the setting and its value. cora-mcp then closes its browser, so that the agent’s next call can run.
- A scan also stops at its page’s
page.timeoutwhen that comes first, which the message then names. - cora-mcp never runs a scan again on its own: the agent decides whether to.
- A client also stops waiting at its own tool timeout, such as the
tool_timeout_secof a Codex entry. So a longermcp.callTimeoutneeds the client’s timeout raised too.
What cora-mcp writes
Section titled “What cora-mcp writes”cora-mcp writes to the project’s .cora/, beside the record the plugin’s hooks keep of each agent session, and outside a project to .cora/ in the folder the agent’s client started it in, which is the folder you opened in the agent:
Directory.cora/
Directoryruns/ one results file per scan
- …
Directoryloop/ a record of each issue a scan finds, with a screenshot of its element
- …
Directorybrowser/ playwright-mcp’s page snapshots, screenshots, console logs and downloads
- …
Directorylogs/ log files you ask for, crash files, and the hooks’ log of each agent session
- …
Directoryhooks/ the hooks’ record of each agent session, which the session’s end removes
- …
A scan’s results
Section titled “A scan’s results”Each scan writes a results file to runs/. explain_finding reads it, and cora report merge and cora baseline update accept it like any other run.
An issue’s record
Section titled “An issue’s record”Each issue a scan finds gets a record in loop/, which follows the issue through its remediation loop:
- A scan creates it. The record holds the element’s entry in the browser’s accessibility tree, and a screenshot of the element. Until a fix is checked, each later scan that finds the issue refreshes the record.
- Each
verify_fixadds an attempt. It checks the fix against the record, and adds the attempt and its verdict. After three attempts without a fix, the issue is escalated, for you to resolve. summarize_fixesremoves it. Once the summary reports the issue, its record goes, with its screenshot.
The record of an issue no fix was checked for also goes once a scan of its page as it loads no longer finds the issue. A later scan that finds a fixed issue again starts its loop over. npx cora status lists each record with where it stands (The fixer’s progress).
The rest of .cora/
Section titled “The rest of .cora/”browser/holds playwright-mcp’s files. Once they pass 100 MiB, the oldest are deleted.logs/holds a log file of cora-mcp’s only when your user config’slog.file, orCORA_LOG_FILE, asks for one: see More detail from cora-mcp. Log files describes the others..cora/ignores itself in git, and yourstateDirectorysetting moves it.
The files in browser/ and the screenshots in loop/ hold what the pages showed, so review them before you share them. CORA’s tools never send a screenshot to the agent.
In a folder cora-mcp cannot write
Section titled “In a folder cora-mcp cannot write”cora-mcp creates .cora/ only once it writes something there: a tool that writes state, such as a scan, verify_fix, summarize_fixes or a browser tool, a log file you ask for with log.file or CORA_LOG_FILE, which it opens as it starts, or a crash file. Listing its tools, and the tools that only read, list_rules, explain_finding and get_fix_guidance, write nothing. So without a log file, cora-mcp starts in any folder, and adds .cora/ to a folder only once the agent scans or browses there.
In a folder it cannot write, such as a system folder, a tool that writes state fails with mcp.state-unwritable, naming the state directory, and the tools that only read still work. To give it a folder it can write:
- open a project folder, or another folder you can write, in the agent;
- in Codex, set the
cwdof cora-mcp’s entry to such a folder, as Version alignment does for a monorepo’s app; - or set
CORA_STATE_DIRECTORYin the entry’s environment to a directory cora-mcp can write, such asenv = { CORA_STATE_DIRECTORY = "/home/ada/cora-state" }in a Codex entry.
When the agent saves a snapshot, a screenshot, console messages or a request under a filename it chooses, the file lands where the agent names it, anywhere in the project. git ignores it only inside .cora/.
What reaches the agent
Section titled “What reaches the agent”CORA removes credentials from its stderr, its log and crash files, and the errors its tools return, as What logs contain describes. Its tools’ other results, its results files and its records in loop/ remove less. They remove only the passwords in URLs, and the URL parameters that only ever carry one, such as token. They hold what the page showed, such as an element’s markup and its accessible name, as the browser gave them.
The browser_* tools return what the browser shows the agent, without that redaction:
- the URLs it visits;
- page content;
- console messages;
- a request’s headers, cookies included, when the agent inspects the request.
Keep secrets you would not show the agent out of URLs and page content.