Skip to content
Open
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
12 changes: 8 additions & 4 deletions cycode/cli/apps/ai_guardrails/session_start_command.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from typing import TYPE_CHECKING, Annotated
from typing import TYPE_CHECKING, Annotated, Optional

import typer

Expand Down Expand Up @@ -79,7 +79,7 @@ def _get_cursor_session_context() -> tuple[dict, dict]:
return mcp_servers, {}


def _report_session_context(ai_client: 'AISecurityManagerClient', ide: str) -> None:
def _report_session_context(ai_client: 'AISecurityManagerClient', ide: str, user_email: Optional[str]) -> None:
"""Report IDE session context to the AI security manager. Never raises."""
try:
if ide == AIIDEType.CLAUDE_CODE:
Expand All @@ -91,7 +91,11 @@ def _report_session_context(ai_client: 'AISecurityManagerClient', ide: str) -> N

if not mcp_servers and not enabled_plugins:
return
ai_client.report_session_context(mcp_servers=mcp_servers, enabled_plugins=enabled_plugins)
ai_client.report_session_context(
mcp_servers=mcp_servers,
enabled_plugins=enabled_plugins,
user_email=user_email,
)
except Exception as e:
logger.debug('Failed to report session context', exc_info=e)

Expand Down Expand Up @@ -148,4 +152,4 @@ def session_start_command(
logger.debug('Failed to create conversation during session start', exc_info=e)

# Step 5: Report session context (MCP servers)
_report_session_context(ai_client, ide)
_report_session_context(ai_client, ide, session_payload.ide_user_email)
2 changes: 2 additions & 0 deletions cycode/cyclient/ai_security_manager_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ def report_session_context(
self,
mcp_servers: Optional[dict] = None,
enabled_plugins: Optional[dict] = None,
user_email: Optional[str] = None,
) -> None:
"""Report session context to the backend."""
body: dict = {
'mcp_servers': mcp_servers,
'enabled_plugins': enabled_plugins,
'user_email': user_email,
}

try:
Expand Down
10 changes: 7 additions & 3 deletions tests/cli/commands/ai_guardrails/test_session_start_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def test_claude_code_reports_mcp_servers(
'gitlab': {'command': 'npx', 'args': ['-y', '@modelcontextprotocol/server-gitlab']},
'filesystem': {'command': 'npx', 'args': ['-y', '@modelcontextprotocol/server-filesystem']},
}
mock_load_config.return_value = {'oauthAccount': {'emailAddress': 'u@e.com'}, 'mcpServers': mcp_servers}
mock_load_config.return_value = {'oauthAccount': {'emailAddress': 'test@test.com'}, 'mcpServers': mcp_servers}
# Marketplace won't resolve (no extraKnownMarketplaces) so plugin gets {"enabled": True} only.
mock_load_settings.return_value = {'enabledPlugins': {'cycode-dev@cycode-marketplace': True}}

Expand All @@ -234,6 +234,7 @@ def test_claude_code_reports_mcp_servers(
mock_ai_client.report_session_context.assert_called_once_with(
mcp_servers=mcp_servers,
enabled_plugins={'cycode-dev@cycode-marketplace': {'enabled': True}},
user_email='test@test.com',
)


Expand Down Expand Up @@ -293,6 +294,7 @@ def test_claude_code_merges_plugin_mcp_servers_and_metadata(
'mcp_server_names': ['aspire'],
}
},
user_email=None,
)


Expand All @@ -311,7 +313,7 @@ def test_claude_code_no_mcp_servers_no_plugins_skips_report(
mock_get_auth.return_value = MagicMock()
mock_ai_client = MagicMock()
mock_get_client.return_value = mock_ai_client
mock_load_config.return_value = {'oauthAccount': {'emailAddress': 'u@e.com'}}
mock_load_config.return_value = {'oauthAccount': {'emailAddress': 'test@test.com'}}
mock_load_settings.return_value = None

payload = {'session_id': 'session-123'}
Expand Down Expand Up @@ -343,7 +345,9 @@ def test_cursor_reports_mcp_servers(
with patch('sys.stdin', new=StringIO(json.dumps(payload))):
session_start_command(mock_ctx, ide='cursor')

mock_ai_client.report_session_context.assert_called_once_with(mcp_servers=mcp_servers, enabled_plugins={})
mock_ai_client.report_session_context.assert_called_once_with(
mcp_servers=mcp_servers, enabled_plugins={}, user_email=None
)


@patch.object(_session_start_mod, 'load_cursor_config')
Expand Down
Loading