universal-mcp 0.1.6rc1__py3-none-any.whl → 0.1.7rc2__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.
@@ -1,6 +1,6 @@
1
1
  from e2b_code_interpreter import Sandbox
2
2
  from loguru import logger
3
-
3
+ from typing import Annotated
4
4
  from universal_mcp.applications.application import APIApplication
5
5
  from universal_mcp.integrations import Integration
6
6
 
@@ -25,11 +25,18 @@ class E2BApp(APIApplication):
25
25
  credentials = self.integration.get_credentials()
26
26
  if not credentials:
27
27
  raise ValueError(
28
- f"Failed to retrieve E2B API Key using integration '{self.integration.name}'. "
29
- f"Check store configuration (e.g., ensure the correct environment variable is set)."
28
+ f"Invalid credential format received for E2B API Key via integration '{self.integration.name}'. "
30
29
  )
31
-
32
- self.api_key = credentials
30
+ api_key = (
31
+ credentials.get("api_key")
32
+ or credentials.get("API_KEY")
33
+ or credentials.get("apiKey")
34
+ )
35
+ if not api_key:
36
+ raise ValueError(
37
+ f"Invalid credential format received for E2B API Key via integration '{self.integration.name}'. "
38
+ )
39
+ self.api_key = api_key
33
40
  logger.info("E2B API Key successfully retrieved via integration.")
34
41
 
35
42
  def _format_execution_output(self, logs) -> str:
@@ -50,7 +57,9 @@ class E2BApp(APIApplication):
50
57
  return "Execution finished with no output (stdout/stderr)."
51
58
  return "\n\n".join(output_parts)
52
59
 
53
- def execute_python_code(self, code: str) -> str:
60
+ def execute_python_code(
61
+ self, code: Annotated[str, "The Python code to execute."]
62
+ ) -> str:
54
63
  """
55
64
  Executes Python code within a secure E2B cloud sandbox.
56
65
 
@@ -61,6 +70,9 @@ class E2BApp(APIApplication):
61
70
  A string containing the formatted standard output (stdout) and standard error (stderr)
62
71
  from the execution. If an error occurs during setup or execution, an
63
72
  error message string is returned.
73
+
74
+ Raises:
75
+ NotAuthorizedError: If the API key is not set.
64
76
  """
65
77
  self._set_api_key()
66
78
  with Sandbox(api_key=self.api_key) as sandbox:
@@ -26,9 +26,7 @@ class FirecrawlApp(APIApplication):
26
26
  return
27
27
 
28
28
  if not self.integration:
29
- raise ValueError(
30
- "Integration is None. Cannot retrieve Firecrawl API Key."
31
- )
29
+ raise ValueError("Integration is None. Cannot retrieve Firecrawl API Key.")
32
30
 
33
31
  credentials = self.integration.get_credentials()
34
32
  if not credentials:
@@ -36,9 +34,18 @@ class FirecrawlApp(APIApplication):
36
34
  f"Failed to retrieve Firecrawl API Key using integration '{self.integration.name}'. "
37
35
  f"Check store configuration (e.g., ensure the correct source like environment variable is set)."
38
36
  )
37
+ api_key = (
38
+ credentials.get("api_key")
39
+ or credentials.get("API_KEY")
40
+ or credentials.get("apiKey")
41
+ )
42
+ if not api_key:
43
+ raise ValueError(
44
+ f"Failed to retrieve Firecrawl API Key using integration '{self.integration.name}'. "
45
+ f"Check store configuration (e.g., ensure the correct environment variable is set)."
46
+ )
47
+ self.api_key = api_key
39
48
 
40
- self.api_key = credentials
41
-
42
49
  def _get_client(self) -> FirecrawlApiClient:
43
50
  """Initializes and returns the Firecrawl client after ensuring API key is set."""
44
51
  self._set_api_key()
