When running cursor agent inside a project that has .cursor/cli.json, granting a permission writes the entry to ~/.cursor/cli-config.json (global) instead of the project-level .cursor/cli.json. Because the project-level file takes precedence, the granted permission is never recognized and the permission dialog reappears every time.
Steps to Reproduce
Create a project with a minimal .cursor/cli.json:
$ cat .cursor/cli.json
{}
Confirm ~/.cursor/cli-config.json has empty permissions:
{
"permissions": {
"allow": [],
"deny": []
}
}
Run cursor agent inside the project and trigger a web fetch
When prompted, press tab to choose “Always allow …”
→ The entry is written to ~/.cursor/cli-config.json, not to .cursor/cli.json
Run cursor agent again — the same permission dialog reappears
Expected Behavior
The allowed entry is written to the project-level .cursor/cli.json, which takes precedence over the global config.
Hey, thanks for the detailed report and the repro steps. The “Always allow” behavior really only writes an entry to ~/.cursor/cli-config.json, that’s the current implementation. It doesn’t write to the project-level config. This should be improved, and I’ll log it as a bug.
One quick question so I can understand which exact case you’re hitting. After step 4 when you press tab and pick “Always allow forum.cursor.com”, can you share the exact contents of .cursor/cli.json?
cat .cursor/cli.json
Scenario A: if the file is still {}, the global permission should be picked up on the next run via deep merge, and the dialog shouldn’t show again. If it still prompts, that’s an extra bug besides only writing to global.
Scenario B: if the file has a permissions section, even an empty one like { "permissions": { "allow": [], "deny": [] } }, that explains the repeated prompt. The empty project-level arrays override the global allow list during merge. In that case, the workaround is to add the needed entries manually to .cursor/cli.json:
As another temporary workaround, you can run cursor agent --disable-project-configs so the CLI ignores the project config and uses only the global config.
Let me know what the file looks like after you grant it, then I can report it to the team more accurately.
After granting “Always allow forum.cursor.com”, the file remained unchanged, and the entry was written to ~/.cursor/cli-config.json instead. Since the project-level config takes priority, the dialog reappears every time.
As a side note, I also tested with .cursor/cli.json = {} (no permissions key at all). In that case, the global config was picked up correctly and the dialog did not reappear — so the deep merge works fine when there is no project-level permissions section.
To summarize: the bug is triggered when .cursor/cli.json contains a permissions section. The workaround of manually adding entries to .cursor/cli.json works. Thanks for logging it!