Skip to content

Commit 8053a01

Browse files
fix: change default client details to be more realistic
1 parent 5ba2c12 commit 8053a01

File tree

16 files changed

+130
-65
lines changed

16 files changed

+130
-65
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
* @michaelmoore-s1
2+
* @samuelmatos-s1
23
* @tjkuson-s1

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Libraries implement **standalone, reusable business logic**:
4242

4343
```python
4444
# ✅ CORRECT: Library with explicit configuration
45+
import uuid
4546
from purple_mcp.libs.purple_ai import (
4647
PurpleAIConfig,
4748
PurpleAIUserDetails,
@@ -52,6 +53,7 @@ from purple_mcp.libs.purple_ai import (
5253
user_details = PurpleAIUserDetails(
5354
account_id="account-123",
5455
team_token="team-token",
56+
session_id=uuid.uuid4().hex,
5557
email_address="user@example.com",
5658
user_agent="purple-mcp/1.0",
5759
build_date="2024-01-01",
@@ -104,6 +106,7 @@ async def purple_ai(query: str) -> str:
104106
user_details = PurpleAIUserDetails(
105107
account_id=settings.purple_ai_account_id,
106108
team_token=settings.purple_ai_team_token,
109+
session_id=settings.purple_ai_session_id,
107110
email_address=settings.purple_ai_email_address,
108111
user_agent=settings.purple_ai_user_agent,
109112
build_date=settings.purple_ai_build_date,

AUTHORS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# To see the full list of contributors, see the revision history.
44

55
Michael Moore
6-
Tom Kuson
7-
Timothy Ng
6+
Samuel Matos
87
Simin Chen
8+
Timothy Ng
9+
Tom Kuson

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased] - YYYY-MM-DD
9+
10+
## Changed
11+
12+
- Updated default values for client details to be more accurate
13+
814
## [0.5.1] - 2025-11-08
915

1016
### Added

src/purple_mcp/config.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
"""
88

99
import logging
10+
import uuid
1011
from functools import lru_cache
1112
from typing import ClassVar, Final
1213
from urllib.parse import urlparse
1314

1415
from pydantic import Field, field_validator
1516
from pydantic_settings import BaseSettings, SettingsConfigDict
1617

18+
from purple_mcp import __version__
19+
1720
logger = logging.getLogger(__name__)
1821

1922
# Environment variable prefix constants
@@ -34,6 +37,7 @@
3437
INVENTORY_RESTAPI_ENDPOINT_ENV: Final[str] = f"{ENV_PREFIX}INVENTORY_RESTAPI_ENDPOINT"
3538
PURPLE_AI_ACCOUNT_ID_ENV: Final[str] = f"{ENV_PREFIX}PURPLE_AI_ACCOUNT_ID"
3639
PURPLE_AI_TEAM_TOKEN_ENV: Final[str] = f"{ENV_PREFIX}PURPLE_AI_TEAM_TOKEN"
40+
PURPLE_AI_SESSION_ID_ENV: Final[str] = f"{ENV_PREFIX}PURPLE_AI_SESSION_ID"
3741
PURPLE_AI_EMAIL_ADDRESS_ENV: Final[str] = f"{ENV_PREFIX}PURPLE_AI_EMAIL_ADDRESS"
3842
PURPLE_AI_USER_AGENT_ENV: Final[str] = f"{ENV_PREFIX}PURPLE_AI_USER_AGENT"
3943
PURPLE_AI_BUILD_DATE_ENV: Final[str] = f"{ENV_PREFIX}PURPLE_AI_BUILD_DATE"
@@ -110,39 +114,44 @@ class Settings(BaseSettings):
110114

111115
# Purple AI User Details
112116
purple_ai_account_id: str = Field(
113-
default="AIMONITORING",
117+
default="0",
114118
description="Account ID for Purple AI user details",
115119
validation_alias=PURPLE_AI_ACCOUNT_ID_ENV,
116120
)
117121
purple_ai_team_token: str = Field(
118-
default="AIMONITORING",
122+
default="0",
119123
description="Team token for Purple AI user details",
120124
validation_alias=PURPLE_AI_TEAM_TOKEN_ENV,
121125
)
122-
purple_ai_email_address: str = Field(
123-
default="ai+purple-mcp@sentinelone.com",
126+
purple_ai_session_id: str | None = Field(
127+
default_factory=lambda: uuid.uuid4().hex,
128+
description="Session ID for Purple AI user details",
129+
validation_alias=PURPLE_AI_SESSION_ID_ENV,
130+
)
131+
purple_ai_email_address: str | None = Field(
132+
default=None,
124133
description="Email address for Purple AI user details",
125134
validation_alias=PURPLE_AI_EMAIL_ADDRESS_ENV,
126135
)
127136
purple_ai_user_agent: str = Field(
128-
default="IsaacAsimovMonitoringInc",
137+
default=f"sentinelone/purple-mcp (version {__version__})",
129138
description="User agent for Purple AI user details",
130139
validation_alias=PURPLE_AI_USER_AGENT_ENV,
131140
)
132-
purple_ai_build_date: str = Field(
133-
default="02/28/2025, 00:00:00 AM",
141+
purple_ai_build_date: str | None = Field(
142+
default=None,
134143
description="Build date for Purple AI user details",
135144
validation_alias=PURPLE_AI_BUILD_DATE_ENV,
136145
)
137-
purple_ai_build_hash: str = Field(
138-
default="N/A",
146+
purple_ai_build_hash: str | None = Field(
147+
default=None,
139148
description="Build hash for Purple AI user details",
140149
validation_alias=PURPLE_AI_BUILD_HASH_ENV,
141150
)
142151

143152
# Purple AI Console Details
144153
purple_ai_console_version: str = Field(
145-
default="S-25.1.1#30",
154+
default="S",
146155
description="Version for Purple AI console details",
147156
validation_alias=PURPLE_AI_CONSOLE_VERSION_ENV,
148157
)

src/purple_mcp/libs/purple_ai/client.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import secrets
1313
import string
1414
import time
15+
import uuid
1516
from datetime import timedelta
1617
from enum import Enum
1718
from http import HTTPStatus
@@ -26,6 +27,7 @@
2627
wait_exponential,
2728
)
2829

30+
from purple_mcp import __version__
2931
from purple_mcp.libs.purple_ai.config import (
3032
PurpleAIConfig,
3133
PurpleAIConsoleDetails,
@@ -67,12 +69,13 @@ def _build_graphql_request(
6769
end_time: int,
6870
base_url: str,
6971
version: str,
70-
account_id: str,
71-
team_token: str,
72-
email_address: str,
73-
user_agent: str,
74-
build_date: str,
75-
build_hash: str,
72+
scalyr_account_id: str,
73+
scalyr_team_token: str,
74+
session_id: str | None,
75+
email_address: str | None,
76+
user_agent: str | None,
77+
build_date: str | None,
78+
build_hash: str | None,
7679
conversation_id: str,
7780
) -> str:
7881
"""Construct a GraphQL request with properly escaped string values.
@@ -87,8 +90,9 @@ def _build_graphql_request(
8790
end_time: End time in milliseconds since epoch
8891
base_url: Console base URL
8992
version: Console version
90-
account_id: User account ID
91-
team_token: User team token
93+
scalyr_account_id: Scalyr User account ID
94+
scalyr_team_token: Scalyr User team token
95+
session_id: User session ID
9296
email_address: User email address
9397
user_agent: User agent string
9498
build_date: Build date string
@@ -121,8 +125,9 @@ def _build_graphql_request(
121125
viewSelector: EDR
122126
contentType: NATURAL_LANGUAGE
123127
userDetails: {{
124-
accountId: {json.dumps(account_id)}
125-
teamToken: {json.dumps(team_token)}
128+
accountId: {json.dumps(scalyr_account_id)}
129+
teamToken: {json.dumps(scalyr_team_token)}
130+
sessionId: {json.dumps(session_id)}
126131
emailAddress: {json.dumps(email_address)}
127132
userAgent: {json.dumps(user_agent)}
128133
buildDate: {json.dumps(build_date)}
@@ -213,8 +218,9 @@ def _generate_query(self, query: str, conversation_id_for_tests: str | None = No
213218
end_time=current_time_millis,
214219
base_url=self.config.console_details.base_url,
215220
version=self.config.console_details.version,
216-
account_id=self.config.user_details.account_id,
217-
team_token=self.config.user_details.team_token,
221+
scalyr_account_id=self.config.user_details.account_id,
222+
scalyr_team_token=self.config.user_details.team_token,
223+
session_id=self.config.user_details.session_id,
218224
email_address=self.config.user_details.email_address,
219225
user_agent=self.config.user_details.user_agent,
220226
build_date=self.config.user_details.build_date,
@@ -519,16 +525,17 @@ async def main() -> None:
519525
"""Run a test query against Purple AI."""
520526
config = PurpleAIConfig(
521527
user_details=PurpleAIUserDetails(
522-
account_id="AIMONITORING",
523-
team_token="AIMONITORING",
524-
email_address="ai+purple-mcp@sentinelone.com",
525-
user_agent="IsaacAsimovMonitoringInc",
526-
build_date="02/28/2025, 00:00:00 AM",
527-
build_hash="N/A",
528+
account_id="0",
529+
team_token="0",
530+
session_id=uuid.uuid4().hex,
531+
email_address=None,
532+
user_agent=f"sentinelone/purple-mcp (version {__version__})",
533+
build_date=None,
534+
build_hash=None,
528535
),
529536
console_details=PurpleAIConsoleDetails(
530537
base_url="https://console.example.com",
531-
version="S-25.1.1#30",
538+
version="S",
532539
),
533540
)
534541
result = await ask_purple(config, "What's the weather in Tokyo?")

src/purple_mcp/libs/purple_ai/config.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ class PurpleAIUserDetails(_ProgrammaticSettings):
2525

2626
account_id: str = Field(..., description="Account ID for the user.")
2727
team_token: str = Field(..., description="Team token for the user.")
28-
email_address: str = Field(..., description="Email address of the user.")
29-
user_agent: str = Field(..., description="User agent for the request.")
30-
build_date: str = Field(..., description="Build date of the client.")
31-
build_hash: str = Field(..., description="Build hash of the client.")
28+
session_id: str | None = Field(..., description="Session ID for the user.")
29+
email_address: str | None = Field(..., description="Email address of the user.")
30+
user_agent: str | None = Field(..., description="User agent for the request.")
31+
build_date: str | None = Field(..., description="Build date of the client.")
32+
build_hash: str | None = Field(..., description="Build hash of the client.")
3233

3334

3435
class PurpleAIConsoleDetails(_ProgrammaticSettings):

src/purple_mcp/libs/purple_ai/docs/API.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Ask Purple AI a question asynchronously.
1818

1919
**Example:**
2020
```python
21+
import uuid
2122
import asyncio
2223
from purple_mcp.libs.purple_ai import (
2324
ask_purple,
@@ -34,6 +35,7 @@ async def main():
3435
user_details=PurpleAIUserDetails(
3536
account_id="123456789",
3637
team_token="team-token",
38+
session_id=uuid.uuid4().hex,
3739
email_address="user@example.com",
3840
user_agent="MyApp/1.0",
3941
build_date="2025-01-01",
@@ -519,4 +521,4 @@ _result_type, response = await ask_purple("What is SentinelOne?", config)
519521
assert response is not None
520522
assert len(response) > 0
521523
assert isinstance(response, str)
522-
```
524+
```

src/purple_mcp/tools/purple_ai.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ async def purple_ai(query: str) -> str:
129129
user_details = PurpleAIUserDetails(
130130
account_id=settings.purple_ai_account_id,
131131
team_token=settings.purple_ai_team_token,
132+
session_id=settings.purple_ai_session_id,
132133
email_address=settings.purple_ai_email_address,
133134
user_agent=settings.purple_ai_user_agent,
134135
build_date=settings.purple_ai_build_date,

tests/integration/test_purple_ai_integration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def real_config(self, integration_env_check: dict[str, str]) -> PurpleAIConfig:
4141
user_details=PurpleAIUserDetails(
4242
account_id=settings.purple_ai_account_id,
4343
team_token=settings.purple_ai_team_token,
44+
session_id=settings.purple_ai_session_id,
4445
email_address=settings.purple_ai_email_address,
4546
user_agent=settings.purple_ai_user_agent,
4647
build_date=settings.purple_ai_build_date,

0 commit comments

Comments
 (0)