mcpower-proxy 0.0.66__py3-none-any.whl → 0.0.68__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.

Potentially problematic release.


This version of mcpower-proxy might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcpower-proxy
3
- Version: 0.0.66
3
+ Version: 0.0.68
4
4
  Summary: MCPower Security proxy
5
5
  Author-email: MCPower Security <support@mcpower.tech>
6
6
  License: Apache License
@@ -209,7 +209,7 @@ Keywords: mcp,security,proxy,monitoring,audit,redaction,policy-enforcement
209
209
  Requires-Python: ~=3.11.0
210
210
  Description-Content-Type: text/markdown
211
211
  License-File: LICENSE
212
- Requires-Dist: fastmcp>=2.10.5
212
+ Requires-Dist: fastmcp==2.13.0.1
213
213
  Requires-Dist: httpx>=0.25.0
214
214
  Requires-Dist: mcp>=1.0.0
215
215
  Requires-Dist: watchdog>=3.0.0
@@ -1,8 +1,8 @@
1
1
  main.py,sha256=4BnzO7q9Atpzgr-_NTc1loRnrRY0m5OxeG9biI-C0es,3707
2
- mcpower_proxy-0.0.66.dist-info/licenses/LICENSE,sha256=U6WUzdnBrbmVxBmY75ikW-KtinwYnowZ7yNb5hECrvY,11337
2
+ mcpower_proxy-0.0.68.dist-info/licenses/LICENSE,sha256=U6WUzdnBrbmVxBmY75ikW-KtinwYnowZ7yNb5hECrvY,11337
3
3
  modules/__init__.py,sha256=mJglXQwSRhU-bBv4LXgfu7NfGN9K4BeQWMPApen5rAA,30
4
4
  modules/apis/__init__.py,sha256=Y5WZpKJzHpnRJebk0F80ZRTjR2PpA2LlYLgqI3XlmRo,15
5
- modules/apis/security_policy.py,sha256=AZDHTuOf99WhhzNw9AwC-0KACx1-ZjtQx-Ve3gAKYPM,15000
5
+ modules/apis/security_policy.py,sha256=sgfkdE1X3P3t4d4WMt1caKXDhpjfBst-HVM0u3qcT9I,15100
6
6
  modules/logs/__init__.py,sha256=dpboUQjuO02z8K-liCbm2DYkCa-CB_ZDV9WSSjNm7Fs,15
7
7
  modules/logs/audit_trail.py,sha256=r8aIjaW-jBXXhSwdafzgOn0AvvdTZG8UPnkI0GmbJnA,6199
8
8
  modules/logs/logger.py,sha256=dfYRLnABZB07SBfoYV4DsD8-ZCpzEeoewFCBGHyqo9k,4171
@@ -25,19 +25,19 @@ modules/ui/xdialog/windows_structs.py,sha256=xzG44OGT5hBFnimJgOLXZBhmpQ_9CFxjtz-
25
25
  modules/ui/xdialog/yad_dialogs.py,sha256=EiajZVJg-xDwYymz1fyQwLtT5DzbJR3e8plMEnOgcpo,6933
26
26
  modules/ui/xdialog/zenity_dialogs.py,sha256=wE71I_Ovf0sjhxHVNocbrhhDd8Y8X8loLETp8TMGMPQ,4512
27
27
  modules/utils/__init__.py,sha256=Ptwu1epT_dW6EHjGkzGHAB-MbrrmYAlcPXGGcr4PvwE,20
28
- modules/utils/cli.py,sha256=qYgf7TsWKjwPsCItbDYzNZCih2vfGAbAl2MIem320_Y,1517
28
+ modules/utils/cli.py,sha256=I8_Fz97J09gHL2PlAcgJzHmeNX9aF8XTzJOBjz3wBbk,1414
29
29
  modules/utils/config.py,sha256=YuGrIYfBsOYABWjFoZosObPz-R7Wdul16RnDed_glYI,6654
30
30
  modules/utils/copy.py,sha256=9OJIqWn8PxPZXr3DTt_01jp0YgmPimckab1969WFh0c,1075
31
31
  modules/utils/ids.py,sha256=eYN31WDlfCyRSsdNu9F_hr_duuEpYEUJ5-ZMqo1fiAQ,4701
32
32
  modules/utils/json.py,sha256=8GA2akQsufXIn9HIP4SkFGFShzngexEBzejXi4B-Mfg,4031
33
33
  modules/utils/mcp_configs.py,sha256=DZaujZnF9LlPDJHzyepH7fWSt1GTr-FEmShPCqnZ5aI,1829
34
34
  wrapper/__init__.py,sha256=OJUsuWSoN1JqIHq4bSrzuL7ufcYJcwAmYCrJjLH44LM,22
