Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions scripts/install-macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ if 'mcpServers' not in config:
# Add/update Home Assistant config (using full path for Claude Desktop compatibility)
config['mcpServers']['Home Assistant'] = {
"command": uvx_path,
"args": ["ha-mcp@latest"],
"args": ["--refresh", "ha-mcp@latest"],
"env": {
"HOMEASSISTANT_URL": demo_url,
"HOMEASSISTANT_TOKEN": demo_token
Expand All @@ -140,7 +140,7 @@ else
"mcpServers": {
"Home Assistant": {
"command": "$UVX_PATH",
"args": ["ha-mcp@latest"],
"args": ["--refresh", "ha-mcp@latest"],
"env": {
"HOMEASSISTANT_URL": "$DEMO_URL",
"HOMEASSISTANT_TOKEN": "$DEMO_TOKEN"
Expand All @@ -157,7 +157,7 @@ printf "\n"
# Step 3: Pre-download dependencies
printf "${YELLOW}Step 3: Pre-downloading ha-mcp...${NC}\n"
printf " This speeds up Claude Desktop startup...\n"
"$UVX_PATH" ha-mcp@latest --version > /dev/null 2>&1 || true
"$UVX_PATH" --refresh ha-mcp@latest --version > /dev/null 2>&1 || true
printf "${GREEN} Dependencies cached${NC}\n"
printf "\n"

Expand Down
4 changes: 2 additions & 2 deletions scripts/install-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ $JsonConfig = @"
"mcpServers": {
"Home Assistant": {
"command": "uvx",
"args": ["ha-mcp@latest"],
"args": ["--refresh", "ha-mcp@latest"],
"env": {
"HOMEASSISTANT_URL": "$DemoUrl",
"HOMEASSISTANT_TOKEN": "$DemoToken"
Expand Down Expand Up @@ -114,7 +114,7 @@ Write-Host ""
Write-Host "Step 3: Pre-downloading ha-mcp..." -ForegroundColor Yellow
Write-Host " This speeds up Claude Desktop startup..."
try {
& uvx ha-mcp@latest --version 2>&1 | Out-Null
& uvx --refresh ha-mcp@latest --version 2>&1 | Out-Null
Write-Host " Dependencies cached" -ForegroundColor Green
} catch {
Write-Host " Pre-download skipped (will download on first use)" -ForegroundColor Yellow
Expand Down
13 changes: 10 additions & 3 deletions src/ha_mcp/utils/usage_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,22 @@ class UsageLogger:

def __init__(
self,
log_file_path: str = "logs/mcp_usage.jsonl",
log_file_path: str | None = None,
ring_buffer_size: int = DEFAULT_RING_BUFFER_SIZE,
):
self._enabled = True
self.log_file_path = Path(log_file_path)

if log_file_path:
self.log_file_path = Path(log_file_path)
else:
# Use user's home directory by default to avoid read-only filesystem errors
# when running via uvx/npx which might have read-only CWD
self.log_file_path = Path.home() / ".ha-mcp" / "logs" / "mcp_usage.jsonl"

try:
self.log_file_path.parent.mkdir(parents=True, exist_ok=True)
except OSError:
# Directory creation failed (e.g., read-only filesystem when running via uvx)
# Directory creation failed (e.g., read-only filesystem)
# Disable logging silently to avoid disrupting the MCP server
self._enabled = False

Expand Down
11 changes: 11 additions & 0 deletions tests/src/unit/test_usage_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,17 @@ def test_ring_buffer_with_error_entries(self, logger):
assert entries[0]["error_message"] == "Entity not found"


class TestUsageLoggerDefaults:
"""Test UsageLogger default behavior."""

def test_default_log_path(self):
"""Test that default log path is in user home directory."""
logger = UsageLogger()
assert str(logger.log_file_path).startswith(str(Path.home()))
assert ".ha-mcp" in str(logger.log_file_path)
Comment on lines +176 to +177

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assertions here are a bit loose. Using startswith and in could potentially pass for incorrect paths. A direct equality check against the expected Path object would be more precise and robust. This ensures the path is exactly what's expected, including all components.

Suggested change
assert str(logger.log_file_path).startswith(str(Path.home()))
assert ".ha-mcp" in str(logger.log_file_path)
expected_path = Path.home() / ".ha-mcp" / "logs" / "mcp_usage.jsonl"
assert logger.log_file_path == expected_path

logger.shutdown()


class TestUsageLoggerConstants:
"""Test constants are properly defined."""

Expand Down