mcpower-proxy 0.0.73__py3-none-any.whl → 0.0.77__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,12 +16,12 @@ class OutputFormat:
16
16
  allow_exit_code: int
17
17
  deny_exit_code: int
18
18
  error_exit_code: int
19
-
19
+
20
20
  # Output formatter function
21
21
  # Args: (hook_type: str, allowed: bool, user_msg: Optional[str], agent_msg: Optional[str]) -> str
22
22
  formatter: Callable[[str, bool, Optional[str], Optional[str]], str]
23
-
24
-
23
+
24
+
25
25
  @dataclass
26
26
  class HookConfig:
27
27
  """
@@ -32,4 +32,3 @@ class HookConfig:
32
32
  server_name: str # IDE-specific tool server name
33
33
  client_name: str # IDE-specific client name (e.g. "cursor", "claude-code")
34
34
  max_content_length: int # Maximum content length before skipping API call
35
-
@@ -7,7 +7,8 @@ import re
7
7
  from collections import Counter
8
8
  from typing import Dict, Any, List, Callable, Optional
9
9
 
10
- from mcpower_shared.mcp_types import create_policy_request, create_policy_response, AgentContext, EnvironmentContext
10
+ from mcpower_shared.mcp_types import create_policy_request, create_policy_response, AgentContext, EnvironmentContext, \
11
+ ServerRef, ToolRef
11
12
  from modules.apis.security_policy import SecurityPolicyClient
12
13
  from modules.decision_handler import DecisionHandler
13
14
  from modules.logs.audit_trail import AuditTrailLogger
@@ -229,9 +230,14 @@ async def inspect_and_enforce(
229
230
  if is_request:
230
231
  policy_request = create_policy_request(
231
232
  event_id=event_id,
232
- server_name=server_name,
233
- server_transport="stdio",
234
- tool_name=tool_name,
233
+ server=ServerRef(
234
+ name=server_name,
235
+ transport="stdio",
236
+ context="ide"
237
+ ),
238
+ tool=ToolRef(
239
+ name=tool_name
240
+ ),
235
241
  agent_context=agent_context,
236
242
  env_context=env_context,
237
243
  arguments=content_data
@@ -243,9 +249,14 @@ async def inspect_and_enforce(
243
249
  else:
244
250
  policy_response = create_policy_response(
245
251
  event_id=event_id,
246
- server_name=server_name,
247
- server_transport="stdio",
248
- tool_name=tool_name,
252
+ server=ServerRef(
253
+ name=server_name,
254
+ transport="stdio",
255
+ context="ide"
256
+ ),
257
+ tool=ToolRef(
258
+ name=tool_name
259
+ ),
249
260
  response_content=safe_json_dumps(content_data),
250
261
  agent_context=agent_context,
251
262
  env_context=env_context
@@ -273,4 +284,3 @@ async def inspect_and_enforce(
273
284
  )
274
285
 
275
286
  return decision
276
-
@@ -68,6 +68,7 @@ def route_cursor_hook(logger: MCPLogger, audit_logger: AuditTrailLogger, stdin_i
68
68
  logger=logger,
69
69
  audit_logger=audit_logger,
70
70
  event_id=event_id,
71
+ prompt_id=prompt_id,
71
72
  cwd=cwd,
72
73
  server_name=CURSOR_CONFIG.server_name,
73
74
  client_name="cursor",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcpower-proxy
3
- Version: 0.0.73
3
+ Version: 0.0.77
4
4
  Summary: MCPower Security proxy
5
5
  Author-email: MCPower Security <support@mcpower.tech>
6
6
  License: Apache License
@@ -216,7 +216,8 @@ Requires-Dist: watchdog>=3.0.0
216
216
  Requires-Dist: jsonc-parser>=1.1.5
217
217
  Requires-Dist: jsonpath-ng>=1.7.0
218
218
  Requires-Dist: pydantic>=2.8.0
219
- Requires-Dist: mcpower-shared==0.1.3
219
+ Requires-Dist: mcpower-shared==0.1.4
220
+ Requires-Dist: bashlex>=0.18
220
221
  Dynamic: license-file
221
222
 
222
223
  # MCPower Proxy
@@ -1,31 +1,32 @@
1
1
  main.py,sha256=MahoqxG5euEJwLhosv2OVUkVbTaMkph_je8lgmtc7Z4,3920
2
2
  ide_tools/__init__.py,sha256=odLisqEeKVuZupQoeM-uP9WgQseVTYQG0eP2hhwUyAc,250
3
3
  ide_tools/router.py,sha256=PbGz1cwUXR3Bcy879W2wgmT4f2uThXiXevpWSxcgKZQ,1538
4
- ide_tools/common/__init__.py,sha256=ALhDYMw8v9tlYVEVcx3kP-e6c0yEyRQAQYe7sqwHHB4,66
5
- ide_tools/common/hooks/__init__.py,sha256=px5Ibzn6rlBcprp7RiZwGWnnWJmGITb0ApiXWKbeyRM,62
6
- ide_tools/common/hooks/init.py,sha256=QH3qhXqOfQj1IzAXRxgDXu2zDnLHJ-_3PFZWq6Zp-TI,4044
7
- ide_tools/common/hooks/output.py,sha256=xmOGmPLXy4H3A2G2A95WxqIB4qCWbVO9sq-pz2clyzU,1856
8
- ide_tools/common/hooks/prompt_submit.py,sha256=-3rwH_e_uywAN9PV_IpSAOEeU21DMJ15PyMLlmwWiPA,7325
9
- ide_tools/common/hooks/read_file.py,sha256=d8p_IpGwgWG9Vn0yd78KPRzoDi3RacmqxiTaFqndBa0,6481
10
- ide_tools/common/hooks/shell_execution.py,sha256=uneYaiU8YQhzEjishnSW3SZGdU4Ob0hgSgo7TK5InQw,7154
11
- ide_tools/common/hooks/types.py,sha256=nT_3rZ7J8b70o2FcY1lkYSFI4Z3WfD7oQgUEGSiFIbQ,1036
12
- ide_tools/common/hooks/utils.py,sha256=R_jKQdG98oQhooMXV_l2xURIvYgi0Y9UwZyGbcx0LuU,9144
4
+ ide_tools/common/__init__.py,sha256=cW2cN5y2l4PHGkkWtYgydrtXtmLU_UipJAf_c0VMTk0,65
5
+ ide_tools/common/hooks/__init__.py,sha256=O-waaJU1OQFxplrLZymSSiIyLDNlGlki6nX-nbJiqz0,61
6
+ ide_tools/common/hooks/init.py,sha256=X0J_rEjU6qjvDaPOh-obzSqfICMsOGc6VxRjcZqLTqQ,4117
7
+ ide_tools/common/hooks/output.py,sha256=FBezJL1S5vzLJWW_cLht4XFLDJvhV_w-UTqCQOLEusE,1879
8
+ ide_tools/common/hooks/prompt_submit.py,sha256=_FysGrlJXcblex-OapWVIv1bedP1IKR2d1cvkINU0uM,4907
9
+ ide_tools/common/hooks/read_file.py,sha256=FBHTxOXrQWlw2qtddAq4gfv5h1g6rTbQ-0uqqL9wXE0,6456
10
+ ide_tools/common/hooks/shell_execution.py,sha256=KbJSGLW__bPso45eAlbV13nnkKYwwd7-KodZ6VyUnS0,9522
11
+ ide_tools/common/hooks/shell_parser_bashlex.py,sha256=ePit2jduHvBYkmEvcslpjCGJ5H-amVEm1We1vVCmMNc,15002
12
+ ide_tools/common/hooks/types.py,sha256=ndisZ8YoasQ3HlVzzyLmpiBCQJs43YPmixbaIIxRpZM,1023
13
+ ide_tools/common/hooks/utils.py,sha256=7Q95IZZG_lShq5Jvw78M7QN5-tVNVeFzLU33qB8boEU,9425
13
14
  ide_tools/cursor/__init__.py,sha256=YW_V8m0A0bou0wQW_wy3nt2L_7MaNWeNKYBx-NQkilw,153
14
15
  ide_tools/cursor/constants.py,sha256=KMRBRqxRxTdemMoq81TVG6avt3ATtsPo4aJo8XhSctk,1804
15
16
  ide_tools/cursor/format.py,sha256=Lh-KH1IlsLL-0B98Bz-ywxpwXL8urK7yPteZGBTPOiY,972
16
- ide_tools/cursor/router.py,sha256=AmRv1kfDEd3EULSlRjj0BDtedlyqtgFgSBp25iMxJBI,3856
17
- mcpower_proxy-0.0.73.dist-info/licenses/LICENSE,sha256=U6WUzdnBrbmVxBmY75ikW-KtinwYnowZ7yNb5hECrvY,11337
17
+ ide_tools/cursor/router.py,sha256=GXmXcNSIA9pe1vnmmoYpz0dyC_B7OSpQwOVHIV7YUEI,3893
18
+ mcpower_proxy-0.0.77.dist-info/licenses/LICENSE,sha256=U6WUzdnBrbmVxBmY75ikW-KtinwYnowZ7yNb5hECrvY,11337
18
19
  modules/__init__.py,sha256=mJglXQwSRhU-bBv4LXgfu7NfGN9K4BeQWMPApen5rAA,30
19
20
  modules/decision_handler.py,sha256=P8isKzf4GIWz9SK-VJPtO8VJEgNp7rAIcVZngnaLHmw,9574
20
21
  modules/apis/__init__.py,sha256=Y5WZpKJzHpnRJebk0F80ZRTjR2PpA2LlYLgqI3XlmRo,15
21
22
  modules/apis/security_policy.py,sha256=3fljaTpzfh_Nj0-jVvbnCJBL-CZxvqFNWfSlrAawsBc,15103
22
23
  modules/logs/__init__.py,sha256=dpboUQjuO02z8K-liCbm2DYkCa-CB_ZDV9WSSjNm7Fs,15
23
- modules/logs/audit_trail.py,sha256=_jE9A3WG7ooPUphDHpUFnZ6de16ewhdXYV-tV2__zxo,6183
24
+ modules/logs/audit_trail.py,sha256=yoxzvRDI8ldjC-5o9__PkvaAbM33jWbq_8Sm6uKj8o8,6198
24
25
  modules/logs/logger.py,sha256=MJS0P8VEzUX-5udzQitznaBPCBAcZJCygUgwaDWSq94,4087
25
26
  modules/redaction/__init__.py,sha256=e5NTmp-zonUdzzscih-w_WQ-X8Nvb8CE8b_d6SbrwWg,316
26
27
  modules/redaction/constants.py,sha256=xbDSX8n72FuJu6JJ_sbBE0f5OcWuwEwHxBZuK9Xz-TI,1213
27
- modules/redaction/gitleaks_rules.py,sha256=8dRb4g5OQaHAjx8vpMbxwu06CdDE39aqw9eqLiCDcqY,46411
28
- modules/redaction/pii_rules.py,sha256=-JhjcCjH5NFeOfQGzTFNdx_-s_0i6tZ-XFxydtkByD0,10019
28
+ modules/redaction/gitleaks_rules.py,sha256=8NHR5kr2XSrPn4c0PsjD0je6p8gmNzq2vI098QUxAx0,46397
29
+ modules/redaction/pii_rules.py,sha256=H7WOIMZZK8mkwdvnBe0J2nPwqzKqGHdUbCSGpxJGT8s,7666
29
30
  modules/redaction/redactor.py,sha256=Y3PSxXJSLJZj8gkKZ3OQ7XxoIPUilFk6gY0dbeqfjwE,23352
30
31
  modules/ui/__init__.py,sha256=YlW4XfQEGW1ezg3UFU59nHw95LicmlpNPhim5IqSB50,34
31
32
  modules/ui/classes.py,sha256=ZvVRdzO_hD4WnpS3_eVa0WCyaooXiYVpHLzQkzBaH6M,1777
@@ -47,13 +48,15 @@ modules/utils/copy.py,sha256=9OJIqWn8PxPZXr3DTt_01jp0YgmPimckab1969WFh0c,1075
47
48
  modules/utils/ids.py,sha256=rhhRz7RmFjuJGYLft1erHz7vJII1DRpr3iHxBhhFl1s,5743
48
49
  modules/utils/json.py,sha256=OA-JtSBqh9qd1yfm-iyOefNBMH3ITFUdxAkj7O_JZ-Y,4024
49
50
  modules/utils/mcp_configs.py,sha256=DZaujZnF9LlPDJHzyepH7fWSt1GTr-FEmShPCqnZ5aI,1829
51
+ modules/utils/platform.py,sha256=Kz1Dh_UkvMbfXqiyZIEj7INYaWE9wT6nM9WIKXM91uM,552
52
+ modules/utils/string.py,sha256=cOuwWReyBwOgjxtTRPq1R6pCpfkgfqVmjdiaDPufIZU,456
50
53
  wrapper/__init__.py,sha256=OJUsuWSoN1JqIHq4bSrzuL7ufcYJcwAmYCrJjLH44LM,22
51
- wrapper/__version__.py,sha256=rCTF1Ssof33lV_ElQ2Jd40DYgONJlHNMKTaVGHBP-go,82
52
- wrapper/middleware.py,sha256=77mZ30DApRlcX7__JzNFlqwKvR1mBYQg5izHbpZiNnw,29854
54
+ wrapper/__version__.py,sha256=4LwZ6ftjxW5rGtS8e8B6V7iXNQZbgnact3whK05F-gg,82
55
+ wrapper/middleware.py,sha256=rXOIduymDLeJ56AWmpMnRnkf7sCmSz7jADMk-v8lcsw,30232
53
56
  wrapper/schema.py,sha256=O-CtKI9eJ4eEnqeUXPCrK7QJAFJrdp_cFbmMyg452Aw,7952
54
57
  wrapper/server.py,sha256=zoIW_bqXV9vKZNFtD-ij0X_LtKJEjucda6lQI5mU6qY,3440
55
- mcpower_proxy-0.0.73.dist-info/METADATA,sha256=XZE3Lk26Hb6MLROM7HbBm9CbJApBPcw-N6U_-3eZyak,15669
56
- mcpower_proxy-0.0.73.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
57
- mcpower_proxy-0.0.73.dist-info/entry_points.txt,sha256=0smL8dxE7ERNz6XEggNaUC3QzKp8mD-v4q5nVEo0MXE,48
58
- mcpower_proxy-0.0.73.dist-info/top_level.txt,sha256=OcCYMHHqbZq3mP5IZDRGdHUNOsKhT1XVnk_mDF_49Es,31
59
- mcpower_proxy-0.0.73.dist-info/RECORD,,
58
+ mcpower_proxy-0.0.77.dist-info/METADATA,sha256=qX1CZtp76YNug7gOFHOmdJG4gXn3FvV7P_bHQ9iySV0,15698
59
+ mcpower_proxy-0.0.77.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
+ mcpower_proxy-0.0.77.dist-info/entry_points.txt,sha256=0smL8dxE7ERNz6XEggNaUC3QzKp8mD-v4q5nVEo0MXE,48
61
+ mcpower_proxy-0.0.77.dist-info/top_level.txt,sha256=OcCYMHHqbZq3mP5IZDRGdHUNOsKhT1XVnk_mDF_49Es,31
62
+ mcpower_proxy-0.0.77.dist-info/RECORD,,
@@ -53,6 +53,7 @@ class AuditTrailLogger:
53
53
  self,
54
54
  event_type: str,
55
55
  data: Dict[str, Any],
56
+ *,
56
57
  event_id: Optional[str] = None,
57
58
  prompt_id: Optional[str] = None,
58
59
  user_prompt: Optional[str] = None,
@@ -88,14 +89,14 @@ class AuditTrailLogger:
88
89
  if prompt_id:
89
90
  event["prompt_id"] = prompt_id
90
91
 
91
- # Include user_prompt text if provided (only needed once per prompt_id)
92
- if user_prompt:
93
- event["user_prompt"] = user_prompt
94
-
95
92
  # Include event_id if provided (for pairing request/response)
96
93
  if event_id:
97
94
  event["event_id"] = event_id
98
95
 
96
+ # Include user_prompt text if provided (only needed once per prompt_id)
97
+ if user_prompt:
98
+ event["user_prompt"] = user_prompt
99
+
99
100
  # If app_uid not set yet, queue the log
100
101
  if self.app_uid is None:
101
102
  self._pending_logs.append(event)
@@ -3,7 +3,7 @@ from typing import Dict, List, Tuple
3
3
 
4
4
  # This file is auto-generated from Gitleaks rules. Do not edit manually.
5
5
  # Source: https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml
6
- # Generation script: targets/vsc-extension/scripts/update-gitleaks-rules.mjs
6
+ # Generation script: targets/scripts/update-gitleaks-rules.mjs
7
7
 
8
8
  COMPILED_RULES: List[Tuple[str, re.Pattern, int, List[str]]] = [
9
9
  (
@@ -60,15 +60,8 @@ class PIIDetector:
60
60
  """Lightweight PII detector using only regex patterns."""
61
61
 
62
62
  def __init__(self):
63
- # URL detector with intelligent boundary detection
64
- self.url_detector = URLDetector()
65
-
66
63
  # Compile regex patterns for better performance
67
64
  self.patterns = {
68
- 'EMAIL_ADDRESS': re.compile(
69
- r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
70
- re.IGNORECASE
71
- ),
72
65
  'CREDIT_CARD': re.compile(
73
66
  r'\b(?:'
74
67
  r'4[0-9]{3}[-\s]?[0-9]{4}[-\s]?[0-9]{4}[-\s]?[0-9]{4}(?:[0-9]{3})?|' # Visa with formatting
@@ -81,40 +74,6 @@ class PIIDetector:
81
74
  r'6(?:011|5[0-9]{2})[0-9]{12}' # Discover
82
75
  r')\b'
83
76
  ),
84
- 'IP_ADDRESS': re.compile(
85
- r'(?:'
86
- # IPv4
87
- r'\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}'
88
- r'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'
89
- r'|'
90
- # IPv6 - comprehensive pattern
91
- r'(?:'
92
- # Full IPv6 or with :: compression
93
- r'(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' # Full: 1:2:3:4:5:6:7:8
94
- r'(?:[0-9a-fA-F]{1,4}:){1,7}:|' # Compressed trailing: 1:: or 1:2:3:4:5:6:7::
95
- r'(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' # Compressed middle: 1::8 or 1:2:3:4:5:6::8
96
- r'(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|' # 1::7:8 or 1:2:3:4:5::7:8
97
- r'(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|' # 1::6:7:8 or 1:2:3:4::6:7:8
98
- r'(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|' # 1::5:6:7:8 or 1:2:3::5:6:7:8
99
- r'(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|' # 1::4:5:6:7:8 or 1:2::4:5:6:7:8
100
- r'[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|' # 1::3:4:5:6:7:8
101
- r':(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|' # ::2:3:4:5:6:7:8 or ::
102
- # IPv4-mapped IPv6: ::ffff:192.0.2.1
103
- r'(?:[0-9a-fA-F]{1,4}:){1,4}:'
104
- r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}'
105
- r'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
106
- r')'
107
- r')',
108
- re.IGNORECASE
109
- ),
110
- # Common crypto addresses
111
- 'CRYPTO_ADDRESS': re.compile(
112
- r'\b(?:'
113
- r'[13][a-km-zA-HJ-NP-Z1-9]{25,34}|' # Bitcoin
114
- r'0x[a-fA-F0-9]{40}|' # Ethereum
115
- r'[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}' # Litecoin
116
- r')\b'
117
- ),
118
77
  # IBAN (International Bank Account Number)
119
78
  'IBAN': re.compile(
120
79
  r'\b[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{7}([A-Z0-9]?){0,16}\b'
@@ -176,9 +135,6 @@ class PIIDetector:
176
135
  """