35
- wrapper/__version__.py,sha256=NMwcKl_v88ECQhojnCXMfvRbXACvhh32_M57YGOUiTE,82
36
- wrapper/middleware.py,sha256=g8jgIA-ciJMshSYflw9HSv_j6i-t1mQvkhc4pjww7Zc,35080
35
+ wrapper/__version__.py,sha256=T9sGujOerGwd7GKxEy9ZnGh5ysLmP0HvBoFYoVUtHQ4,82
36
+ wrapper/middleware.py,sha256=yvtYAssvcdbEPvLbc9FFhmZS0uToGcNyiXJK_cIKYC0,35364
37
37
  wrapper/schema.py,sha256=O-CtKI9eJ4eEnqeUXPCrK7QJAFJrdp_cFbmMyg452Aw,7952
38
38
  wrapper/server.py,sha256=uVtxELALRrQNd-VrPWyLQPiEzxOpG-oCU7bItAeSjYU,2981
39
- mcpower_proxy-0.0.66.dist-info/METADATA,sha256=j3rSpJS3RFqhTP7QmONIhOVN1l7rIGvB8WXGlcoOIds,15667
40
- mcpower_proxy-0.0.66.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
- mcpower_proxy-0.0.66.dist-info/entry_points.txt,sha256=0smL8dxE7ERNz6XEggNaUC3QzKp8mD-v4q5nVEo0MXE,48
42
- mcpower_proxy-0.0.66.dist-info/top_level.txt,sha256=FLbRkTTggoMB-kq14IH4ZUbNGMGtbxtmiWw0QykRlkU,21
43
- mcpower_proxy-0.0.66.dist-info/RECORD,,
39
+ mcpower_proxy-0.0.68.dist-info/METADATA,sha256=Wd48d6uOzsE9KwOaJPPO_dW0TYONi2T8hzo6p2-F7VM,15669
40
+ mcpower_proxy-0.0.68.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ mcpower_proxy-0.0.68.dist-info/entry_points.txt,sha256=0smL8dxE7ERNz6XEggNaUC3QzKp8mD-v4q5nVEo0MXE,48
42
+ mcpower_proxy-0.0.68.dist-info/top_level.txt,sha256=FLbRkTTggoMB-kq14IH4ZUbNGMGtbxtmiWw0QykRlkU,21
43
+ mcpower_proxy-0.0.68.dist-info/RECORD,,
@@ -1,9 +1,9 @@
1
1
  """Security Policy API Client"""
2
2
 
3
3
  import json
4
+ import time
4
5
  import uuid
5
6
  from typing import Dict, Any, Optional, List
6
- import time
7
7
 
8
8
  import httpx
9
9
 
@@ -13,6 +13,7 @@ from modules.logs.logger import MCPLogger
13
13
  from modules.redaction import redact
14
14
  from modules.utils.config import get_api_url, get_user_id
15
15
  from modules.utils.json import safe_json_dumps, to_dict
16
+ from wrapper.__version__ import __version__
16
17
 
17
18
 
18
19
  class SecurityAPIError(Exception):
@@ -166,6 +167,7 @@ class SecurityPolicyClient:
166
167
 
167
168
  headers = {
168
169
  "Content-Type": "application/json",
170
+ "User-Agent": f"MCPower-{__version__}",
169
171
  "X-User-UID": self.user_id,
170
172
  "X-App-UID": self.app_id
171
173
  }
modules/utils/cli.py CHANGED
@@ -7,7 +7,7 @@ import argparse
7
7
  def parse_args():
8
8
  """Parse command line arguments"""
9
9
  parser = argparse.ArgumentParser(
10
- description="MCPower - Transparent 1:1 MCP Wrapper with security enforcement",
10
+ description="Transparent MCP wrapper with security middleware for real-time policy enforcement and monitoring.",
11
11
  formatter_class=argparse.RawDescriptionHelpFormatter,
12
12
  epilog="""
13
13
  Examples:
@@ -24,10 +24,8 @@ Examples:
24
24
  %(prog)s --wrapped-config '{"command": "node", "args": ["server.js"]}' --name MyWrapper
25
25
 
26
26
  Reference Links:
27
- FastMCP Proxy: https://gofastmcp.com/servers/proxy
28
- • FastMCP Middleware: https://gofastmcp.com/servers/middleware
27
+ MCPower Proxy: https://github.com/ai-mcpower/mcpower-proxy
29
28
  • MCP Official: https://modelcontextprotocol.io
30
- • Claude MCP Config: https://docs.anthropic.com/en/docs/claude-code/mcp
31
29
  """
32
30
  )
33
31
 
wrapper/__version__.py CHANGED
@@ -3,4 +3,4 @@
3
3
  Wrapper MCP Server Version
