mcp-server-fetch 2025.1.14__py3-none-any.whl → 2025.1.17__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.
- mcp_server_fetch/server.py +21 -20
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.17.dist-info}/METADATA +2 -2
- mcp_server_fetch-2025.1.17.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.17.dist-info}/WHEEL +0 -0
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.17.dist-info}/entry_points.txt +0 -0
- {mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.17.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.17
|
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.17.dist-info/METADATA,sha256=aPezgZZtmwNmeKV839Vk9XLHwalZbjLzzrGT2rlkB7g,4845
|
5
|
+
mcp_server_fetch-2025.1.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
+
mcp_server_fetch-2025.1.17.dist-info/entry_points.txt,sha256=tYA4AQfADMVk6YWCfuPe7TjGGmPmk7gLosHt_ewL48c,59
|
7
|
+
mcp_server_fetch-2025.1.17.dist-info/licenses/LICENSE,sha256=jMfG4zsk7U7o_MzDPszxAlSdBPpMuXN87Ml3Da0QgP8,1059
|
8
|
+
mcp_server_fetch-2025.1.17.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.17.dist-info}/entry_points.txt
RENAMED
File without changes
|
{mcp_server_fetch-2025.1.14.dist-info → mcp_server_fetch-2025.1.17.dist-info}/licenses/LICENSE
RENAMED
File without changes
|