@@ -128,9 +135,9 @@ class FirecrawlApp(APIApplication):
128
135
  """
129
136
  try:
130
137
  client = self._get_client()
131
- status = client.check_crawl_status(id=job_id)
138
+ status = client.check_crawl_status(id=job_id)
132
139
  return status
133
-
140
+
134
141
  except Exception as e:
135
142
  return f"Error checking crawl status for job ID {job_id}: {type(e).__name__} - {e}"
136
143
 
@@ -148,13 +155,12 @@ class FirecrawlApp(APIApplication):
148
155
  try:
149
156
  client = self._get_client()
150
157
  response = client.cancel_crawl(id=job_id)
151
-
158
+
152
159
  return response
153
160
 
154
- except Exception as e:
161
+ except Exception as e:
155
162
  return f"Error cancelling crawl job ID {job_id}: {type(e).__name__} - {e}"
156
163
 
157
-
158
164
  def start_batch_scrape(
159
165
  self,
160
166
  urls: list[str],
@@ -196,9 +202,9 @@ class FirecrawlApp(APIApplication):
196
202
  """
197
203
  try:
198
204
  client = self._get_client()
199
- status = client.check_batch_scrape_status(id=job_id)
205
+ status = client.check_batch_scrape_status(id=job_id)
200
206
  return status
201
-
207
+
202
208
  except Exception as e:
203
209
  return f"Error checking batch scrape status for job ID {job_id}: {type(e).__name__} - {e}"
204
210
 
@@ -220,7 +226,7 @@ class FirecrawlApp(APIApplication):
220
226
  A dictionary containing the job initiation response on success,
221
227
  or a string containing an error message on failure.
222
228
  """
223
-
229
+
224
230
  try:
225
231
  client = self._get_client()
226
232
  response = client.async_extract(
@@ -246,7 +252,7 @@ class FirecrawlApp(APIApplication):
246
252
  client = self._get_client()
247
253
  status = client.get_extract_status(job_id=job_id)
248
254
  return status
249
-
255
+
250
256
  except Exception as e:
251
257
  return f"Error checking extraction status for job ID {job_id}: {type(e).__name__} - {e}"
252
258
 
@@ -262,4 +268,4 @@ class FirecrawlApp(APIApplication):
262
268
  self.check_batch_scrape_status,
263
269
  self.start_extract,
264
270
  self.check_extract_status,
265
- ]
271
+ ]
@@ -2,6 +2,7 @@ from typing import Any, Literal
2
2
 
3
3
  from universal_mcp.applications.application import APIApplication
4
4
  from universal_mcp.integrations import Integration
5
+ from loguru import logger
5
6
 
6
7
 
7
8
  class PerplexityApp(APIApplication):
@@ -19,25 +20,43 @@ class PerplexityApp(APIApplication):
19
20
 
20
21
  credentials = self.integration.get_credentials()
21
22
  if not credentials:
22
- raise ValueError(
23
+ raise ValueError(
23
24
  f"Failed to retrieve Perplexity API Key using integration '{self.integration.name}'. "
24
- )
25
-
26
- if not isinstance(credentials, str) or not credentials.strip():
27
- raise ValueError(
25
+ )
26
+ api_key = (
27
+ credentials.get("api_key")
28
+ or credentials.get("API_KEY")
29
+ or credentials.get("apiKey")
30
+ )
31
+ if not api_key:
32
+ raise ValueError(
28
33
  f"Invalid credential format received for Perplexity API Key via integration '{self.integration.name}'. "
29
34
  )
30
- self.api_key = credentials
35
+ self.api_key = api_key
31
36
 
32
37
  def _get_headers(self) -> dict[str, str]:
33
38
  self._set_api_key()
39
+ logger.info(f"Perplexity API Key: {self.api_key}")
34
40
  return {
35
41
  "Authorization": f"Bearer {self.api_key}",
36
42
  "Content-Type": "application/json",
37
43
  "Accept": "application/json",
38
44
  }
39
45
 
40
- def chat(self, query: str, model: Literal["r1-1776","sonar","sonar-pro","sonar-reasoning","sonar-reasoning-pro", "sonar-deep-research"] = "sonar" , temperature: float = 1, system_prompt: str = "Be precise and concise.") -> dict[str, Any] | str:
46
+ def chat(
47
+ self,
48
+ query: str,
49
+ model: Literal[
50
+ "r1-1776",
51
+ "sonar",
52
+ "sonar-pro",
53
+ "sonar-reasoning",
54
+ "sonar-reasoning-pro",
55
+ "sonar-deep-research",
56
+ ] = "sonar",
57
+ temperature: float = 1,
58
+ system_prompt: str = "Be precise and concise.",
59
+ ) -> dict[str, Any] | str:
41
60
  """
42
61
  Sends a query to a Perplexity Sonar online model and returns the response.
43
62
 