177
136
  matches = []
178
137
 
179
- # Extract URLs using URLDetector
180
- matches.extend(self.url_detector.extract(text))
181
-
182
138
  # Extract other PII using regex patterns
183
139
  for entity_type, pattern in self.patterns.items():
184
140
  for match in pattern.finditer(text):
@@ -212,11 +168,7 @@ class PIIDetector:
212
168
  """Calculate confidence score based on entity type and matched text."""
213
169
  # Base confidence scores
214
170
  base_scores = {
215
- 'EMAIL_ADDRESS': 0.95,
216
171
  'CREDIT_CARD': 0.85, # Will be 0.99 after Luhn validation
217
- 'IP_ADDRESS': 0.90,
218
- 'URL': 0.80,
219
- 'CRYPTO_ADDRESS': 0.95,
220
172
  'IBAN': 0.85, # Will be 0.99 after MOD-97 validation
221
173
  }
222
174
 
@@ -0,0 +1,23 @@
1
+ """Platform detection utilities"""
2
+ import sys
3
+ from typing import Optional, Literal
4
+
5
+
6
+ def get_client_os() -> Optional[Literal["macos", "windows", "linux"]]:
7
+ """
8
+ Fetch Python's sys.platform and convert to standardized OS names.
9
+
10
+ Returns:
11
+ "macos", "windows", "linux", or None if platform is unknown
12
+ """
13
+ platform = sys.platform
14
+
15
+ if platform == "darwin":
16
+ return "macos"
17
+ elif platform == "win32":
18
+ return "windows"
19
+ elif platform == "linux":
20
+ return "linux"
21
+ else:
22
+ return None
23
+
@@ -0,0 +1,17 @@
1
+ """String utility functions"""
2
+
3
+
4
+ def truncate_at(text: str, max_length: int) -> str:
5
+ """
6
+ Truncate string at max_length, appending '...' only if truncated.
7
+
8
+ Args:
9
+ text: String to truncate
10
+ max_length: Maximum length before truncation
11
+
12
+ Returns:
13
+ Truncated string with '...' suffix if truncated, original if not
14
+ """
15
+ if len(text) <= max_length:
16
+ return text
17
+ return f"{text[:max_length]}..."
wrapper/__version__.py CHANGED
@@ -3,4 +3,4 @@
3
3
  Wrapper MCP Server Version
