langflow-base-nightly 0.5.0.dev15__py3-none-any.whl → 0.5.0.dev17__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.
- langflow/__main__.py +2 -1
- langflow/base/mcp/util.py +97 -12
- langflow/frontend/assets/{SlackIcon-BuGq-sFY.js → SlackIcon-B6OnYflf.js} +1 -1
- langflow/frontend/assets/{Wikipedia-C6mTeFwE.js → Wikipedia-DyYUD0Vv.js} +1 -1
- langflow/frontend/assets/{Wolfram-Cl1pdGB7.js → Wolfram-ClaQ_Whz.js} +1 -1
- langflow/frontend/assets/{index-COjGIAJY.js → index-3X9qaBXP.js} +1 -1
- langflow/frontend/assets/{index-DwteOrWt.js → index-6MqKdunf.js} +1 -1
- langflow/frontend/assets/{index-CE_5Fqkc.js → index-75qdoVDt.js} +1 -1
- langflow/frontend/assets/{index-rA5CdSsY.js → index-97wm7ieO.js} +1 -1
- langflow/frontend/assets/{index-BjJqax0j.js → index-9s8Hrvs5.js} +1 -1
- langflow/frontend/assets/{index-Dr0Evr3R.js → index-B0DYLCP0.js} +1 -1
- langflow/frontend/assets/{index-BR987P2T.js → index-B0t-Hept.js} +1 -1
- langflow/frontend/assets/{index-DJ-FHTsV.js → index-B19i_bSw.js} +1 -1
- langflow/frontend/assets/{index-BzIjYyV3.js → index-B3ETB0RO.js} +1 -1
- langflow/frontend/assets/{index-BzTH-yyX.js → index-B5jDBAVy.js} +1 -1
- langflow/frontend/assets/{index-F5fn0AQz.js → index-B5texAn-.js} +1 -1
- langflow/frontend/assets/{index-CLcXn5NP.js → index-B9wmplp9.js} +1 -1
- langflow/frontend/assets/{index-0N7rEeK6.js → index-BBOgPzsl.js} +1 -1
- langflow/frontend/assets/{index-C9vUZRGz.js → index-BBlPm6lh.js} +1 -1
- langflow/frontend/assets/{index-CewMquJt.js → index-BC8M60Vc.js} +1 -1
- langflow/frontend/assets/{index-5mgrucK2.js → index-BCMwcPhV.js} +1 -1
- langflow/frontend/assets/{index-y7pkRuOy.js → index-BCjvUnkR.js} +1 -1
- langflow/frontend/assets/{index-DgELewjn.js → index-BFH-ud3k.js} +1 -1
- langflow/frontend/assets/{index-CHy7X3Wk.js → index-BLsRxP8O.js} +1 -1
- langflow/frontend/assets/{index-C04LmF5t.js → index-BOWYO1KU.js} +1 -1
- langflow/frontend/assets/{index-DIrWUGNA.js → index-BSI02N_h.js} +1 -1
- langflow/frontend/assets/{index-B3jDfKQC.js → index-BZDRz1qu.js} +1 -1
- langflow/frontend/assets/{index-DyI50yCv.js → index-BdNDTbs-.js} +1 -1
- langflow/frontend/assets/{index-B5fGShZm.js → index-Be4BChy4.js} +1 -1
- langflow/frontend/assets/{index-xsXWdFQP.js → index-BeeL87RV.js} +1 -1
- langflow/frontend/assets/{index-BO7aKIFQ.js → index-BetYK_oB.js} +1 -1
- langflow/frontend/assets/{index-DDGzSYvX.js → index-BihwW9rc.js} +1 -1
- langflow/frontend/assets/{index-Dwip-p69.js → index-BqZ3U8MB.js} +1 -1
- langflow/frontend/assets/{index-CsgBk0rG.js → index-BtSFqHXS.js} +1 -1
- langflow/frontend/assets/{index-8eNqyxH2.js → index-C1Dl8PEX.js} +1 -1
- langflow/frontend/assets/{index-BfbTtNhx.js → index-C35Hy9op.js} +1 -1
- langflow/frontend/assets/{index-Wxjf8dTi.js → index-C3J6YXjG.js} +1 -1
- langflow/frontend/assets/{index-xwBWKncb.js → index-C52CFGSW.js} +1 -1
- langflow/frontend/assets/{index-CyY4Zb7T.js → index-C7Trj9_M.js} +1 -1
- langflow/frontend/assets/{index-CusNYouh.js → index-CAPVeoka.js} +1 -1
- langflow/frontend/assets/{index-q-4Oj5dw.js → index-CBGiY1eb.js} +1 -1
- langflow/frontend/assets/{index-Czze0hOz.js → index-CCIECKWf.js} +1 -1
- langflow/frontend/assets/{index-B4UxEROC.js → index-CC_lrMJo.js} +1 -1
- langflow/frontend/assets/{index-BCdoJWNc.js → index-CF_ebmhM.js} +1 -1
- langflow/frontend/assets/{index-FwjDt9L0.js → index-CHIdJoks.js} +1 -1
- langflow/frontend/assets/{index-n58jFVmL.js → index-CK56_vnt.js} +1 -1
- langflow/frontend/assets/{index-BwpxKa4O.js → index-CKssEuyj.js} +1 -1
- langflow/frontend/assets/{index-Dkr20a-8.js → index-CL_OoTC0.js} +1 -1
- langflow/frontend/assets/{index-CreSy1YL.js → index-CLzWH6BA.js} +1 -1
- langflow/frontend/assets/{index-DkbreZiZ.js → index-CMM4rKwZ.js} +1 -1
- langflow/frontend/assets/{index-DhoGjlQy.js → index-CNP9AW5B.js} +1 -1
- langflow/frontend/assets/{index-C4sZmGLG.js → index-CNspj1lY.js} +1 -1
- langflow/frontend/assets/{index-ikFClZi4.js → index-CS1zJ4IB.js} +1 -1
- langflow/frontend/assets/{index-D23oLkWW.js → index-CYVrsF5c.js} +1 -1
- langflow/frontend/assets/{index-DCd88wbY.js → index-CZIAUlSm.js} +1 -1
- langflow/frontend/assets/{index-jU2KaLOC.js → index-CjbLmEl9.js} +1 -1
- langflow/frontend/assets/{index-TmuU10lC.js → index-CnK7uWZ0.js} +1 -1
- langflow/frontend/assets/{index-BGQ4Eq40.js → index-CsdO6qn5.js} +1 -1
- langflow/frontend/assets/{index-Dn2VQCqb.js → index-Ct1NpiLv.js} +1 -1
- langflow/frontend/assets/{index--2CW5frk.js → index-Cy53U29m.js} +1 -1
- langflow/frontend/assets/{index-BvQ36Iz2.js → index-CyXtI6kM.js} +1 -1
- langflow/frontend/assets/{index-DCxyXwW-.js → index-Cznu7ZXi.js} +1 -1
- langflow/frontend/assets/{index-xi5R3Ztz.js → index-D-RHPEM0.js} +1 -1
- langflow/frontend/assets/{index-DzgWJVeU.js → index-D1yIjmtI.js} +1 -1
- langflow/frontend/assets/{index-k5kov_IX.js → index-D42DjeKJ.js} +1 -1
- langflow/frontend/assets/{index-CM1S4FuW.js → index-D4xYn2YG.js} +1 -1
- langflow/frontend/assets/{index-Dof4LN2v.js → index-D5bSbeSB.js} +1 -1
- langflow/frontend/assets/{index-5dPo5x5t.js → index-D5kNXcW_.js} +1 -1
- langflow/frontend/assets/{index-Dmamz0z9.js → index-DBTfpBLj.js} +1 -1
- langflow/frontend/assets/{index-S0WulKUL.js → index-DEOwNUrS.js} +1 -1
- langflow/frontend/assets/{index-C73vbvpU.js → index-DG4VyIzQ.js} +1 -1
- langflow/frontend/assets/{index-D6ZOAit6.js → index-DGykoQzr.js} +1 -1
- langflow/frontend/assets/{index-QqIf4MIJ.js → index-DI7rFoFJ.js} +1 -1
- langflow/frontend/assets/{index-BV-1aWMO.js → index-DPe39olB.js} +1 -1
- langflow/frontend/assets/{index-Cq2PDwmy.js → index-DQ4cKYH9.js} +1 -1
- langflow/frontend/assets/{index-DYiPmRgD.js → index-D_Jy57MT.js} +1 -1
- langflow/frontend/assets/{index-ydWO1Gui.js → index-DaVQHmqH.js} +1 -1
- langflow/frontend/assets/{index-D5vEZWvq.js → index-DbIRN2la.js} +1 -1
- langflow/frontend/assets/{index-_4nA4mrb.js → index-DcM4A5ga.js} +1 -1
- langflow/frontend/assets/{index-4IouJGCA.js → index-DcZKf2SM.js} +1 -1
- langflow/frontend/assets/{index--zt-fXWv.js → index-DeNNPoI7.js} +4 -4
- langflow/frontend/assets/{index-oh0hcpNl.js → index-DfgnKazq.js} +1 -1
- langflow/frontend/assets/{index-Dli1rL84.js → index-DlmrQVJ5.js} +1 -1
- langflow/frontend/assets/{index-DZ-Tj8xK.js → index-Dmuj9xBn.js} +1 -1
- langflow/frontend/assets/{index-DS7j5zAD.js → index-DnPONvOe.js} +1 -1
- langflow/frontend/assets/{index-CeDSETay.js → index-DncMVZ9U.js} +1 -1
- langflow/frontend/assets/{index-Du2GjDA4.js → index-Do5ZoFyC.js} +1 -1
- langflow/frontend/assets/{index-DIF4m9l7.js → index-DuAWLQtN.js} +1 -1
- langflow/frontend/assets/{index-C-TS0WC2.js → index-DvLrHWnh.js} +1 -1
- langflow/frontend/assets/{index-RLJPjjpM.js → index-DzVrUioR.js} +1 -1
- langflow/frontend/assets/{index-Br2xlOTR.js → index-DzvtRqH5.js} +1 -1
- langflow/frontend/assets/{index-BA8JYsJX.js → index-EUuVOsbW.js} +1 -1
- langflow/frontend/assets/{index-Dr2jGPJH.js → index-Ii9PxM0C.js} +1 -1
- langflow/frontend/assets/{index-Wyp-_NOT.js → index-JQq8V44Q.js} +1 -1
- langflow/frontend/assets/{index-DQRQDV3B.js → index-KLlF6Lvc.js} +1 -1
- langflow/frontend/assets/{index-BuCCNJmV.js → index-KdMFcblk.js} +1 -1
- langflow/frontend/assets/{index-DE6imfD9.js → index-NBoL6TBf.js} +1 -1
- langflow/frontend/assets/{index-CJwwLDoV.js → index-NfhyUZTI.js} +1 -1
- langflow/frontend/assets/{index-BHmpJmyI.js → index-O-EPCcgz.js} +1 -1
- langflow/frontend/assets/{index-CcsiwET2.js → index-P9b6pAOB.js} +1 -1
- langflow/frontend/assets/{index-DNLLlQ4J.js → index-Pk308l34.js} +1 -1
- langflow/frontend/assets/{index-DcUb2cV5.js → index-QECbNvku.js} +1 -1
- langflow/frontend/assets/{index-Dd2GNuvj.js → index-RU_c_P1U.js} +1 -1
- langflow/frontend/assets/{index-Bi_ml8kG.js → index-SfagZ34e.js} +1 -1
- langflow/frontend/assets/{index-DetEMiy0.js → index-SpBMrQ1j.js} +1 -1
- langflow/frontend/assets/{index-CxzVQwQJ.js → index-TR7R-tOm.js} +1 -1
- langflow/frontend/assets/{index-BeG8Pymu.js → index-UIii6lI9.js} +1 -1
- langflow/frontend/assets/{index-BcKPmwO5.js → index-YlKbd5Ib.js} +1 -1
- langflow/frontend/assets/{index-BuSDUHIr.js → index-_YVNMdvG.js} +1 -1
- langflow/frontend/assets/{index-B5zxtSnZ.js → index-_v2WplBD.js} +1 -1
- langflow/frontend/assets/{index-B_cNRBa2.js → index-aEDy0wbU.js} +1 -1
- langflow/frontend/assets/{index-CgNasvrj.js → index-bCBs7TOh.js} +1 -1
- langflow/frontend/assets/{index-COIG_tKu.js → index-fiSh5n-7.js} +1 -1
- langflow/frontend/assets/{index-J52Qzbp2.js → index-jCtHTt5p.js} +1 -1
- langflow/frontend/assets/{index-vYonHXpn.js → index-jdnKw9LX.js} +1 -1
- langflow/frontend/assets/{index-CCLR_wQ0.js → index-kOEkcX9B.js} +1 -1
- langflow/frontend/assets/{index-B0MnkGGh.js → index-m_IPpfQH.js} +1 -1
- langflow/frontend/assets/{index-BKVHa_7r.js → index-mtQATrpg.js} +1 -1
- langflow/frontend/assets/{index-BNQ5zM1M.js → index-n7y1y6mh.js} +1 -1
- langflow/frontend/assets/{index-BrEOz1nl.js → index-sev0raE-.js} +1 -1
- langflow/frontend/assets/{index-DYxzClr0.js → index-ttnKGD-a.js} +1 -1
- langflow/frontend/assets/{index-CMQkU6BV.js → index-yXJiF0LQ.js} +1 -1
- langflow/frontend/assets/{index-DAf-p-ie.js → index-ykKJNMxa.js} +1 -1
- langflow/frontend/assets/{index-BEdvRNt3.js → index-zRx8dV-Q.js} +1 -1
- langflow/frontend/assets/lazyIconImports-BfrjJUMH.js +2 -0
- langflow/frontend/assets/{use-post-add-user-DnN2suY0.js → use-post-add-user-vCVZzR9A.js} +1 -1
- langflow/frontend/index.html +1 -1
- langflow/load/load.py +14 -1
- langflow/logging/logger.py +11 -24
- langflow/services/flow/flow_runner.py +8 -1
- {langflow_base_nightly-0.5.0.dev15.dist-info → langflow_base_nightly-0.5.0.dev17.dist-info}/METADATA +1 -1
- {langflow_base_nightly-0.5.0.dev15.dist-info → langflow_base_nightly-0.5.0.dev17.dist-info}/RECORD +134 -134
- langflow/frontend/assets/lazyIconImports-DFVfn_d3.js +0 -2
- {langflow_base_nightly-0.5.0.dev15.dist-info → langflow_base_nightly-0.5.0.dev17.dist-info}/WHEEL +0 -0
- {langflow_base_nightly-0.5.0.dev15.dist-info → langflow_base_nightly-0.5.0.dev17.dist-info}/entry_points.txt +0 -0
langflow/__main__.py
CHANGED
|
@@ -188,6 +188,7 @@ def run(
|
|
|
188
188
|
show_default=False,
|
|
189
189
|
),
|
|
190
190
|
log_file: Path | None = typer.Option(None, help="Path to the log file.", show_default=False),
|
|
191
|
+
log_rotation: str | None = typer.Option(None, help="Log rotation(Time/Size).", show_default=False),
|
|
191
192
|
cache: str | None = typer.Option( # noqa: ARG001
|
|
192
193
|
None,
|
|
193
194
|
help="Type of cache to use. (InMemoryCache, SQLiteCache)",
|
|
@@ -263,7 +264,7 @@ def run(
|
|
|
263
264
|
else:
|
|
264
265
|
os.environ["LANGFLOW_LOG_LEVEL"] = env_log_level.lower()
|
|
265
266
|
|
|
266
|
-
configure(log_level=log_level, log_file=log_file)
|
|
267
|
+
configure(log_level=log_level, log_file=log_file, log_rotation=log_rotation)
|
|
267
268
|
|
|
268
269
|
# Create progress indicator (show verbose timing if log level is DEBUG)
|
|
269
270
|
verbose = log_level == "debug"
|
langflow/base/mcp/util.py
CHANGED
|
@@ -30,6 +30,86 @@ HTTP_NOT_FOUND = 404
|
|
|
30
30
|
HTTP_BAD_REQUEST = 400
|
|
31
31
|
HTTP_INTERNAL_SERVER_ERROR = 500
|
|
32
32
|
|
|
33
|
+
# RFC 7230 compliant header name pattern: token = 1*tchar
|
|
34
|
+
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
|
|
35
|
+
# "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
|
36
|
+
HEADER_NAME_PATTERN = re.compile(r"^[!#$%&\'*+\-.0-9A-Z^_`a-z|~]+$")
|
|
37
|
+
|
|
38
|
+
# Common allowed headers for MCP connections
|
|
39
|
+
ALLOWED_HEADERS = {
|
|
40
|
+
"authorization",
|
|
41
|
+
"accept",
|
|
42
|
+
"accept-encoding",
|
|
43
|
+
"accept-language",
|
|
44
|
+
"cache-control",
|
|
45
|
+
"content-type",
|
|
46
|
+
"user-agent",
|
|
47
|
+
"x-api-key",
|
|
48
|
+
"x-auth-token",
|
|
49
|
+
"x-custom-header",
|
|
50
|
+
"x-langflow-session",
|
|
51
|
+
"x-mcp-client",
|
|
52
|
+
"x-requested-with",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def validate_headers(headers: dict[str, str]) -> dict[str, str]:
|
|
57
|
+
"""Validate and sanitize HTTP headers according to RFC 7230.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
headers: Dictionary of header name-value pairs
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Dictionary of validated and sanitized headers
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
ValueError: If headers contain invalid names or values
|
|
67
|
+
"""
|
|
68
|
+
if not headers:
|
|
69
|
+
return {}
|
|
70
|
+
|
|
71
|
+
sanitized_headers = {}
|
|
72
|
+
|
|
73
|
+
for name, value in headers.items():
|
|
74
|
+
if not isinstance(name, str) or not isinstance(value, str):
|
|
75
|
+
logger.warning(f"Skipping non-string header: {name}={value}")
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
# Validate header name according to RFC 7230
|
|
79
|
+
if not HEADER_NAME_PATTERN.match(name):
|
|
80
|
+
logger.warning(f"Invalid header name '{name}', skipping")
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
# Normalize header name to lowercase (HTTP headers are case-insensitive)
|
|
84
|
+
normalized_name = name.lower()
|
|
85
|
+
|
|
86
|
+
# Optional: Check against whitelist of allowed headers
|
|
87
|
+
if normalized_name not in ALLOWED_HEADERS:
|
|
88
|
+
# For MCP, we'll be permissive and allow non-standard headers
|
|
89
|
+
# but log a warning for security awareness
|
|
90
|
+
logger.debug(f"Using non-standard header: {normalized_name}")
|
|
91
|
+
|
|
92
|
+
# Check for potential header injection attempts BEFORE sanitizing
|
|
93
|
+
if "\r" in value or "\n" in value:
|
|
94
|
+
logger.warning(f"Potential header injection detected in '{name}', skipping")
|
|
95
|
+
continue
|
|
96
|
+
|
|
97
|
+
# Sanitize header value - remove control characters and newlines
|
|
98
|
+
# RFC 7230: field-value = *( field-content / obs-fold )
|
|
99
|
+
# We'll remove control characters (0x00-0x1F, 0x7F) except tab (0x09) and space (0x20)
|
|
100
|
+
sanitized_value = re.sub(r"[\x00-\x08\x0A-\x1F\x7F]", "", value)
|
|
101
|
+
|
|
102
|
+
# Remove leading/trailing whitespace
|
|
103
|
+
sanitized_value = sanitized_value.strip()
|
|
104
|
+
|
|
105
|
+
if not sanitized_value:
|
|
106
|
+
logger.warning(f"Header '{name}' has empty value after sanitization, skipping")
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
sanitized_headers[normalized_name] = sanitized_value
|
|
110
|
+
|
|
111
|
+
return sanitized_headers
|
|
112
|
+
|
|
33
113
|
|
|
34
114
|
def sanitize_mcp_name(name: str, max_length: int = 46) -> str:
|
|
35
115
|
"""Sanitize a name for MCP usage by removing emojis, diacritics, and special characters.
|
|
@@ -334,12 +414,12 @@ def _process_headers(headers: Any) -> dict:
|
|
|
334
414
|
Args:
|
|
335
415
|
headers: The headers to process, can be dict, str, or list
|
|
336
416
|
Returns:
|
|
337
|
-
Processed dictionary
|
|
417
|
+
Processed and validated dictionary
|
|
338
418
|
"""
|
|
339
419
|
if headers is None:
|
|
340
420
|
return {}
|
|
341
421
|
if isinstance(headers, dict):
|
|
342
|
-
return headers
|
|
422
|
+
return validate_headers(headers)
|
|
343
423
|
if isinstance(headers, list):
|
|
344
424
|
processed_headers = {}
|
|
345
425
|
try:
|
|
@@ -351,7 +431,7 @@ def _process_headers(headers: Any) -> dict:
|
|
|
351
431
|
processed_headers[key] = value
|
|
352
432
|
except (KeyError, TypeError, ValueError):
|
|
353
433
|
return {} # Return empty dictionary instead of None
|
|
354
|
-
return processed_headers
|
|
434
|
+
return validate_headers(processed_headers)
|
|
355
435
|
return {}
|
|
356
436
|
|
|
357
437
|
|
|
@@ -924,7 +1004,7 @@ class MCPSseClient:
|
|
|
924
1004
|
self._component_cache.set("mcp_session_manager", session_manager)
|
|
925
1005
|
return session_manager
|
|
926
1006
|
|
|
927
|
-
async def validate_url(self, url: str | None) -> tuple[bool, str]:
|
|
1007
|
+
async def validate_url(self, url: str | None, headers: dict[str, str] | None = None) -> tuple[bool, str]:
|
|
928
1008
|
"""Validate the SSE URL before attempting connection."""
|
|
929
1009
|
try:
|
|
930
1010
|
parsed = urlparse(url)
|
|
@@ -935,7 +1015,9 @@ class MCPSseClient:
|
|
|
935
1015
|
try:
|
|
936
1016
|
# For SSE endpoints, try a GET request with short timeout
|
|
937
1017
|
# Many SSE servers don't support HEAD requests and return 404
|
|
938
|
-
response = await client.get(
|
|
1018
|
+
response = await client.get(
|
|
1019
|
+
url, timeout=2.0, headers={"Accept": "text/event-stream", **(headers or {})}
|
|
1020
|
+
)
|
|
939
1021
|
|
|
940
1022
|
# For SSE, we expect the server to either:
|
|
941
1023
|
# 1. Start streaming (200)
|
|
@@ -967,14 +1049,16 @@ class MCPSseClient:
|
|
|
967
1049
|
except (httpx.HTTPError, ValueError, OSError) as e:
|
|
968
1050
|
return False, f"URL validation error: {e!s}"
|
|
969
1051
|
|
|
970
|
-
async def pre_check_redirect(self, url: str | None) -> str | None:
|
|
1052
|
+
async def pre_check_redirect(self, url: str | None, headers: dict[str, str] | None = None) -> str | None:
|
|
971
1053
|
"""Check for redirects and return the final URL."""
|
|
972
1054
|
if url is None:
|
|
973
1055
|
return url
|
|
974
1056
|
try:
|
|
975
1057
|
async with httpx.AsyncClient(follow_redirects=False) as client:
|
|
976
1058
|
# Use GET with SSE headers instead of HEAD since many SSE servers don't support HEAD
|
|
977
|
-
response = await client.get(
|
|
1059
|
+
response = await client.get(
|
|
1060
|
+
url, timeout=2.0, headers={"Accept": "text/event-stream", **(headers or {})}
|
|
1061
|
+
)
|
|
978
1062
|
if response.status_code == httpx.codes.TEMPORARY_REDIRECT:
|
|
979
1063
|
return response.headers.get("Location", url)
|
|
980
1064
|
# Don't treat 404 as an error here - let the main connection handle it
|
|
@@ -990,22 +1074,23 @@ class MCPSseClient:
|
|
|
990
1074
|
sse_read_timeout_seconds: int = 30,
|
|
991
1075
|
) -> list[StructuredTool]:
|
|
992
1076
|
"""Connect to MCP server using SSE transport (SDK style)."""
|
|
993
|
-
|
|
994
|
-
|
|
1077
|
+
# Validate and sanitize headers early
|
|
1078
|
+
validated_headers = _process_headers(headers)
|
|
1079
|
+
|
|
995
1080
|
if url is None:
|
|
996
1081
|
msg = "URL is required for SSE mode"
|
|
997
1082
|
raise ValueError(msg)
|
|
998
|
-
is_valid, error_msg = await self.validate_url(url)
|
|
1083
|
+
is_valid, error_msg = await self.validate_url(url, validated_headers)
|
|
999
1084
|
if not is_valid:
|
|
1000
1085
|
msg = f"Invalid SSE URL ({url}): {error_msg}"
|
|
1001
1086
|
raise ValueError(msg)
|
|
1002
1087
|
|
|
1003
|
-
url = await self.pre_check_redirect(url)
|
|
1088
|
+
url = await self.pre_check_redirect(url, validated_headers)
|
|
1004
1089
|
|
|
1005
1090
|
# Store connection parameters for later use in run_tool
|
|
1006
1091
|
self._connection_params = {
|
|
1007
1092
|
"url": url,
|
|
1008
|
-
"headers":
|
|
1093
|
+
"headers": validated_headers,
|
|
1009
1094
|
"timeout_seconds": timeout_seconds,
|
|
1010
1095
|
"sse_read_timeout_seconds": sse_read_timeout_seconds,
|
|
1011
1096
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as a}from"./index
|
|
1
|
+
import{j as a}from"./index-DeNNPoI7.js";const s=l=>a.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 54 54",width:"1em",height:"1em",...l,children:a.jsxs("g",{fill:"none",fillRule:"evenodd",children:[a.jsx("path",{fill:"#36C5F0",d:"M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381 5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386"}),a.jsx("path",{fill:"#2EB67D",d:"M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376 5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381 0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0 5.376 5.387 5.381 5.381 0 0 0 5.376-5.387"}),a.jsx("path",{fill:"#ECB22E",d:"M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381 5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386"}),a.jsx("path",{fill:"#E01E5A",d:"M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0 5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381 5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381 0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387"})]})});export{s as default};
|