4
4
  """
5
5
 
6
- __version__ = "0.0.66"
6
+ __version__ = "0.0.68"
wrapper/middleware.py CHANGED
@@ -12,6 +12,10 @@ from typing import Any, Dict, List, Optional
12
12
  from fastmcp.exceptions import FastMCPError
13
13
  from fastmcp.server.middleware.middleware import Middleware, MiddlewareContext, CallNext
14
14
  from fastmcp.server.proxy import ProxyClient
15
+
16
+ from mcpower_shared.mcp_types import (create_policy_request, create_policy_response, AgentContext, EnvironmentContext,
17
+ InitRequest,
18
+ ServerRef, ToolRef, UserConfirmation)
15
19
  from modules.apis.security_policy import SecurityPolicyClient
16
20
  from modules.logs.audit_trail import AuditTrailLogger
17
21
  from modules.logs.logger import MCPLogger
@@ -24,10 +28,6 @@ from modules.utils.json import safe_json_dumps, to_dict
24
28
  from modules.utils.mcp_configs import extract_wrapped_server_info
25
29
  from wrapper.schema import merge_input_schema_with_existing
26
30
 
27
- from mcpower_shared.mcp_types import (create_policy_request, create_policy_response, AgentContext, EnvironmentContext,
28
- InitRequest,
29
- ServerRef, ToolRef, UserConfirmation)
30
-
31
31
 
32
32
  class MockContext:
33
33
  """Mock context for internal operations"""
@@ -88,14 +88,18 @@ class SecurityMiddleware(Middleware):
88
88
  async def on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any:
89
89
  self.logger.info(f"on_message: {redact(safe_json_dumps(context))}")
90
90
 
91
- # Check workspace roots and re-initialize app_uid if workspace changed
92
- workspace_roots = await self._extract_workspace_roots(context)
93
- current_workspace_root = workspace_roots[0] if workspace_roots else str(Path.home() / ".mcpower")
94
- if current_workspace_root != self._last_workspace_root:
95
- self.logger.debug(f"Workspace root changed from {self._last_workspace_root} to {current_workspace_root}")
96
- self._last_workspace_root = current_workspace_root
97
- self.app_id = read_app_uid(logger=self.logger, project_folder_path=current_workspace_root)
98
- self.audit_logger.set_app_uid(self.app_id)
91
+ # Skip workspace check for `initialize` calls to avoid premature app_uid changes.
92
+ # The `initialize` request doesn't contain workspace data, so checking it would
93
+ # cause unnecessary audit log flushes before the actual workspace init arrives.
94
+ if context.method != "initialize":
95
+ # Check workspace roots and re-initialize app_uid if workspace changed
96
+ workspace_roots = await self._extract_workspace_roots(context)
97
+ current_workspace_root = workspace_roots[0] if workspace_roots else str(Path.home() / ".mcpower")
98
+ if current_workspace_root != self._last_workspace_root:
99
+ self.logger.debug(f"Workspace root changed from {self._last_workspace_root} to {current_workspace_root}")
100
+ self._last_workspace_root = current_workspace_root
101
+ self.app_id = read_app_uid(logger=self.logger, project_folder_path=current_workspace_root)
102
+ self.audit_logger.set_app_uid(self.app_id)
99
103
 
100
104
  operation_type = "message"
101
105
  call_next_callback = call_next
@@ -116,7 +120,7 @@ class SecurityMiddleware(Middleware):
116
120
  case "tools/list":
117
121
  # Special handling for tools/list - call /init instead of normal inspection
118
122
  return await self._handle_tools_list(context, call_next)
119
- case "resources/list" | "resources/templates/list" | "prompts/list":
123
+ case "initialize" | "resources/list" | "resources/templates/list" | "prompts/list":
120
124
  return await call_next_callback(context)
121
125
 
122
126
  return await self._handle_operation(
@@ -184,12 +188,12 @@ class SecurityMiddleware(Middleware):
184
188
  # FIXME: log_message should be redacted before logging,
185
189
  self.logger.info(f"secure_log_handler: {str(log_message)[:100]}...")
186
190
  # FIXME: log_message should be reviewed with policy before forwarding
187
-
191
+
188
192
  # Handle case where log_message.data is a string instead of dict
189
193
  # The default_log_handler expects data to be a dict with 'msg' and 'extra' keys
190
194
  if hasattr(log_message, 'data') and isinstance(log_message.data, str):
191
195
  log_message = safe_copy(log_message, {'data': {'msg': log_message.data, 'extra': None}})
192
-
196
+
193
197
  return await ProxyClient.default_log_handler(log_message)
194
198
 
195
199
  async def _handle_operation(self, context: MiddlewareContext, call_next, error_class, operation_type: str):
@@ -482,12 +486,12 @@ class SecurityMiddleware(Middleware):
482
486
  file_path_prefix = 'file://'
483
487
  if uri.startswith(file_path_prefix):
484
488
  path = urllib.parse.unquote(uri[len(file_path_prefix):])
485
-
489
+
486
490
  # Windows fix: remove leading slash before drive letter
487
491
  # file:///C:/path becomes /C:/path, should be C:/path
488
492
  if sys.platform == 'win32' and len(path) >= 3 and path[0] == '/' and path[2] == ':':
489
493
  path = path[1:]
490
-
494
+
491
495
  try:
492
496
  resolved_path = str(Path(path).resolve())
493
497
  workspace_roots.append(resolved_path)