4
4
  """
5
5
 
6
- __version__ = "0.0.73"
6
+ __version__ = "0.0.77"
wrapper/middleware.py CHANGED
@@ -28,6 +28,8 @@ from modules.utils.copy import safe_copy
28
28
  from modules.utils.ids import generate_event_id, get_session_id, read_app_uid, get_project_mcpower_dir
29
29
  from modules.utils.json import safe_json_dumps, to_dict
30
30
  from modules.utils.mcp_configs import extract_wrapped_server_info
31
+ from modules.utils.platform import get_client_os
32
+ from modules.utils.string import truncate_at
31
33
  from wrapper.schema import merge_input_schema_with_existing
32
34
 
33
35
 
@@ -173,7 +175,7 @@ class SecurityMiddleware(Middleware):
173
175
  async def secure_elicitation_handler(self, message, response_type, params, context):
174
176
  # FIXME: elicitation message, params, and context should be redacted before logging
175
177
  self.logger.info(f"secure_elicitation_handler: "
176
- f"message={str(message)[:100]}..., response_type={response_type},"
178
+ f"message={truncate_at(str(message), 100)}, response_type={response_type},"
177
179
  f"params={params}, context={context}")
178
180
 
179
181
  mock_context = MockContext(
@@ -203,7 +205,7 @@ class SecurityMiddleware(Middleware):
203
205
 
204
206
  async def secure_log_handler(self, log_message):
205
207
  # FIXME: log_message should be redacted before logging,
206
- self.logger.info(f"secure_log_handler: {str(log_message)[:100]}...")
208
+ self.logger.info(f"secure_log_handler: {truncate_at(str(log_message), 100)}")
207
209
  # FIXME: log_message should be reviewed with policy before forwarding
208
210
 
209
211
  # Handle case where log_message.data is a string instead of dict
@@ -568,9 +570,13 @@ class SecurityMiddleware(Middleware):
568
570
  base_dict = await self._build_baseline_policy_dict(event_id, context, wrapper_args, tool_args)
569
571
  policy_request = create_policy_request(
570
572
  event_id=event_id,
571
- server_name=base_dict["server"]["name"],
572
- server_transport=base_dict["server"]["transport"],
573
- tool_name=base_dict["tool"]["name"] or base_dict["tool"]["method"],
573
+ server=ServerRef(
574
+ name=base_dict["server"]["name"],
575
+ transport=base_dict["server"]["transport"]
576
+ ),
577
+ tool=ToolRef(
578
+ name=base_dict["tool"]["name"] or base_dict["tool"]["method"]
579
+ ),
574
580
  agent_context=base_dict["agent_context"],
575
581
  env_context=base_dict["environment_context"],
576
582
  arguments=tool_args,
@@ -596,9 +602,13 @@ class SecurityMiddleware(Middleware):
596
602
  base_dict = await self._build_baseline_policy_dict(event_id, context, wrapper_args, tool_args)
597
603
  policy_response = create_policy_response(
598
604
  event_id=event_id,
599
- server_name=base_dict["server"]["name"],
600
- server_transport=base_dict["server"]["transport"],
601
- tool_name=base_dict["tool"]["name"] or base_dict["tool"]["method"],
605
+ server=ServerRef(
606
+ name=base_dict["server"]["name"],
607
+ transport=base_dict["server"]["transport"]
608
+ ),
609
+ tool=ToolRef(
610
+ name=base_dict["tool"]["name"] or base_dict["tool"]["method"]
611
+ ),
602
612
  response_content=safe_json_dumps(result),
603
613
  agent_context=base_dict["agent_context"],
604
614
  env_context=base_dict["environment_context"],
@@ -646,7 +656,9 @@ class SecurityMiddleware(Middleware):
646
656
  "current_files": wrapper_args.get('__wrapper_currentFiles')
647
657
  },
648
658
  client=self.wrapper_server_name,
649
- client_version=self.wrapper_server_version
659
+ client_version=self.wrapper_server_version,
660
+ client_os=get_client_os(),
661
+ app_id=self.app_id,
650
662
  )
651
663
  }
652
664