@@ -69,11 +88,11 @@ class PerplexityApp(APIApplication):
69
88
 
70
89
  data = self._post(endpoint, data=payload)
71
90
  response = data.json()
72
- content = response['choices'][0]['message']['content']
73
- citations = response.get('citations', [])
91
+ content = response["choices"][0]["message"]["content"]
92
+ citations = response.get("citations", [])
74
93
  return {"content": content, "citations": citations}
75
94
 
76
95
  def list_tools(self):
77
96
  return [
78
97
  self.chat,
79
- ]
98
+ ]
@@ -5,13 +5,23 @@ from universal_mcp.integrations import Integration
5
5
  class ResendApp(APIApplication):
6
6
  def __init__(self, integration: Integration) -> None:
7
7
  super().__init__(name="resend", integration=integration)
8
+ self.api_key = None
8
9
 
9
10
  def _get_headers(self):
10
- credentials = self.integration.get_credentials()
11
- if not credentials:
12
- raise ValueError("No credentials found")
11
+ if not self.api_key:
12
+ credentials = self.integration.get_credentials()
13
+ if not credentials:
14
+ raise ValueError("No credentials found")
15
+ api_key = (
16
+ credentials.get("api_key")
17
+ or credentials.get("API_KEY")
18
+ or credentials.get("apiKey")
19
+ )
20
+ if not api_key:
21
+ raise ValueError("No API key found")
22
+ self.api_key = api_key
13
23
  return {
14
- "Authorization": f"Bearer {credentials['api_key']}",
24
+ "Authorization": f"Bearer {self.api_key}",
15
25
  }
16
26
 
17
27
  def send_email(self, to: str, subject: str, content: str) -> str:
@@ -22,8 +22,16 @@ class SerpApp(APIApplication):
22
22
  f"Failed to retrieve SERP API Key using integration '{self.integration.name}'. "
23
23
  f"Check store configuration (e.g., ensure the correct environment variable is set)."
24
24
  )
25
-
26
- self.api_key = credentials
25
+ api_key = (
26
+ credentials.get("api_key")
27
+ or credentials.get("API_KEY")
28
+ or credentials.get("apiKey")
29
+ )
30
+ if not api_key:
31
+ raise ValueError(
32
+ f"Invalid credential format received for SERP API Key via integration '{self.integration.name}'. "
33
+ )
34
+ self.api_key = api_key
27
35
  logger.info("SERP API Key successfully retrieved via integration.")
28
36
 
29
37
  async def search(self, params: dict[str, any] = None) -> str:
@@ -7,13 +7,23 @@ class TavilyApp(APIApplication):
7
7
  name = "tavily"
8
8
  self.base_url = "https://api.tavily.com"
9
9
  super().__init__(name=name, integration=integration)
10
+ self.api_key = None
10
11
 
11
12
  def _get_headers(self):
12
- credentials = self.integration.get_credentials()
13
- if not credentials:
14
- raise ValueError("No credentials found")
13
+ if not self.api_key:
14
+ credentials = self.integration.get_credentials()
15
+ if not credentials:
16
+ raise ValueError("No credentials found")
17
+ api_key = (
18
+ credentials.get("api_key")
19
+ or credentials.get("API_KEY")
20
+ or credentials.get("apiKey")
21
+ )
22
+ if not api_key:
23
+ raise ValueError("No API key found")
24
+ self.api_key = api_key
15
25
  return {
16
- "Authorization": f"Bearer {credentials['api_key']}",
26
+ "Authorization": f"Bearer {self.api_key}",
17
27
  "Content-Type": "application/json",
18
28
  }
19
29
 
universal_mcp/config.py CHANGED
@@ -10,7 +10,7 @@ class StoreConfig(BaseModel):
10
10
 
11
11
  class IntegrationConfig(BaseModel):
12
12
  name: str
13
- type: Literal["api_key", "oauth", "agentr"]
13
+ type: Literal["api_key", "oauth", "agentr", "oauth2"]
14
14
  credentials: dict | None = None
15
15
  store: StoreConfig | None = None
16
16
 
@@ -8,12 +8,13 @@ from universal_mcp.stores.store import Store
8
8
 
9
9
 
10
10
  def sanitize_api_key_name(name: str) -> str:
11
- suffix = "_API_KEY"
11
+ suffix = "_API_KEY"
12
12
  if name.endswith(suffix) or name.endswith(suffix.lower()):
