Skip to content

Commit adefcde

Browse files
fix: improve default client details (#11)
## Changes Default client details to be more accurate. Previously non-realistic values were being used.
1 parent 5ba2c12 commit adefcde

File tree

19 files changed

+164
-78
lines changed

19 files changed

+164
-78
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="[email protected]",
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="[email protected]",
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/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ async def main():
3131
user_details=PurpleAIUserDetails(
3232
account_id="your-account-id",
3333
team_token="your-team-token",
34+
session_id="your-session-id",
3435
email_address="[email protected]",
3536
user_agent="PurpleAI-Client/1.0",
3637
build_date="2024-01-01",
@@ -79,4 +80,4 @@ The library requires a SentinelOne console service token with appropriate permis
7980

8081
## Contributing
8182

82-
This library follows the purple-mcp project's contribution guidelines. See the main project's CONTRIBUTING.md for details.
83+
This library follows the purple-mcp project's contribution guidelines. See the main project's CONTRIBUTING.md for details.

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="[email protected]",
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: 17 additions & 5 deletions
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,14 +35,15 @@ 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="[email protected]",
3840
user_agent="MyApp/1.0",
3941
build_date="2025-01-01",
4042
build_hash="abc123",
4143
),
4244
console_details=PurpleAIConsoleDetails(
4345
base_url="https://console.example.com",
44-
version="S-25.1.1#30",
46+
version="S",
4547
),
4648
)
4749

@@ -72,6 +74,7 @@ Ask Purple AI a question synchronously.
7274

7375
**Example:**
7476
```python
77+
import uuid
7578
from purple_mcp.libs.purple_ai import sync_ask_purple, PurpleAIConfig, PurpleAIUserDetails, PurpleAIConsoleDetails
7679

7780
config = PurpleAIConfig(
@@ -80,14 +83,15 @@ config = PurpleAIConfig(
8083
user_details=PurpleAIUserDetails(
8184
account_id="123456789",
8285
team_token="team-token",
86+
session_id=uuid.uuid4().hex,
8387
email_address="[email protected]",
8488
user_agent="MyApp/1.0",
8589
build_date="2025-01-01",
8690
build_hash="abc123"
8791
),
8892
console_details=PurpleAIConsoleDetails(
8993
base_url="https://console.example.com",
90-
version="S-25.1.1#30"
94+
version="S"
9195
)
9296
)
9397

@@ -120,6 +124,7 @@ PurpleAIConfig(
120124

121125
#### Example
122126
```python
127+
import uuid
123128
from purple_mcp.libs.purple_ai import (
124129
PurpleAIConfig,
125130
PurpleAIConsoleDetails,
@@ -131,11 +136,12 @@ config = PurpleAIConfig(
131136
auth_token="your-service-token",
132137
console_details=PurpleAIConsoleDetails(
133138
base_url="https://console.example.com",
134-
version="S-25.1.1#30"
139+
version="S"
135140
),
136141
user_details=PurpleAIUserDetails(
137142
account_id="123456789",
138143
team_token="team-token-abc",
144+
session_id=uuid.uuid4().hex,
139145
email_address="[email protected]",
140146
user_agent="MyApp/1.0",
141147
build_date="2025-01-15",
@@ -164,7 +170,7 @@ PurpleAIConsoleDetails(
164170
```python
165171
console_details = PurpleAIConsoleDetails(
166172
base_url="https://console.example.com",
167-
version="S-25.1.1#30"
173+
version="S"
168174
)
169175
```
170176

@@ -177,6 +183,7 @@ User-specific configuration details.
177183
PurpleAIUserDetails(
178184
account_id: str,
179185
team_token: str,
186+
session_id: str,
180187
email_address: str,
181188
user_agent: str,
182189
build_date: str,
@@ -197,6 +204,7 @@ PurpleAIUserDetails(
197204
user_details = PurpleAIUserDetails(
198205
account_id="123456789",
199206
team_token="team-token-abc",
207+
session_id=uuid.uuid4().hex,
200208
email_address="[email protected]",
201209
user_agent="SecurityTools/2.1 (Python/3.11)",
202210
build_date="2025-01-15",
@@ -411,6 +419,7 @@ The library can use environment variables for configuration:
411419

412420
```python
413421
import os
422+
import uuid
414423
from purple_mcp.libs.purple_ai import PurpleAIConfig
415424

416425
def create_config_from_env():
@@ -422,6 +431,7 @@ def create_config_from_env():
422431
user_details=PurpleAIUserDetails(
423432
account_id=os.getenv("PURPLEMCP_PURPLE_AI_ACCOUNT_ID", ""),
424433
team_token=os.getenv("PURPLEMCP_PURPLE_AI_TEAM_TOKEN", ""),
434+
session_id=os.getenv("PURPLEMCP_PURPLE_AI_SESSION_ID", uuid.uuid4().hex),
425435
email_address=os.getenv("PURPLEMCP_PURPLE_AI_EMAIL_ADDRESS", ""),
426436
user_agent=os.getenv("PURPLEMCP_PURPLE_AI_USER_AGENT", "PurpleAI/1.0"),
427437
build_date=os.getenv("PURPLEMCP_PURPLE_AI_BUILD_DATE", ""),
@@ -468,6 +478,7 @@ test_config = PurpleAIConfig(
468478
user_details=PurpleAIUserDetails(
469479
account_id="test-account",
470480
team_token="test-team-token",
481+
session_id="test-session-id",
471482
email_address="[email protected]",
472483
user_agent="TestClient/1.0",
473484
build_date="2025-01-01",
@@ -503,6 +514,7 @@ async def test_purple_ai_integration():
503514
user_details=PurpleAIUserDetails(
504515
account_id=os.getenv("PURPLEMCP_PURPLE_AI_ACCOUNT_ID"),
505516
team_token=os.getenv("PURPLEMCP_PURPLE_AI_TEAM_TOKEN"),
517+
session_id=os.getenv("PURPLEMCP_PURPLE_AI_SESSION_ID"),
506518
email_address=os.getenv("PURPLEMCP_PURPLE_AI_EMAIL_ADDRESS"),
507519
user_agent=os.getenv("PURPLEMCP_PURPLE_AI_USER_AGENT", "IntegrationTest/1.0"),
508520
build_date=os.getenv("PURPLEMCP_PURPLE_AI_BUILD_DATE"),
@@ -519,4 +531,4 @@ _result_type, response = await ask_purple("What is SentinelOne?", config)
519531
assert response is not None
520532
assert len(response) > 0
521533
assert isinstance(response, str)
522-
```
534+
```

0 commit comments

Comments
 (0)