nvidia-nat 1.3.0a20250906__py3-none-any.whl → 1.3.0a20250909__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.
- nat/builder/component_utils.py +1 -1
- nat/cli/commands/info/list_mcp.py +29 -7
- nat/data_models/common.py +1 -1
- nat/data_models/thinking_mixin.py +2 -3
- nat/tool/register.py +0 -2
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/METADATA +3 -1
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/RECORD +12 -18
- nat/tool/mcp/__init__.py +0 -14
- nat/tool/mcp/exceptions.py +0 -142
- nat/tool/mcp/mcp_client_base.py +0 -406
- nat/tool/mcp/mcp_client_impl.py +0 -229
- nat/tool/mcp/mcp_tool.py +0 -133
- nat/utils/exception_handlers/mcp.py +0 -211
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/WHEEL +0 -0
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/entry_points.txt +0 -0
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/licenses/LICENSE.md +0 -0
- {nvidia_nat-1.3.0a20250906.dist-info → nvidia_nat-1.3.0a20250909.dist-info}/top_level.txt +0 -0
nat/builder/component_utils.py
CHANGED
|
@@ -174,7 +174,7 @@ def update_dependency_graph(config: "Config", instance_config: TypedBaseModel,
|
|
|
174
174
|
nx.DiGraph: An dependency graph that has been updated with the provided runtime instance.
|
|
175
175
|
"""
|
|
176
176
|
|
|
177
|
-
for field_name, field_info in instance_config.model_fields.items():
|
|
177
|
+
for field_name, field_info in type(instance_config).model_fields.items():
|
|
178
178
|
|
|
179
179
|
for instance_id, value_node in recursive_componentref_discovery(
|
|
180
180
|
instance_config,
|
|
@@ -22,8 +22,16 @@ from typing import Any
|
|
|
22
22
|
import click
|
|
23
23
|
from pydantic import BaseModel
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
from nat.
|
|
25
|
+
try:
|
|
26
|
+
from nat.plugins.mcp.exception_handler import format_mcp_error
|
|
27
|
+
from nat.plugins.mcp.exceptions import MCPError
|
|
28
|
+
except ImportError:
|
|
29
|
+
# Fallback for when MCP client package is not installed
|
|
30
|
+
MCPError = Exception
|
|
31
|
+
|
|
32
|
+
def format_mcp_error(error, include_traceback=False):
|
|
33
|
+
click.echo(f"Error: {error}", err=True)
|
|
34
|
+
|
|
27
35
|
|
|
28
36
|
# Suppress verbose logs from mcp.client.sse and httpx
|
|
29
37
|
logging.getLogger("mcp.client.sse").setLevel(logging.WARNING)
|
|
@@ -145,9 +153,15 @@ async def list_tools_and_schemas(command, url, tool_name=None, transport='sse',
|
|
|
145
153
|
Raises:
|
|
146
154
|
MCPError: Caught internally and logged, returns empty list instead
|
|
147
155
|
"""
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
156
|
+
try:
|
|
157
|
+
from nat.plugins.mcp.client_base import MCPSSEClient
|
|
158
|
+
from nat.plugins.mcp.client_base import MCPStdioClient
|
|
159
|
+
from nat.plugins.mcp.client_base import MCPStreamableHTTPClient
|
|
160
|
+
except ImportError:
|
|
161
|
+
click.echo(
|
|
162
|
+
"MCP client functionality requires nvidia-nat-mcp package. Install with: uv pip install nvidia-nat-mcp",
|
|
163
|
+
err=True)
|
|
164
|
+
return []
|
|
151
165
|
|
|
152
166
|
if args is None:
|
|
153
167
|
args = []
|
|
@@ -239,8 +253,16 @@ async def list_tools_direct(command, url, tool_name=None, transport='sse', args=
|
|
|
239
253
|
return tools
|
|
240
254
|
except Exception as e:
|
|
241
255
|
# Convert raw exceptions to structured MCPError for consistency
|
|
242
|
-
|
|
243
|
-
|
|
256
|
+
try:
|
|
257
|
+
from nat.plugins.mcp.exception_handler import convert_to_mcp_error
|
|
258
|
+
from nat.plugins.mcp.exception_handler import extract_primary_exception
|
|
259
|
+
except ImportError:
|
|
260
|
+
# Fallback when MCP client package is not installed
|
|
261
|
+
def convert_to_mcp_error(exception, url):
|
|
262
|
+
return Exception(f"Error connecting to {url}: {exception}")
|
|
263
|
+
|
|
264
|
+
def extract_primary_exception(exceptions):
|
|
265
|
+
return exceptions[0] if exceptions else Exception("Unknown error")
|
|
244
266
|
|
|
245
267
|
if isinstance(e, ExceptionGroup): # noqa: F821
|
|
246
268
|
primary_exception = extract_primary_exception(list(e.exceptions))
|
nat/data_models/common.py
CHANGED
|
@@ -160,7 +160,7 @@ class TypedBaseModel(BaseModel):
|
|
|
160
160
|
|
|
161
161
|
@staticmethod
|
|
162
162
|
def discriminator(v: typing.Any) -> str | None:
|
|
163
|
-
# If
|
|
163
|
+
# If it's serialized, then we use the alias
|
|
164
164
|
if isinstance(v, dict):
|
|
165
165
|
return v.get("_type", v.get("type"))
|
|
166
166
|
|
|
@@ -20,9 +20,9 @@ from pydantic import Field
|
|
|
20
20
|
|
|
21
21
|
from nat.data_models.gated_field_mixin import GatedFieldMixin
|
|
22
22
|
|
|
23
|
-
#
|
|
24
|
-
# regex patterns
|
|
23
|
+
# Currently the control logic for thinking is only implemented for Nemotron models
|
|
25
24
|
_NEMOTRON_REGEX = re.compile(r"^nvidia/(llama|nvidia).*nemotron", re.IGNORECASE)
|
|
25
|
+
# The keys are the fields that are used to determine if the model supports thinking
|
|
26
26
|
_MODEL_KEYS = ("model_name", "model", "azure_deployment")
|
|
27
27
|
|
|
28
28
|
|
|
@@ -43,7 +43,6 @@ class ThinkingMixin(
|
|
|
43
43
|
thinking: bool | None = Field(
|
|
44
44
|
default=None,
|
|
45
45
|
description="Whether to enable thinking. Defaults to None when supported on the model.",
|
|
46
|
-
exclude=True,
|
|
47
46
|
)
|
|
48
47
|
|
|
49
48
|
@property
|
nat/tool/register.py
CHANGED
|
@@ -31,8 +31,6 @@ from .github_tools import get_github_file
|
|
|
31
31
|
from .github_tools import get_github_issue
|
|
32
32
|
from .github_tools import get_github_pr
|
|
33
33
|
from .github_tools import update_github_issue
|
|
34
|
-
from .mcp import mcp_client_impl
|
|
35
|
-
from .mcp import mcp_tool
|
|
36
34
|
from .memory_tools import add_memory_tool
|
|
37
35
|
from .memory_tools import delete_memory_tool
|
|
38
36
|
from .memory_tools import get_memory_tool
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nvidia-nat
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.0a20250909
|
|
4
4
|
Summary: NVIDIA NeMo Agent toolkit
|
|
5
5
|
Author: NVIDIA Corporation
|
|
6
6
|
Maintainer: NVIDIA Corporation
|
|
@@ -255,6 +255,8 @@ Provides-Extra: langchain
|
|
|
255
255
|
Requires-Dist: nvidia-nat-langchain; extra == "langchain"
|
|
256
256
|
Provides-Extra: llama-index
|
|
257
257
|
Requires-Dist: nvidia-nat-llama-index; extra == "llama-index"
|
|
258
|
+
Provides-Extra: mcp
|
|
259
|
+
Requires-Dist: nvidia-nat-mcp; extra == "mcp"
|
|
258
260
|
Provides-Extra: mem0ai
|
|
259
261
|
Requires-Dist: nvidia-nat-mem0ai; extra == "mem0ai"
|
|
260
262
|
Provides-Extra: opentelemetry
|
|
@@ -35,7 +35,7 @@ nat/authentication/oauth2/oauth2_auth_code_flow_provider_config.py,sha256=e165ys
|
|
|
35
35
|
nat/authentication/oauth2/register.py,sha256=7rXhf-ilgSS_bUJsd9pOOCotL1FM8dKUt3ke1TllKkQ,1228
|
|
36
36
|
nat/builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
nat/builder/builder.py,sha256=kLqfg69IOtKb4-_iK8Vht0USbmf9dZry5YQgbfDJOzI,10016
|
|
38
|
-
nat/builder/component_utils.py,sha256=
|
|
38
|
+
nat/builder/component_utils.py,sha256=aVVLW468v0nbX1RxS5jBPaCvlnTRiHqwbmHuRyVh-2E,13581
|
|
39
39
|
nat/builder/context.py,sha256=LLyMNwgF5h5Sx1qGdNz3rp4CaJfDn_ytd7T_qv6itb0,11618
|
|
40
40
|
nat/builder/embedder.py,sha256=NPkOEcxt_-wc53QRijCQQDLretRUYHRYaKoYmarmrBk,965
|
|
41
41
|
nat/builder/eval_builder.py,sha256=6Raia6VgQwfFTQGbjnwAL8p4MXQhl_n5UIVuQ-l9_GQ,6575
|
|
@@ -75,7 +75,7 @@ nat/cli/commands/info/__init__.py,sha256=GUJrgGtpvyMUCjUBvR3faAdv-tZzbU9W-izgx9a
|
|
|
75
75
|
nat/cli/commands/info/info.py,sha256=5_s2_MMYn6ZLQpADdZ3aVRg4uvyXvF-4xVJclXxN15U,1317
|
|
76
76
|
nat/cli/commands/info/list_channels.py,sha256=K97TE6wtikgImY-wAbFNi0HHUGtkvIFd2woaG06VkT0,1277
|
|
77
77
|
nat/cli/commands/info/list_components.py,sha256=QlAJVONBA77xW8Lx6Autw5NTAZNy_VrJGr1GL9MfnHM,4532
|
|
78
|
-
nat/cli/commands/info/list_mcp.py,sha256
|
|
78
|
+
nat/cli/commands/info/list_mcp.py,sha256=lPp_6h_QPLblsJIeWROYr6Nx30BD-3JOtIbpxr8n39E,18985
|
|
79
79
|
nat/cli/commands/object_store/__init__.py,sha256=GUJrgGtpvyMUCjUBvR3faAdv-tZzbU9W-izgx9aMEQg,680
|
|
80
80
|
nat/cli/commands/object_store/object_store.py,sha256=_ivB-R30a-66fNy-fUzi58HQ0Ay0gYsGz7T1xXoRa3Y,8576
|
|
81
81
|
nat/cli/commands/registry/__init__.py,sha256=GUJrgGtpvyMUCjUBvR3faAdv-tZzbU9W-izgx9aMEQg,680
|
|
@@ -98,7 +98,7 @@ nat/cli/commands/workflow/templates/workflow.py.j2,sha256=Z4uZPG9rtf1nxF74dF4DqD
|
|
|
98
98
|
nat/data_models/__init__.py,sha256=Xs1JQ16L9btwreh4pdGKwskffAw1YFO48jKrU4ib_7c,685
|
|
99
99
|
nat/data_models/api_server.py,sha256=J9G4aYV2TmIsMNEQtwHZYriyyjynghyHHIa7uwileFM,25689
|
|
100
100
|
nat/data_models/authentication.py,sha256=kF-eTOiKuEsvHFAPy-WQxumeSIhtjny59Wci1uh84qo,7349
|
|
101
|
-
nat/data_models/common.py,sha256=
|
|
101
|
+
nat/data_models/common.py,sha256=nXXfGrjpxebzBUa55mLdmzePLt7VFHvTAc6Znj3yEv0,5875
|
|
102
102
|
nat/data_models/component.py,sha256=YURCaCPnaa6ZPVzSMHHm3iFkqnxGhUHvxUWY8bRKlnI,1816
|
|
103
103
|
nat/data_models/component_ref.py,sha256=mVkaVv55xfTYXUxl28gGWHlKFT73IqUGwFkKaBLVVuw,4518
|
|
104
104
|
nat/data_models/config.py,sha256=VBin3qeWxX8DUkw5lJ6RD7dStR7qPp52XIsy0cJkUP4,17156
|
|
@@ -128,7 +128,7 @@ nat/data_models/streaming.py,sha256=sSqJqLqb70qyw69_4R9QC2RMbRw7UjTLPdo3FYBUGxE,
|
|
|
128
128
|
nat/data_models/swe_bench_model.py,sha256=uZs-hLFuT1B5CiPFwFg1PHinDW8PHne8TBzu7tHFv_k,1718
|
|
129
129
|
nat/data_models/telemetry_exporter.py,sha256=P7kqxIQnFVuvo_UFpH9QSB8fACy_0U2Uzkw_IfWXagE,998
|
|
130
130
|
nat/data_models/temperature_mixin.py,sha256=nUvA_tvjMfILGpBx52RLmJrApJzuswQqlNpS6netkxM,1485
|
|
131
|
-
nat/data_models/thinking_mixin.py,sha256=
|
|
131
|
+
nat/data_models/thinking_mixin.py,sha256=lzAnUk5vyv1nTYG9ho4BD3U2NTVZ50gBysN62iGj2KM,3303
|
|
132
132
|
nat/data_models/top_p_mixin.py,sha256=33cRWjgT0lctucSl8rzioMVeabw3977aGRRWupD9ZaY,1456
|
|
133
133
|
nat/data_models/ttc_strategy.py,sha256=tAkKWcyEBmBOOYtHMtQTgeCbHxFTk5SEkmFunNVnfyE,1114
|
|
134
134
|
nat/embedder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -381,7 +381,7 @@ nat/tool/chat_completion.py,sha256=zB8sqEBEHW0QDcnv0NdqO43ybxe5Q-WKZr9s349UBvA,3
|
|
|
381
381
|
nat/tool/datetime_tools.py,sha256=yZV5lE3FsQuIZE3B36gg38hxfavxgaG04eVFbL0UBTI,3239
|
|
382
382
|
nat/tool/document_search.py,sha256=M6OjKdqUm_HdNn5-rgm5SDOeFGTNuwjYiuMQL43myGc,6741
|
|
383
383
|
nat/tool/nvidia_rag.py,sha256=cEHSc3CZwpd71YcOQngya-Ca_B6ZOb87Dmsoza0VhFY,4163
|
|
384
|
-
nat/tool/register.py,sha256=
|
|
384
|
+
nat/tool/register.py,sha256=7w_yQp4Z1ELX7RqcGME36fL5DlYaCqeD2ZW1bLwSooE,1433
|
|
385
385
|
nat/tool/retriever.py,sha256=FP5JL1vCQNrqaKz4F1up-osjxEPhxPFOyaScrgByc34,3877
|
|
386
386
|
nat/tool/server_tools.py,sha256=rQLipwRv8lAyU-gohky2JoVDxWQTUTSttNWjhu7lcHU,3194
|
|
387
387
|
nat/tool/code_execution/README.md,sha256=sl3YX4As95HX61XqTXOGnUcHBV1lla-OeuTnLI4qgng,4019
|
|
@@ -404,11 +404,6 @@ nat/tool/github_tools/get_github_file.py,sha256=tGMzrE-v16rjDoG-IbOkaS5hXe4SCb-o
|
|
|
404
404
|
nat/tool/github_tools/get_github_issue.py,sha256=fFJFYt3mWR6CK46r6k3-3eVbAKLNh1yHRMmZU0c-4jA,6532
|
|
405
405
|
nat/tool/github_tools/get_github_pr.py,sha256=p4Xu-YA6L1dQ8O0e5LDzphrn5DknjttDhLeudgk7Iys,9716
|
|
406
406
|
nat/tool/github_tools/update_github_issue.py,sha256=fj_OAp5bSmSyj-wPAUvzfCGRBuwPyoK1kJ95Fn8XDg8,4103
|
|
407
|
-
nat/tool/mcp/__init__.py,sha256=GUJrgGtpvyMUCjUBvR3faAdv-tZzbU9W-izgx9aMEQg,680
|
|
408
|
-
nat/tool/mcp/exceptions.py,sha256=EGVOnYlui8xufm8dhJyPL1SUqBLnCGOTvRoeyNcmcWE,5980
|
|
409
|
-
nat/tool/mcp/mcp_client_base.py,sha256=uZ9WCJYhPiYYCaZfC3oa2EwXYJUMDSnm2b5Z6_VSfZE,13412
|
|
410
|
-
nat/tool/mcp/mcp_client_impl.py,sha256=Q2qJAUFWq__opXXUzO6XhhRf9gjwJcEkdHXSiQz4S4I,9668
|
|
411
|
-
nat/tool/mcp/mcp_tool.py,sha256=OIvoLnl2d9PWqE9625jj0CiVEPBVS9LajxFD1VOJlVY,6382
|
|
412
407
|
nat/tool/memory_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
413
408
|
nat/tool/memory_tools/add_memory_tool.py,sha256=DYaYkVlH2myRshJpzmULfzdF0wFoPCAkTBokFVmhfzU,3349
|
|
414
409
|
nat/tool/memory_tools/delete_memory_tool.py,sha256=EWJVgzIzLDqktY5domXph-N2U9FmybdWl4J7KM7uK4g,2532
|
|
@@ -428,7 +423,6 @@ nat/utils/data_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
428
423
|
nat/utils/data_models/schema_validator.py,sha256=pmGr5KuRX5tbVsymG1NxaSnGrKIfzxXEJNd58wIQ9SM,1532
|
|
429
424
|
nat/utils/exception_handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
430
425
|
nat/utils/exception_handlers/automatic_retries.py,sha256=uje36i6tcZ7gX5tMF2mmAB6c2uhkgYjUErs6VL2rCeA,11913
|
|
431
|
-
nat/utils/exception_handlers/mcp.py,sha256=BPfcmSEeW8XVA46vm1kQEOEKTNkZarKW-PMEK-n0QvM,7625
|
|
432
426
|
nat/utils/exception_handlers/schemas.py,sha256=EcNukc4-oASIX2mHAP-hH1up1roWnm99iY18P_v13D0,3800
|
|
433
427
|
nat/utils/io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
434
428
|
nat/utils/io/model_processing.py,sha256=bEbH_tIgZQvPlEJKVV4kye_Y9UU96W4k2mKuckGErHA,936
|
|
@@ -444,10 +438,10 @@ nat/utils/reactive/base/observer_base.py,sha256=6BiQfx26EMumotJ3KoVcdmFBYR_fnAss
|
|
|
444
438
|
nat/utils/reactive/base/subject_base.py,sha256=UQOxlkZTIeeyYmG5qLtDpNf_63Y7p-doEeUA08_R8ME,2521
|
|
445
439
|
nat/utils/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
446
440
|
nat/utils/settings/global_settings.py,sha256=9JaO6pxKT_Pjw6rxJRsRlFCXdVKCl_xUKU2QHZQWWNM,7294
|
|
447
|
-
nvidia_nat-1.3.
|
|
448
|
-
nvidia_nat-1.3.
|
|
449
|
-
nvidia_nat-1.3.
|
|
450
|
-
nvidia_nat-1.3.
|
|
451
|
-
nvidia_nat-1.3.
|
|
452
|
-
nvidia_nat-1.3.
|
|
453
|
-
nvidia_nat-1.3.
|
|
441
|
+
nvidia_nat-1.3.0a20250909.dist-info/licenses/LICENSE-3rd-party.txt,sha256=fOk5jMmCX9YoKWyYzTtfgl-SUy477audFC5hNY4oP7Q,284609
|
|
442
|
+
nvidia_nat-1.3.0a20250909.dist-info/licenses/LICENSE.md,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
443
|
+
nvidia_nat-1.3.0a20250909.dist-info/METADATA,sha256=Usx9uaZgocnncgN6GEsXRUFY5xAU73Y4fkRsMy7e57I,22152
|
|
444
|
+
nvidia_nat-1.3.0a20250909.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
445
|
+
nvidia_nat-1.3.0a20250909.dist-info/entry_points.txt,sha256=FNh4pZVSe_61s29zdks66lmXBPtsnko8KSZ4ffv7WVE,653
|
|
446
|
+
nvidia_nat-1.3.0a20250909.dist-info/top_level.txt,sha256=lgJWLkigiVZuZ_O1nxVnD_ziYBwgpE2OStdaCduMEGc,8
|
|
447
|
+
nvidia_nat-1.3.0a20250909.dist-info/RECORD,,
|
nat/tool/mcp/__init__.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
nat/tool/mcp/exceptions.py
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
from enum import Enum
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class MCPErrorCategory(str, Enum):
|
|
20
|
-
"""Categories of MCP errors for structured handling."""
|
|
21
|
-
CONNECTION = "connection"
|
|
22
|
-
TIMEOUT = "timeout"
|
|
23
|
-
SSL = "ssl"
|
|
24
|
-
AUTHENTICATION = "authentication"
|
|
25
|
-
TOOL_NOT_FOUND = "tool_not_found"
|
|
26
|
-
PROTOCOL = "protocol"
|
|
27
|
-
UNKNOWN = "unknown"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class MCPError(Exception):
|
|
31
|
-
"""Base exception for MCP-related errors."""
|
|
32
|
-
|
|
33
|
-
def __init__(self,
|
|
34
|
-
message: str,
|
|
35
|
-
url: str,
|
|
36
|
-
category: MCPErrorCategory = MCPErrorCategory.UNKNOWN,
|
|
37
|
-
suggestions: list[str] | None = None,
|
|
38
|
-
original_exception: Exception | None = None):
|
|
39
|
-
super().__init__(message)
|
|
40
|
-
self.url = url
|
|
41
|
-
self.category = category
|
|
42
|
-
self.suggestions = suggestions or []
|
|
43
|
-
self.original_exception = original_exception
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class MCPConnectionError(MCPError):
|
|
47
|
-
"""Exception for MCP connection failures."""
|
|
48
|
-
|
|
49
|
-
def __init__(self, url: str, original_exception: Exception | None = None):
|
|
50
|
-
super().__init__(f"Unable to connect to MCP server at {url}",
|
|
51
|
-
url=url,
|
|
52
|
-
category=MCPErrorCategory.CONNECTION,
|
|
53
|
-
suggestions=[
|
|
54
|
-
"Please ensure the MCP server is running and accessible",
|
|
55
|
-
"Check if the URL and port are correct"
|
|
56
|
-
],
|
|
57
|
-
original_exception=original_exception)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class MCPTimeoutError(MCPError):
|
|
61
|
-
"""Exception for MCP timeout errors."""
|
|
62
|
-
|
|
63
|
-
def __init__(self, url: str, original_exception: Exception | None = None):
|
|
64
|
-
super().__init__(f"Connection timed out to MCP server at {url}",
|
|
65
|
-
url=url,
|
|
66
|
-
category=MCPErrorCategory.TIMEOUT,
|
|
67
|
-
suggestions=[
|
|
68
|
-
"The server may be overloaded or network is slow",
|
|
69
|
-
"Try again in a moment or check network connectivity"
|
|
70
|
-
],
|
|
71
|
-
original_exception=original_exception)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class MCPSSLError(MCPError):
|
|
75
|
-
"""Exception for MCP SSL/TLS errors."""
|
|
76
|
-
|
|
77
|
-
def __init__(self, url: str, original_exception: Exception | None = None):
|
|
78
|
-
super().__init__(f"SSL/TLS error connecting to {url}",
|
|
79
|
-
url=url,
|
|
80
|
-
category=MCPErrorCategory.SSL,
|
|
81
|
-
suggestions=[
|
|
82
|
-
"Check if the server requires HTTPS or has valid certificates",
|
|
83
|
-
"Try using HTTP instead of HTTPS if appropriate"
|
|
84
|
-
],
|
|
85
|
-
original_exception=original_exception)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class MCPRequestError(MCPError):
|
|
89
|
-
"""Exception for MCP request errors."""
|
|
90
|
-
|
|
91
|
-
def __init__(self, url: str, original_exception: Exception | None = None):
|
|
92
|
-
message = f"Request failed to MCP server at {url}"
|
|
93
|
-
if original_exception:
|
|
94
|
-
message += f": {original_exception}"
|
|
95
|
-
|
|
96
|
-
super().__init__(message,
|
|
97
|
-
url=url,
|
|
98
|
-
category=MCPErrorCategory.PROTOCOL,
|
|
99
|
-
suggestions=["Check the server URL format and network settings"],
|
|
100
|
-
original_exception=original_exception)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
class MCPToolNotFoundError(MCPError):
|
|
104
|
-
"""Exception for when a specific MCP tool is not found."""
|
|
105
|
-
|
|
106
|
-
def __init__(self, tool_name: str, url: str, original_exception: Exception | None = None):
|
|
107
|
-
super().__init__(f"Tool '{tool_name}' not available at {url}",
|
|
108
|
-
url=url,
|
|
109
|
-
category=MCPErrorCategory.TOOL_NOT_FOUND,
|
|
110
|
-
suggestions=[
|
|
111
|
-
"Use 'nat info mcp --detail' to see available tools",
|
|
112
|
-
"Check that the tool name is spelled correctly"
|
|
113
|
-
],
|
|
114
|
-
original_exception=original_exception)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class MCPAuthenticationError(MCPError):
|
|
118
|
-
"""Exception for MCP authentication failures."""
|
|
119
|
-
|
|
120
|
-
def __init__(self, url: str, original_exception: Exception | None = None):
|
|
121
|
-
super().__init__(f"Authentication failed when connecting to MCP server at {url}",
|
|
122
|
-
url=url,
|
|
123
|
-
category=MCPErrorCategory.AUTHENTICATION,
|
|
124
|
-
suggestions=[
|
|
125
|
-
"Check if the server requires authentication credentials",
|
|
126
|
-
"Verify that your credentials are correct and not expired"
|
|
127
|
-
],
|
|
128
|
-
original_exception=original_exception)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class MCPProtocolError(MCPError):
|
|
132
|
-
"""Exception for MCP protocol-related errors."""
|
|
133
|
-
|
|
134
|
-
def __init__(self, url: str, message: str = "Protocol error", original_exception: Exception | None = None):
|
|
135
|
-
super().__init__(f"{message} (MCP server at {url})",
|
|
136
|
-
url=url,
|
|
137
|
-
category=MCPErrorCategory.PROTOCOL,
|
|
138
|
-
suggestions=[
|
|
139
|
-
"Check that the MCP server is running and accessible at this URL",
|
|
140
|
-
"Verify the server supports the expected MCP protocol version"
|
|
141
|
-
],
|
|
142
|
-
original_exception=original_exception)
|