kl-mcp-client 1.0.3__tar.gz → 1.0.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kl-mcp-client
3
- Version: 1.0.3
3
+ Version: 1.0.4
4
4
  Summary: MCP Client
5
5
  Author-email: Kyle <hngan.it@gmail.com>
6
6
  License: MIT
@@ -1,8 +1,24 @@
1
+ from functools import wraps
1
2
  from typing import Any, Dict, Optional
2
3
 
3
4
  from .client import MCPClient
4
5
 
5
6
 
7
+ def _ensure_client(func):
8
+ """Decorator kiểm tra self.client != None trước khi gọi tool."""
9
+
10
+ @wraps(func)
11
+ def wrapper(self, *args, **kwargs):
12
+ if self.client is None:
13
+ return {
14
+ "ok": False,
15
+ "error": "MCP client not connected. Call connect mcp server first.",
16
+ }
17
+ return func(self, *args, **kwargs)
18
+
19
+ return wrapper
20
+
21
+
6
22
  class MCPTools:
7
23
  """
8
24
  Wrapper chuẩn cho Google ADK + MCP Server.
@@ -10,38 +26,47 @@ class MCPTools:
10
26
  - Tool screenshot → trả đúng content để ADK Web hiển thị image
11
27
  """
12
28
 
13
- def __init__(self, client: MCPClient):
14
- self.client = client
29
+ def __init__(self):
30
+ self.client = None
15
31
 
16
32
  # ======================================================
17
33
  # SESSION MANAGEMENT
18
34
  # ======================================================
35
+ def connect_mcp(self, mcpUrl: str) -> Dict[str, Any]:
36
+ # sid = self.client.create_session(mcpUrl)
37
+ self.client = MCPClient(base_url=mcpUrl, headers=None, timeout=30, retries=2)
38
+ return {"ok": True, "cdpUrl": "http://127.0.0.1:9222"}
19
39
 
40
+ @_ensure_client
20
41
  def create_session(self, cdpUrl: str) -> Dict[str, Any]:
21
42
  sid = self.client.create_session(cdpUrl)
22
43
  return {"sessionId": sid}
23
44
 
45
+ @_ensure_client
24
46
  def close_session(self, sessionId: str) -> Dict[str, Any]:
25
47
  ok = self.client.close_session(sessionId)
26
48
  return {"ok": bool(ok)}
27
49
 
50
+ @_ensure_client
28
51
  def list_sessions(self) -> Dict[str, Any]:
29
52
  return {"sessions": self.client.list_local_sessions()}
30
53
 
31
54
  # ======================================================
32
55
  # NAVIGATION & DOM
33
56
  # ======================================================
34
-
57
+ @_ensure_client
35
58
  def open_page(self, sessionId: str, url: str) -> Dict[str, Any]:
36
59
  return self.client.call_tool(
37
60
  "openPage", {"sessionId": sessionId, "url": url}
38
61
  ).get("structuredContent", {})
39
62
 
63
+ @_ensure_client
40
64
  def get_html(self, sessionId: str) -> Dict[str, Any]:
41
65
  return self.client.call_tool("getHTML", {"sessionId": sessionId}).get(
42
66
  "structuredContent", {}
43
67
  )
44
68
 
69
+ @_ensure_client
45
70
  def screenshot(self, sessionId: str) -> Dict[str, Any]:
