Skip to content

Commit 64ee723

Browse files
IMNMVclaude
andcommitted
Preserve user MCP env block; unify home resolution across the bridge
ClaudeR 0.13.1 / clauder-mcp 0.14.5. Two pre-existing bugs, both found while auditing an unrelated plan. configure() replaced the whole r-studio entry with a fresh command/args list, so re-running install_clauder() deleted any env block on it. That silently dropped CLAUDER_AGENT_ID and collapsed multi-agent identity back to a random id, the failure that 0.11.0 set out to fix. The entry is now updated in place and unknown fields survive. The bridge resolved the session discovery directory through USERPROFILE on Windows to match the R side, but _coord_dir still used a plain expanduser("~"). With HOME pointed at a OneDrive-redirected Documents folder, R and the bridge wrote coordination logs to different places: send_message reported success, check_messages stayed empty, and wait_for_message blocked until timeout with nothing to report. Both paths now go through one _home_dir() helper. R CMD check: Status OK. checks.R and pytest 37/37 pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent b06b6ed commit 64ee723

7 files changed

Lines changed: 39 additions & 25 deletions

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: ClaudeR
22
Title: R Integration for Claude AI
3-
Version: 0.13.0
3+
Version: 0.13.1
44
Authors@R: person("Nykko", "Vitali", email = "nykvt@icloud.com", role = c("aut", "cre"))
55
Description: Connects RStudio with Claude AI to enable interactive coding sessions.
66
License: MIT + file LICENSE

R/setup.R

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ configure <- function(for_cursor = FALSE, use_uvx = TRUE, python_path = NULL) {
105105

106106

107107
# --- Add or update the r-studio server entry ---
108-
config$mcpServers$`r-studio` <- list(
109-
command = mcp_command,
110-
args = mcp_args
111-
)
108+
# Update command and args in place. Anything else the user put on this entry
109+
# (most importantly an env block carrying CLAUDER_AGENT_ID) must survive, so
110+
# do not replace the whole entry.
111+
existing <- config$mcpServers$`r-studio`
112+
if (!is.list(existing)) existing <- list()
113+
existing$command <- mcp_command
114+
existing$args <- mcp_args
115+
config$mcpServers$`r-studio` <- existing
112116

113117

114118
# --- Write the updated config back to the file ---

clauder-mcp/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "clauder-mcp"
3-
version = "0.14.4"
3+
version = "0.14.5"
44
description = "MCP server connecting AI assistants to RStudio for interactive R coding and data analysis"
55
readme = "README.md"
66
requires-python = ">=3.10"

clauder-mcp/server.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
"url": "https://github.com/IMNMV/ClaudeR",
88
"source": "github"
99
},
10-
"version": "0.14.4",
10+
"version": "0.14.5",
1111
"packages": [
1212
{
1313
"registryType": "pypi",
1414
"identifier": "clauder-mcp",
15-
"version": "0.14.4",
15+
"version": "0.14.5",
1616
"transport": {
1717
"type": "stdio"
1818
}

clauder-mcp/src/clauder_mcp/server.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@
3030
# On Windows, prefer USERPROFILE explicitly. Python's expanduser already does
3131
# this internally, but being explicit guards against odd HOME settings (e.g.
3232
# OneDrive-redirected Documents) and matches the R-side discovery_dir().
33-
if sys.platform == "win32":
34-
SESSIONS_DIR = os.path.join(
35-
os.environ.get("USERPROFILE") or os.path.expanduser("~"),
36-
".claude_r_sessions",
37-
)
38-
else:
39-
SESSIONS_DIR = os.path.expanduser("~/.claude_r_sessions")
33+
def _home_dir() -> str:
34+
"""Home directory, resolved the same way the R side resolves it.
35+
36+
Every path shared with R must go through this. R uses path.expand("~"),
37+
which on Windows follows USERPROFILE, so a HOME pointing at OneDrive would
38+
otherwise put the two halves in different folders."""
39+
if sys.platform == "win32":
40+
return os.environ.get("USERPROFILE") or os.path.expanduser("~")
41+
return os.path.expanduser("~")
42+
43+
44+
SESSIONS_DIR = os.path.join(_home_dir(), ".claude_r_sessions")
4045
_agent_id: Optional[str] = None # Set in main()
4146
_agent_id_source: str = "unset" # Where the identity came from (for the intro)
4247
_target_session: Optional[str] = None # Set by connect_session tool
@@ -329,7 +334,7 @@ def _coord_dir() -> str:
329334
get_r_addin_url() # latch a session if not bound yet
330335
session = _target_session or "default"
331336
safe = re.sub(r"[^a-zA-Z0-9_-]", "_", session)
332-
d = os.path.join(os.path.expanduser("~"), ".clauder_coord", safe)
337+
d = os.path.join(_home_dir(), ".clauder_coord", safe)
333338
os.makedirs(d, mode=0o700, exist_ok=True)
334339
return d
335340

clauder-mcp/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inst/scripts/persistent_r_mcp.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@
3030
# On Windows, prefer USERPROFILE explicitly. Python's expanduser already does
3131
# this internally, but being explicit guards against odd HOME settings (e.g.
3232
# OneDrive-redirected Documents) and matches the R-side discovery_dir().
33-
if sys.platform == "win32":
34-
SESSIONS_DIR = os.path.join(
35-
os.environ.get("USERPROFILE") or os.path.expanduser("~"),
36-
".claude_r_sessions",
37-
)
38-
else:
39-
SESSIONS_DIR = os.path.expanduser("~/.claude_r_sessions")
33+
def _home_dir() -> str:
34+
"""Home directory, resolved the same way the R side resolves it.
35+
36+
Every path shared with R must go through this. R uses path.expand("~"),
37+
which on Windows follows USERPROFILE, so a HOME pointing at OneDrive would
38+
otherwise put the two halves in different folders."""
39+
if sys.platform == "win32":
40+
return os.environ.get("USERPROFILE") or os.path.expanduser("~")
41+
return os.path.expanduser("~")
42+
43+
44+
SESSIONS_DIR = os.path.join(_home_dir(), ".claude_r_sessions")
4045
_agent_id: Optional[str] = None # Set in main()
4146
_agent_id_source: str = "unset" # Where the identity came from (for the intro)
4247
_target_session: Optional[str] = None # Set by connect_session tool
@@ -329,7 +334,7 @@ def _coord_dir() -> str:
329334
get_r_addin_url() # latch a session if not bound yet
330335
session = _target_session or "default"
331336
safe = re.sub(r"[^a-zA-Z0-9_-]", "_", session)
332-
d = os.path.join(os.path.expanduser("~"), ".clauder_coord", safe)
337+
d = os.path.join(_home_dir(), ".clauder_coord", safe)
333338
os.makedirs(d, mode=0o700, exist_ok=True)
334339
return d
335340

0 commit comments

Comments
 (0)