13
13
  return name.upper()
14
14
  else:
15
15
  return f"{name.upper()}{suffix}"
16
-
16
+
17
+
17
18
  class Integration(ABC):
18
19
  """Abstract base class for handling application integrations and authentication.
19
20
 
@@ -91,7 +92,7 @@ class ApiKeyIntegration(Integration):
91
92
  if credentials is None:
92
93
  action = self.authorize()
93
94
  raise NotAuthorizedError(action)
94
- return credentials
95
+ return {"api_key": credentials}
95
96
 
96
97
  def set_credentials(self, credentials: dict):
97
98
  self.store.set(self.name, credentials)
@@ -115,7 +115,11 @@ class LocalServer(Server):
115
115
  tool_name = tool.__name__
116
116
  name = app.name + "_" + tool_name
117
117
  description = tool.__doc__
118
- if app_config.actions is None or tool_name in app_config.actions:
118
+ if (
119
+ app_config.actions is None
120
+ or len(app_config.actions) == 0
121
+ or name in app_config.actions
122
+ ):
119
123
  self.add_tool(tool, name=name, description=description)
120
124
  except Exception as e:
121
125
  logger.error(f"Error loading app {app_config.name}: {e}")
@@ -167,7 +171,11 @@ class AgentRServer(Server):
167
171
  tool_name = tool.__name__
168
172
  name = app.name + "_" + tool_name
169
173
  description = tool.__doc__
170
- if app_config.actions is None or tool_name in app_config.actions:
174
+ if (
175
+ app_config.actions is None
176
+ or len(app_config.actions) == 0
177
+ or name in app_config.actions
178
+ ):
171
179
  self.add_tool(tool, name=name, description=description)
172
180
  except Exception as e:
173
181
  logger.error(f"Error loading app {app_config.name}: {e}")
@@ -61,7 +61,7 @@ def install_claude(api_key: str) -> None:
61
61
  config["mcpServers"] = {}
62
62
  config["mcpServers"]["universal_mcp"] = {
63
63
  "command": get_uvx_path(),
64
- "args": ["universal_mcp@latest", "run"],
64
+ "args": ["universal_mcp[all]@latest", "run"],
65
65
  "env": {"AGENTR_API_KEY": api_key},
66
66
  }
67
67
  with open(config_path, "w") as f:
@@ -90,7 +90,7 @@ def install_cursor(api_key: str) -> None:
90
90
  config["mcpServers"] = {}
91
91
  config["mcpServers"]["universal_mcp"] = {
92
92
  "command": get_uvx_path(),
93
- "args": ["universal_mcp@latest", "run"],
93
+ "args": ["universal_mcp[all]@latest", "run"],
94
94
  "env": {"AGENTR_API_KEY": api_key},
95
95
  }
96
96
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp
3
- Version: 0.1.6rc1
3
+ Version: 0.1.7rc2
4
4
  Summary: Universal MCP acts as a middle ware for your API applications. It can store your credentials, authorize, enable disable apps on the fly and much more.
5
5
  Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -1,15 +1,15 @@
1
1
  universal_mcp/__init__.py,sha256=2gdHpHaDDcsRjZjJ01FLN-1iidN_wbDAolNpxhGoFB4,59
2
2
  universal_mcp/cli.py,sha256=DG-Qxc5vQIdbhAIQuU7bKKJuRGzwyOigjfCKSWBRhBI,5258
3
- universal_mcp/config.py,sha256=9eb3DDg4PBBr1MlGeBrA4bja3Y6howOH-UKpo7JIbs8,828
3
+ universal_mcp/config.py,sha256=sJaPI4q51CDPPG0z32rMJiE7a64eaa9nxbjJgYnaFA4,838
4
4
  universal_mcp/exceptions.py,sha256=Zp2_v_m3L7GDAmD1ZyuwFtY6ngapdhxuIygrvpZAQtM,271
5
5
  universal_mcp/logger.py,sha256=W6A868vyvpdkEQ4Dd0rWdC_7ErSxSQ1z2uxCb77IM8Y,2015
6
6
  universal_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  universal_mcp/applications/__init__.py,sha256=qeWnbdIudyMR7ST4XTc0gpEM9o6TsM1ZnZ92dMAPSBA,754
8
8
  universal_mcp/applications/application.py,sha256=dqp8lgIi2xhY62imwo7C6769URQtNmqd6Ok6PiTr6wc,3399
9
9
  universal_mcp/applications/e2b/README.md,sha256=S4lTp-vEZ8VTCKPXqjUXu5nYlUMAF8lw8CQyBGPgxjs,700
10
- universal_mcp/applications/e2b/app.py,sha256=5piCipi1TC_KuKLFP17do1Y1r28fqApvRsZy76equ9w,2573
10
+ universal_mcp/applications/e2b/app.py,sha256=l7oRmxIuVglA1v9EtYqx_rlvYjUZz7GShmI_VLEQLjI,2979
11
11
  universal_mcp/applications/firecrawl/README.md,sha256=KAWe_TQbrc9eA6bSyde5dapMP1CNvarVItV_YJH3d_0,1430
12
- universal_mcp/applications/firecrawl/app.py,sha256=RSy8zRn4k1A1tIpJNqrUnPI8ctEv1nKWuOuJQcp9mGo,9264
12
+ universal_mcp/applications/firecrawl/app.py,sha256=aPYx3uCsrR6CHz0RERE0ikHMbzwbhKE-SDkF5DVZLiQ,9572
13
13
  universal_mcp/applications/github/README.md,sha256=6ID-__gUJ5ZxzAS_OjzmoUAag1LamSvEB75DHcj3m-g,1294
14
14
  universal_mcp/applications/github/app.py,sha256=L201f5MSx1YVx0nqgduZ5gyHPZdX0UfcEhPmDWiWK6s,13686
15
15
  universal_mcp/applications/google_calendar/app.py,sha256=g_3vrsM2ltwpTySgC5I4SYg47n4UJiYigECO0ax1EHM,19134
@@ -26,23 +26,23 @@ universal_mcp/applications/notion/README.md,sha256=45NmPOmSQv99qBvWdwmnV5vbaYc9_
26
26
  universal_mcp/applications/notion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  universal_mcp/applications/notion/app.py,sha256=XpLnmeXj0Gnf_RYHlbAFnwtSCTYsrNzk6MSMSyDmHGQ,17283
28
28
  universal_mcp/applications/perplexity/README.md,sha256=QGV1iReH5p-Np7vvkZsVHxxDKQ0YaitHEwomNmGEyQs,732
29
- universal_mcp/applications/perplexity/app.py,sha256=J27IDcz9pRC_uW4wABpn-EcI4RvKIzoh_o2hzysM5wA,3187
29
+ universal_mcp/applications/perplexity/app.py,sha256=q3FUnSHwq-_HnIUTYuxVdKmNJ5p0b-Aj3vZ0ZrP7Mg4,3494
30
30
  universal_mcp/applications/reddit/README.md,sha256=YVbJ1RN6NWlB-P6w2LxCk_DuUWl7mwaKZScY-mIMnNc,1271
31
31
  universal_mcp/applications/reddit/app.py,sha256=leU__w5VxX1vMK-kfuy-dvY97Pn8Mn80X2payVshirU,13562
32
32
  universal_mcp/applications/resend/README.md,sha256=k-sb2UwbFvDPEz6qQPLWd2cJj8hDx5f3NW7dz2jAfjI,719
33
- universal_mcp/applications/resend/app.py,sha256=bRo-CRDuk65EUSHOJnbVHWV6TuiUHtedz6FXKRS1ym0,1386
33
+ universal_mcp/applications/resend/app.py,sha256=fl_0U61Rm0fqz1lCxPiuGRkl2x0meafp6kMZbshD7wo,1733
34
34
  universal_mcp/applications/serp/README.md,sha256=hX4VeT2iL_67ZsMhKd60DAujQCh9K3IdHroHIq808RY,691
35
- universal_mcp/applications/serp/app.py,sha256=hPXu1sBiRZRCCzr4q2uvt54F0-B3aZK2Uz4wfKokkZ4,3131
35
+ universal_mcp/applications/serp/app.py,sha256=ug-XkyRrWRRgO_DV_lw4kIzQaGREd5VW1vV4Xv3ptAc,3461
36
36
  universal_mcp/applications/tavily/README.md,sha256=cNg4EwX5wBbkDpPtNBNC3A_GxglfSVhdAJuweSrXN20,721
37
- universal_mcp/applications/tavily/app.py,sha256=FSIRFz7jwm2i9wiDpRWIoQBxHaJ6dl89AjSZY9WP2VE,1776
37
+ universal_mcp/applications/tavily/app.py,sha256=K5TLh6OSQ7w792poupZidzgbWotrIyEsu7YnGzPRX0w,2123
38
38
  universal_mcp/applications/zenquotes/README.md,sha256=wA3hjqjrkrczQaffpwyolSKq6gXmkLgeHx6_EQrYEOY,709
39
39
  universal_mcp/applications/zenquotes/app.py,sha256=nidRGwVORIU25QGCCbjDIv1UNFUj5nWA3qqK4JP0Tdg,621
40
40
  universal_mcp/integrations/README.md,sha256=lTAPXO2nivcBe1q7JT6PRa6v9Ns_ZersQMIdw-nmwEA,996
41
41
  universal_mcp/integrations/__init__.py,sha256=8e11JZyctaR9CmlNkfEZ6HhGDvhlvf9iug2wdjb5pwY,270
42
42
  universal_mcp/integrations/agentr.py,sha256=l0mo79oeDML19udFfoCo9lyhbDAf0X94_lnpOgbTrb0,3331
43
- universal_mcp/integrations/integration.py,sha256=8TYr7N1F6oV8PPOSLo0eA_6nD-vrwIWbuplqwD03uuQ,5819
43
+ universal_mcp/integrations/integration.py,sha256=X8COgD8vg1bKUq4-0ytkMytk1eEaDF1O2JLvu3ewgFk,5828
44
44
  universal_mcp/servers/__init__.py,sha256=dgRW_khG537GeLKC5_U5jhxCuu1L_1YeTujeDg0601E,654
45
- universal_mcp/servers/server.py,sha256=uHArnw_kYIhvlE-Zp5GharGqapGy4jaOlxRQGsOafPM,6431
45
+ universal_mcp/servers/server.py,sha256=9GazpAzNiMgCMg4Vb4VeyoviddEt6pQzi7vLli8vC5A,6677
46
46
  universal_mcp/stores/__init__.py,sha256=Sc4AWtee_qtK5hpEVUAH2XM_6EBhcfikQXWiGXdNfes,560
47
47
  universal_mcp/stores/store.py,sha256=CNOnmKeOCkSU2ZA9t12AIWJcmqZZX_LSyZaV8FQf8Xk,4545
48
48
  universal_mcp/utils/__init__.py,sha256=8wi4PGWu-SrFjNJ8U7fr2iFJ1ktqlDmSKj1xYd7KSDc,41
@@ -50,9 +50,9 @@ universal_mcp/utils/api_generator.py,sha256=-wRBpLVfJQXy1R-8FpDNs6b8_eeekVDuPc_u
50
50
  universal_mcp/utils/bridge.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  universal_mcp/utils/docgen.py,sha256=yK6Ijo8G-wHPU3E1AnFpnXS9vXt2j9FM77w0etTaNOA,12639
52
52
  universal_mcp/utils/dump_app_tools.py,sha256=cLB9SumKsbs-rXJ_02lpMyyNkOmKZ57gekhCjhAlcHg,2009
53
- universal_mcp/utils/installation.py,sha256=uSL_H76fG_7yN4QNxkfp1mEF_00iAPyiXqtdWEMVJe8,3747
53
+ universal_mcp/utils/installation.py,sha256=3vy9ZLjQj1xpSAOyWpOanBr7o5DtffzWB5JAjN0Jjtk,3757
54
54
  universal_mcp/utils/openapi.py,sha256=ud_ZB7_60BcS1Vao7ESKDqo0gry9JN5wzy-CFssrjm8,13140
55
- universal_mcp-0.1.6rc1.dist-info/METADATA,sha256=WofjKtlNIky51G0DqQTvWvO_9bJNoNwE6nJclnHkKbs,10855
56
- universal_mcp-0.1.6rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
- universal_mcp-0.1.6rc1.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
58
- universal_mcp-0.1.6rc1.dist-info/RECORD,,
55
+ universal_mcp-0.1.7rc2.dist-info/METADATA,sha256=p5lVC89uhzjoZVt6ltqWNKdwpLljzROvssQRJAXrVu0,10855
56
+ universal_mcp-0.1.7rc2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
+ universal_mcp-0.1.7rc2.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
58
+ universal_mcp-0.1.7rc2.dist-info/RECORD,,