Summary
The strata tool add cursor command directly reads and writes the user's global Cursor MCP configuration file (~/.cursor/mcp.json) without user confirmation, backup, or atomic write protection. This is inconsistent with the VSCode and Claude/Gemini integrations in the same codebase, which delegate config management to the respective platform CLIs (code --add-mcp, claude mcp add).
Affected Code
File: open-strata/src/strata/utils/tool_integration.py
add_strata_to_cursor() (lines 109-155): Reads ~/.cursor/mcp.json, injects {"strata": {"command": "strata"}} into mcpServers, writes back.
ensure_json_config() (lines 45-69): On JSON parse failure, silently creates a new empty config, potentially discarding all existing MCP server entries.
save_json_config() (lines 72-81): Direct open("w") + json.dump() with no atomic write pattern.
Reproduction
- Install strata:
pip install strata
- Configure Cursor with several MCP servers in
~/.cursor/mcp.json
- Run:
strata tool add cursor
- Observe:
~/.cursor/mcp.json modified with no confirmation prompt
- To observe corruption risk: Manually corrupt
~/.cursor/mcp.json with invalid JSON, then run strata tool add cursor — existing config is silently replaced with {"mcpServers": {"strata": {"command": "strata"}}}
Inconsistency With Other Integrations
| Platform |
Method |
Safety |
| VSCode |
code --add-mcp CLI |
Platform-managed config handling |
| Claude |
claude mcp add CLI |
Platform-managed config handling |
| Gemini |
gemini mcp add CLI |
Platform-managed config handling |
| Cursor |
Direct file write to ~/.cursor/mcp.json |
No platform API — strata reimplements config management |
Issues
1. No user confirmation
The command writes to ~/.cursor/mcp.json immediately with no prompt. A --dry-run flag or interactive confirmation ("This will modify ~/.cursor/mcp.json. Continue? [y/N]") would be appropriate.
2. Silent corruption recovery
ensure_json_config() (line 67) catches json.JSONDecodeError and returns an empty dict. If the user's config is temporarily malformed (e.g., Cursor was mid-write, or the user was editing it), running strata tool add cursor will silently discard all existing MCP server configurations.
3. No atomic writes
save_json_config() uses open("w") which truncates the file before writing. If the process crashes or is interrupted during json.dump(), the file is left empty or partially written. Standard mitigation: write to a temp file, then os.rename().
4. No backup
The original config is not preserved before modification. A simple shutil.copy2() to mcp.json.bak before writing would provide recovery.
5. TOCTOU race condition
Between reading the config (line 138) and writing it back (line 149), another process (Cursor IDE, another strata instance, user editing) could modify the file. The strata write would silently overwrite those changes.
Mitigating Factors
- The operation is user-initiated (requires running
strata tool add cursor)
- Existing MCP server entries are preserved via recursive merge (
update_json_recursively)
- The config path (
~/.cursor/mcp.json) matches Cursor's expected location
Suggested Fixes
- Add confirmation prompt before writing to global config
- Add
--dry-run flag to preview changes
- Implement atomic writes (temp file +
os.rename())
- Create backup (
mcp.json.bak) before modification
- Fix silent corruption: On
JSONDecodeError, warn and abort rather than silently creating empty config
- Document that this command directly modifies
~/.cursor/mcp.json
Context
Found during a security review of the MCP server ecosystem. CWE-269 (Improper Privilege Management).
Reporter: Christopher Lusk — [email protected] — North Echo Security Research
Summary
The
strata tool add cursorcommand directly reads and writes the user's global Cursor MCP configuration file (~/.cursor/mcp.json) without user confirmation, backup, or atomic write protection. This is inconsistent with the VSCode and Claude/Gemini integrations in the same codebase, which delegate config management to the respective platform CLIs (code --add-mcp,claude mcp add).Affected Code
File:
open-strata/src/strata/utils/tool_integration.pyadd_strata_to_cursor()(lines 109-155): Reads~/.cursor/mcp.json, injects{"strata": {"command": "strata"}}intomcpServers, writes back.ensure_json_config()(lines 45-69): On JSON parse failure, silently creates a new empty config, potentially discarding all existing MCP server entries.save_json_config()(lines 72-81): Directopen("w")+json.dump()with no atomic write pattern.Reproduction
pip install strata~/.cursor/mcp.jsonstrata tool add cursor~/.cursor/mcp.jsonmodified with no confirmation prompt~/.cursor/mcp.jsonwith invalid JSON, then runstrata tool add cursor— existing config is silently replaced with{"mcpServers": {"strata": {"command": "strata"}}}Inconsistency With Other Integrations
code --add-mcpCLIclaude mcp addCLIgemini mcp addCLI~/.cursor/mcp.jsonIssues
1. No user confirmation
The command writes to
~/.cursor/mcp.jsonimmediately with no prompt. A--dry-runflag or interactive confirmation ("This will modify ~/.cursor/mcp.json. Continue? [y/N]") would be appropriate.2. Silent corruption recovery
ensure_json_config()(line 67) catchesjson.JSONDecodeErrorand returns an empty dict. If the user's config is temporarily malformed (e.g., Cursor was mid-write, or the user was editing it), runningstrata tool add cursorwill silently discard all existing MCP server configurations.3. No atomic writes
save_json_config()usesopen("w")which truncates the file before writing. If the process crashes or is interrupted duringjson.dump(), the file is left empty or partially written. Standard mitigation: write to a temp file, thenos.rename().4. No backup
The original config is not preserved before modification. A simple
shutil.copy2()tomcp.json.bakbefore writing would provide recovery.5. TOCTOU race condition
Between reading the config (line 138) and writing it back (line 149), another process (Cursor IDE, another strata instance, user editing) could modify the file. The strata write would silently overwrite those changes.
Mitigating Factors
strata tool add cursor)update_json_recursively)~/.cursor/mcp.json) matches Cursor's expected locationSuggested Fixes
--dry-runflag to preview changesos.rename())mcp.json.bak) before modificationJSONDecodeError, warn and abort rather than silently creating empty config~/.cursor/mcp.jsonContext
Found during a security review of the MCP server ecosystem. CWE-269 (Improper Privilege Management).
Reporter: Christopher Lusk — [email protected] — North Echo Security Research