dtlpymcp 0.1.11__tar.gz → 0.1.12__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: dtlpymcp
3
- Version: 0.1.11
3
+ Version: 0.1.12
4
4
  Summary: STDIO MCP proxy server for Dataloop platform.
5
5
  Author-email: Your Name <your.email@example.com>
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -1,3 +1,3 @@
1
1
  from .utils.dtlpy_context import DataloopContext, MCPSource
2
2
 
3
- __version__ = "0.1.11"
3
+ __version__ = "0.1.12"
@@ -1,3 +1,4 @@
1
+ from imp import source_from_cache
1
2
  from mcp.server.fastmcp.utilities.func_metadata import ArgModelBase, FuncMetadata
2
3
  from mcp.client.streamable_http import streamablehttp_client
3
4
  from typing import List, Tuple, Callable, Optional
@@ -20,6 +21,8 @@ logger = logging.getLogger("dtlpymcp")
20
21
  class MCPSource(BaseModel):
21
22
  dpk_name: Optional[str] = None
22
23
  app_url: Optional[str] = None
24
+ dpk_version: Optional[str] = None
25
+ app_trusted: Optional[bool] = None
23
26
  server_url: Optional[str] = None
24
27
  app_jwt: Optional[str] = None
25
28
  tools: Optional[List[Tool]] = []
@@ -60,6 +63,7 @@ class DataloopContext:
60
63
  sources.append(
61
64
  {
62
65
  "dpk_name": app.dpk_name,
66
+ "dpk_version": app.dpk_version,
63
67
  "app_url": next(iter(app.routes.values())),
64
68
  "server_url": None,
65
69
  "app_jwt": None,
@@ -154,6 +158,8 @@ class DataloopContext:
154
158
  app = apps[0]
155
159
  logger.info(f"App: {app.name}")
156
160
  source.app_url = next(iter(app.routes.values()))
161
+ dpk = dl.dpks.get(dpk_name=source.dpk_name, dpk_version=source.dpk_version).to_json()
162
+ source.app_trusted = dpk.get('trusted', False)
157
163
  session = requests.Session()
158
164
  response = session.get(source.app_url, headers=dl.client_api.auth)
159
165
  logger.info(f"App route URL: {response.url}")
@@ -168,14 +174,21 @@ class DataloopContext:
168
174
  def is_expired(app_jwt: str) -> bool:
169
175
  """
170
176
  Check if the APP_JWT is expired.
177
+
178
+ Note: Verification is intentionally skipped - this is only used for
179
+ client-side expiration checking. The server validates the JWT.
171
180
  """
172
181
  try:
173
- decoded = jwt.decode(app_jwt, options={"verify_signature": False})
174
- if decoded.get("exp") < time.time():
175
- return True
176
- return False
177
- except jwt.ExpiredSignatureError:
178
- return True
182
+ decoded = jwt.decode(
183
+ app_jwt,
184
+ options={
185
+ "verify_signature": False,
186
+ "verify_exp": False,
187
+ "verify_aud": False,
188
+ "verify_iss": False,
189
+ },
190
+ )
191
+ return decoded.get("exp", 0) < time.time()
179
192
  except Exception as e:
180
193
  logger.error(f"Error decoding JWT: {e}")
181
194
  return True
@@ -203,9 +216,19 @@ class DataloopContext:
203
216
  def user_info(token: str) -> dict:
204
217
  """
205
218
  Decode a JWT token and return user info.
219
+
220
+ Note: Verification is intentionally skipped - this is only used for
221
+ reading claims client-side. The server validates the JWT.
206
222
  """
207
- decoded = jwt.decode(token, options={"verify_signature": False})
208
- return decoded
223
+ return jwt.decode(
224
+ token,
225
+ options={
226
+ "verify_signature": False,
227
+ "verify_exp": False,
228
+ "verify_aud": False,
229
+ "verify_iss": False,
230
+ },
231
+ )
209
232
 
210
233
  async def list_source_tools(self, source: MCPSource) -> Tuple[str, List[dict], Callable]:
211
234
  """
@@ -214,7 +237,10 @@ class DataloopContext:
214
237
  if source.server_url is None:
215
238
  logger.error("DataloopContext required for DPK servers")
216
239
  raise ValueError("DataloopContext required for DPK servers")
217
- headers = {"Cookie": f"JWT-APP={source.app_jwt}", "x-dl-info": f"{self.token}"}
240
+ if source.app_trusted:
241
+ headers = {"authorization": f"Bearer {self.token}", "x-dl-info": f"{self.token}"}
242
+ else:
243
+ headers = {"Cookie": f"JWT-APP={source.app_jwt}", "x-dl-info": f"{self.token}"}
218
244
  async with streamablehttp_client(source.server_url, headers=headers) as (read, write, _):
219
245
  async with ClientSession(read, write, read_timeout_seconds=timedelta(seconds=60)) as session:
220
246
  await session.initialize()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dtlpymcp
3
- Version: 0.1.11
3
+ Version: 0.1.12
4
4
  Summary: STDIO MCP proxy server for Dataloop platform.
5
5
  Author-email: Your Name <your.email@example.com>
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dtlpymcp"
7
- version = "0.1.11"
7
+ version = "0.1.12"
8
8
  description = "STDIO MCP proxy server for Dataloop platform."
9
9
  authors = [
10
10
  { name = "Your Name", email = "your.email@example.com" }
@@ -1,7 +1,7 @@
1
1
  from dtlpymcp.proxy import main
2
2
  import dtlpy as dl
3
3
  import os
4
- dl.setenv('rc')
4
+ dl.setenv('prod')
5
5
  if dl.token_expired():
6
6
  dl.login()
7
7
  os.environ["DATALOOP_API_KEY"] = dl.token()
File without changes
File without changes
File without changes
File without changes
File without changes