mcp-server-fetch 2025.1.14__py3-none-any.whl → 2025.1.16__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- mcp_server_fetch/server.py +21 -20
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.16.dist-info}/METADATA +2 -2
- mcp_server_fetch-2025.1.16.dist-info/RECORD +8 -0
- mcp_server_fetch-2025.1.14.dist-info/RECORD +0 -8
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.16.dist-info}/WHEEL +0 -0
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.16.dist-info}/entry_points.txt +0 -0
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.16.dist-info}/licenses/LICENSE +0 -0
mcp_server_fetch/server.py
CHANGED
@@ -7,6 +7,7 @@ from mcp.shared.exceptions import McpError
|
|
7
7
|
from mcp.server import Server
|
8
8
|
from mcp.server.stdio import stdio_server
|
9
9
|
from mcp.types import (
|
10
|
+
ErrorData,
|
10
11
|
GetPromptResult,
|
11
12
|
Prompt,
|
12
13
|
PromptArgument,
|
@@ -79,15 +80,15 @@ async def check_may_autonomously_fetch_url(url: str, user_agent: str) -> None:
|
|
79
80
|
headers={"User-Agent": user_agent},
|
80
81
|
)
|
81
82
|
except HTTPError:
|
82
|
-
raise McpError(
|
83
|
-
INTERNAL_ERROR,
|
84
|
-
f"Failed to fetch robots.txt {robot_txt_url} due to a connection issue",
|
85
|
-
)
|
83
|
+
raise McpError(ErrorData(
|
84
|
+
code=INTERNAL_ERROR,
|
85
|
+
message=f"Failed to fetch robots.txt {robot_txt_url} due to a connection issue",
|
86
|
+
))
|
86
87
|
if response.status_code in (401, 403):
|
87
|
-
raise McpError(
|
88
|
-
INTERNAL_ERROR,
|
89
|
-
f"When fetching robots.txt ({robot_txt_url}), received status {response.status_code} so assuming that autonomous fetching is not allowed, the user can try manually fetching by using the fetch prompt",
|
90
|
-
)
|
88
|
+
raise McpError(ErrorData(
|
89
|
+
code=INTERNAL_ERROR,
|
90
|
+
message=f"When fetching robots.txt ({robot_txt_url}), received status {response.status_code} so assuming that autonomous fetching is not allowed, the user can try manually fetching by using the fetch prompt",
|
91
|
+
))
|
91
92
|
elif 400 <= response.status_code < 500:
|
92
93
|
return
|
93
94
|
robot_txt = response.text
|
@@ -96,15 +97,15 @@ async def check_may_autonomously_fetch_url(url: str, user_agent: str) -> None:
|
|
96
97
|
)
|
97
98
|
robot_parser = Protego.parse(processed_robot_txt)
|
98
99
|
if not robot_parser.can_fetch(str(url), user_agent):
|
99
|
-
raise McpError(
|
100
|
-
INTERNAL_ERROR,
|
101
|
-
f"The sites robots.txt ({robot_txt_url}), specifies that autonomous fetching of this page is not allowed, "
|
100
|
+
raise McpError(ErrorData(
|
101
|
+
code=INTERNAL_ERROR,
|
102
|
+
message=f"The sites robots.txt ({robot_txt_url}), specifies that autonomous fetching of this page is not allowed, "
|
102
103
|
f"<useragent>{user_agent}</useragent>\n"
|
103
104
|
f"<url>{url}</url>"
|
104
105
|
f"<robots>\n{robot_txt}\n</robots>\n"
|
105
106
|
f"The assistant must let the user know that it failed to view the page. The assistant may provide further guidance based on the above information.\n"
|
106
107
|
f"The assistant can tell the user that they can try manually fetching the page by using the fetch prompt within their UI.",
|
107
|
-
)
|
108
|
+
))
|
108
109
|
|
109
110
|
|
110
111
|
async def fetch_url(
|
@@ -124,12 +125,12 @@ async def fetch_url(
|
|
124
125
|
timeout=30,
|
125
126
|
)
|
126
127
|
except HTTPError as e:
|
127
|
-
raise McpError(INTERNAL_ERROR, f"Failed to fetch {url}: {e!r}")
|
128
|
+
raise McpError(ErrorData(code=INTERNAL_ERROR, message=f"Failed to fetch {url}: {e!r}"))
|
128
129
|
if response.status_code >= 400:
|
129
|
-
raise McpError(
|
130
|
-
INTERNAL_ERROR,
|
131
|
-
f"Failed to fetch {url} - status code {response.status_code}",
|
132
|
-
)
|
130
|
+
raise McpError(ErrorData(
|
131
|
+
code=INTERNAL_ERROR,
|
132
|
+
message=f"Failed to fetch {url} - status code {response.status_code}",
|
133
|
+
))
|
133
134
|
|
134
135
|
page_raw = response.text
|
135
136
|
|
@@ -221,11 +222,11 @@ Although originally you did not have internet access, and were advised to refuse
|
|
221
222
|
try:
|
222
223
|
args = Fetch(**arguments)
|
223
224
|
except ValueError as e:
|
224
|
-
raise McpError(INVALID_PARAMS, str(e))
|
225
|
+
raise McpError(ErrorData(code=INVALID_PARAMS, message=str(e)))
|
225
226
|
|
226
227
|
url = str(args.url)
|
227
228
|
if not url:
|
228
|
-
raise McpError(INVALID_PARAMS, "URL is required")
|
229
|
+
raise McpError(ErrorData(code=INVALID_PARAMS, message="URL is required"))
|
229
230
|
|
230
231
|
if not ignore_robots_txt:
|
231
232
|
await check_may_autonomously_fetch_url(url, user_agent_autonomous)
|
@@ -253,7 +254,7 @@ Although originally you did not have internet access, and were advised to refuse
|
|
253
254
|
@server.get_prompt()
|
254
255
|
async def get_prompt(name: str, arguments: dict | None) -> GetPromptResult:
|
255
256
|
if not arguments or "url" not in arguments:
|
256
|
-
raise McpError(INVALID_PARAMS, "URL is required")
|
257
|
+
raise McpError(ErrorData(code=INVALID_PARAMS, message="URL is required"))
|
257
258
|
|
258
259
|
url = arguments["url"]
|
259
260
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-server-fetch
|
3
|
-
Version: 2025.1.
|
3
|
+
Version: 2025.1.16
|
4
4
|
Summary: A Model Context Protocol server providing tools to fetch and convert web content for usage by LLMs
|
5
5
|
Author: Anthropic, PBC.
|
6
6
|
Maintainer-email: Jack Adamson <jadamson@anthropic.com>
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.10
|
15
15
|
Requires-Python: >=3.10
|
16
16
|
Requires-Dist: markdownify>=0.13.1
|
17
|
-
Requires-Dist: mcp>=1.
|
17
|
+
Requires-Dist: mcp>=1.1.3
|
18
18
|
Requires-Dist: protego>=0.3.1
|
19
19
|
Requires-Dist: pydantic>=2.0.0
|
20
20
|
Requires-Dist: readabilipy>=0.2.0
|
@@ -0,0 +1,8 @@
|
|
1
|
+
mcp_server_fetch/__init__.py,sha256=6mqCwMSe8NtUcwXsmZTGjln83bc1vE31CL5yInKZd0s,614
|
2
|
+
mcp_server_fetch/__main__.py,sha256=P5j_W1F3QvOrY7x2YIQ0KlY1Y9eO_vS6rrOo1mL1fvk,57
|
3
|
+
mcp_server_fetch/server.py,sha256=iiB6aXXG30bNdPZlngM5rj67Y4iaNxZ09o8fBgSm3sU,10402
|
4
|
+
mcp_server_fetch-2025.1.16.dist-info/METADATA,sha256=U2TQzcpPnG6WwUsbVGxiZS9IM7CJB-lIgNskciq5idA,4845
|
5
|
+
mcp_server_fetch-2025.1.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
+
mcp_server_fetch-2025.1.16.dist-info/entry_points.txt,sha256=tYA4AQfADMVk6YWCfuPe7TjGGmPmk7gLosHt_ewL48c,59
|
7
|
+
mcp_server_fetch-2025.1.16.dist-info/licenses/LICENSE,sha256=jMfG4zsk7U7o_MzDPszxAlSdBPpMuXN87Ml3Da0QgP8,1059
|
8
|
+
mcp_server_fetch-2025.1.16.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
mcp_server_fetch/__init__.py,sha256=6mqCwMSe8NtUcwXsmZTGjln83bc1vE31CL5yInKZd0s,614
|
2
|
-
mcp_server_fetch/__main__.py,sha256=P5j_W1F3QvOrY7x2YIQ0KlY1Y9eO_vS6rrOo1mL1fvk,57
|
3
|
-
mcp_server_fetch/server.py,sha256=um0KbhDBWcjgKTMxP_mSQvwaPbilH3-hFXMlRSD0ClE,10195
|
4
|
-
mcp_server_fetch-2025.1.14.dist-info/METADATA,sha256=rBTeptl2ITtR2-icAku7mRYlW9Se2S1oxRoBqnFBlNQ,4845
|
5
|
-
mcp_server_fetch-2025.1.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
-
mcp_server_fetch-2025.1.14.dist-info/entry_points.txt,sha256=tYA4AQfADMVk6YWCfuPe7TjGGmPmk7gLosHt_ewL48c,59
|
7
|
-
mcp_server_fetch-2025.1.14.dist-info/licenses/LICENSE,sha256=jMfG4zsk7U7o_MzDPszxAlSdBPpMuXN87Ml3Da0QgP8,1059
|
8
|
-
mcp_server_fetch-2025.1.14.dist-info/RECORD,,
|
File without changes
|
{mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.16.dist-info}/entry_points.txt
RENAMED
File without changes
|
{mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.16.dist-info}/licenses/LICENSE
RENAMED
File without changes
|