46
71
  """
47
72
  Trả về đúng phần IMAGE content:
@@ -54,16 +79,19 @@ class MCPTools:
54
79
  full = self.client.call_tool("screenshot", {"sessionId": sessionId})
55
80
  return full["content"][0]
56
81
 
82
+ @_ensure_client
57
83
  def click(self, sessionId: str, selector: str) -> Dict[str, Any]:
58
84
  return self.client.call_tool(
59
85
  "click", {"sessionId": sessionId, "selector": selector}
60
86
  ).get("structuredContent", {})
61
87
 
88
+ @_ensure_client
62
89
  def type(self, sessionId: str, selector: str, text: str) -> Dict[str, Any]:
63
90
  return self.client.call_tool(
64
91
  "type", {"sessionId": sessionId, "selector": selector, "text": text}
65
92
  ).get("structuredContent", {})
66
93
 
94
+ @_ensure_client
67
95
  def evaluate(self, sessionId: str, expression: str) -> Dict[str, Any]:
68
96
  return self.client.call_tool(
69
97
  "evaluate", {"sessionId": sessionId, "expression": expression}
@@ -72,27 +100,31 @@ class MCPTools:
72
100
  # ======================================================
73
101
  # ELEMENT UTILITIES
74
102
  # ======================================================
75
-
103
+ @_ensure_client
76
104
  def find_element(self, sessionId: str, selector: str) -> Dict[str, Any]:
77
105
  return self.client.call_tool(
78
106
  "findElement", {"sessionId": sessionId, "selector": selector}
79
107
  ).get("structuredContent", {})
80
108
 
109
+ @_ensure_client
81
110
  def find_all(self, sessionId: str, selector: str) -> Dict[str, Any]:
82
111
  return self.client.call_tool(
83
112
  "findAll", {"sessionId": sessionId, "selector": selector}
84
113
  ).get("structuredContent", {})
85
114
 
115
+ @_ensure_client
86
116
  def get_bounding_box(self, sessionId: str, selector: str) -> Dict[str, Any]:
87
117
  return self.client.call_tool(
88
118
  "getBoundingBox", {"sessionId": sessionId, "selector": selector}
89
119
  ).get("structuredContent", {})
90
120
 
121
+ @_ensure_client
91
122
  def click_bounding_box(self, sessionId: str, selector: str) -> Dict[str, Any]:
92
123
  return self.client.call_tool(
93
124
  "clickBoundingBox", {"sessionId": sessionId, "selector": selector}
94
125
  ).get("structuredContent", {})
95
126
 
127
+ @_ensure_client
96
128
  def upload_file(
97
129
  self, sessionId: str, selector: str, filename: str, base64data: str
98
130
  ) -> Dict[str, Any]:
@@ -116,6 +148,7 @@ class MCPTools:
116
148
  },
117
149
  ).get("structuredContent", {})
118
150
 
151
+ @_ensure_client
119
152
  def wait_for_selector(
120
153
  self, sessionId: str, selector: str, timeoutMs: Optional[int] = None
121
154
  ) -> Dict[str, Any]:
@@ -130,7 +163,7 @@ class MCPTools:
130
163
  # ======================================================
131
164
  # TAB MANAGEMENT
132
165
  # ======================================================
133
-
166
+ @_ensure_client
134
167
  def new_tab(
135
168
  self, sessionId: str, url: Optional[str] = "about:blank"
136
169
  ) -> Dict[str, Any]:
@@ -138,6 +171,7 @@ class MCPTools:
138
171
  "newTab", {"sessionId": sessionId, "url": url}
139
172
  ).get("structuredContent", {})
140
173
 
174
+ @_ensure_client
141
175
  def switch_tab(self, sessionId: str, targetId: str) -> Dict[str, Any]:
142
176
  return self.client.call_tool(
143
177
  "switchTab", {"sessionId": sessionId, "targetId": targetId}
@@ -146,27 +180,31 @@ class MCPTools:
146
180
  # ======================================================
147
181
  # ADVANCED ACTIONS
148
182
  # ======================================================
149
-
183
+ @_ensure_client
150
184
  def click_to_text(self, sessionId: str, text: str) -> dict:
151
185
  return self.client.call_tool(
152
186
  "clickToText", {"sessionId": sessionId, "text": text}
153
187
  ).get("structuredContent", {})
154
188
 
189
+ @_ensure_client
155
190
  def find_element_xpath(self, sessionId: str, xpath: str) -> Dict[str, Any]:
156
191
  return self.client.call_tool(
157
192
  "findElementByXPath", {"sessionId": sessionId, "xpath": xpath}
158
193
  ).get("structuredContent", {})
159
194
 
195
+ @_ensure_client
160
196
  def find_element_by_text(self, sessionId: str, text: str) -> Dict[str, Any]:
161
197
  return self.client.call_tool(
162
198
  "findElementByText", {"sessionId": sessionId, "text": text}
163
199
  ).get("structuredContent", {})
164
200
 
201
+ @_ensure_client
165
202
  def click_by_node_id(self, sessionId: str, nodeId: int) -> Dict[str, Any]:
166
203
  return self.client.call_tool(
167
204
  "clickByNodeId", {"sessionId": sessionId, "nodeId": nodeId}
168
205
  ).get("structuredContent", {})
169
206
 
207
+ @_ensure_client
170
208
  def import_cookies(self, sessionId: str, cookies: dict) -> Dict[str, Any]:
171
209
  return self.client.call_tool(
172
210
  "importCookies", {"sessionId": sessionId, "cookies": cookies}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kl-mcp-client
3
- Version: 1.0.3
3
+ Version: 1.0.4
4
4
  Summary: MCP Client
5
5
  Author-email: Kyle <hngan.it@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kl-mcp-client"
7
- version = "1.0.3"
7
+ version = "1.0.4"
8
8
  description = "MCP Client"
9
9
  authors = [
10
10
  { name="Kyle", email="hngan.it@gmail.com" }
File without changes
File without changes