docpull 3.0.1__tar.gz → 3.0.2__tar.gz
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.
- {docpull-3.0.1/src/docpull.egg-info → docpull-3.0.2}/PKG-INFO +12 -2
- {docpull-3.0.1 → docpull-3.0.2}/README.md +11 -1
- {docpull-3.0.1 → docpull-3.0.2}/pyproject.toml +1 -1
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/__init__.py +1 -1
- {docpull-3.0.1 → docpull-3.0.2/src/docpull.egg-info}/PKG-INFO +12 -2
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull.egg-info/SOURCES.txt +1 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_cli.py +7 -0
- docpull-3.0.2/tests/test_mcp_server.py +51 -0
- {docpull-3.0.1 → docpull-3.0.2}/LICENSE +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/setup.cfg +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/__main__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/cache/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/cache/manager.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/cache/streaming_dedup.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/cli.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/concurrency/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/concurrency/manager.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/chunking.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/extractor.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/markdown.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/protocols.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/special_cases.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/conversion/trafilatura_extractor.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/core/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/core/fetcher.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/composite.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/crawler.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/filters.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/link_extractors/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/link_extractors/enhanced.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/link_extractors/protocols.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/link_extractors/static.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/protocols.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/discovery/sitemap.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/doctor.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/http/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/http/client.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/http/protocols.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/http/rate_limiter.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/logging_config.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/mcp/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/mcp/server.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/mcp/sources.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/mcp/tools.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/metadata_extractor.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/models/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/models/config.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/models/events.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/models/profiles.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/base.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/chunk.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/convert.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/dedup.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/fetch.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/metadata.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/save.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/save_json.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/save_ndjson.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/save_sqlite.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/pipeline/steps/validate.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/py.typed +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/security/__init__.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/security/robots.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/security/url_validator.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull/time_utils.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull.egg-info/dependency_links.txt +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull.egg-info/entry_points.txt +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull.egg-info/requires.txt +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/src/docpull.egg-info/top_level.txt +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_cache_conditional_get.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_chunking.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_conversion.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_convert_step_new.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_discovery.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_integration.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_link_extractors.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_mcp_tools.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_naming.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_pipeline.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_real_site_regressions.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_save_ndjson.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_security_hardening.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_special_cases.py +0 -0
- {docpull-3.0.1 → docpull-3.0.2}/tests/test_time_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docpull
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: Pull documentation from the web and convert to clean markdown
|
|
5
5
|
Author-email: Zachary Roth <support@raintree.technology>
|
|
6
6
|
Maintainer-email: Raintree Technology <support@raintree.technology>
|
|
@@ -228,12 +228,19 @@ pip install 'docpull[mcp]'
|
|
|
228
228
|
docpull mcp # starts the stdio server
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
Claude Code:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
claude mcp add --transport stdio docpull -- docpull mcp
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Cursor (`.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` globally):
|
|
232
238
|
|
|
233
239
|
```json
|
|
234
240
|
{
|
|
235
241
|
"mcpServers": {
|
|
236
242
|
"docpull": {
|
|
243
|
+
"type": "stdio",
|
|
237
244
|
"command": "docpull",
|
|
238
245
|
"args": ["mcp"]
|
|
239
246
|
}
|
|
@@ -241,6 +248,9 @@ Add to Claude Desktop or Claude Code manually:
|
|
|
241
248
|
}
|
|
242
249
|
```
|
|
243
250
|
|
|
251
|
+
Claude Desktop uses the same `mcpServers` shape in
|
|
252
|
+
`claude_desktop_config.json`.
|
|
253
|
+
|
|
244
254
|
Or, if you use Claude Code, install the plugin instead — it bundles the MCP
|
|
245
255
|
server, five slash commands (`/docs-add`, `/docs-search`, `/docs-list`,
|
|
246
256
|
`/docs-refresh`, `/docs-remove`), and a meta-skill that teaches Claude
|
|
@@ -140,12 +140,19 @@ pip install 'docpull[mcp]'
|
|
|
140
140
|
docpull mcp # starts the stdio server
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
Claude Code:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
claude mcp add --transport stdio docpull -- docpull mcp
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Cursor (`.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` globally):
|
|
144
150
|
|
|
145
151
|
```json
|
|
146
152
|
{
|
|
147
153
|
"mcpServers": {
|
|
148
154
|
"docpull": {
|
|
155
|
+
"type": "stdio",
|
|
149
156
|
"command": "docpull",
|
|
150
157
|
"args": ["mcp"]
|
|
151
158
|
}
|
|
@@ -153,6 +160,9 @@ Add to Claude Desktop or Claude Code manually:
|
|
|
153
160
|
}
|
|
154
161
|
```
|
|
155
162
|
|
|
163
|
+
Claude Desktop uses the same `mcpServers` shape in
|
|
164
|
+
`claude_desktop_config.json`.
|
|
165
|
+
|
|
156
166
|
Or, if you use Claude Code, install the plugin instead — it bundles the MCP
|
|
157
167
|
server, five slash commands (`/docs-add`, `/docs-search`, `/docs-list`,
|
|
158
168
|
`/docs-refresh`, `/docs-remove`), and a meta-skill that teaches Claude
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "docpull"
|
|
7
|
-
version = "3.0.
|
|
7
|
+
version = "3.0.2"
|
|
8
8
|
dynamic = []
|
|
9
9
|
description = "Pull documentation from the web and convert to clean markdown"
|
|
10
10
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docpull
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: Pull documentation from the web and convert to clean markdown
|
|
5
5
|
Author-email: Zachary Roth <support@raintree.technology>
|
|
6
6
|
Maintainer-email: Raintree Technology <support@raintree.technology>
|
|
@@ -228,12 +228,19 @@ pip install 'docpull[mcp]'
|
|
|
228
228
|
docpull mcp # starts the stdio server
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
Claude Code:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
claude mcp add --transport stdio docpull -- docpull mcp
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Cursor (`.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` globally):
|
|
232
238
|
|
|
233
239
|
```json
|
|
234
240
|
{
|
|
235
241
|
"mcpServers": {
|
|
236
242
|
"docpull": {
|
|
243
|
+
"type": "stdio",
|
|
237
244
|
"command": "docpull",
|
|
238
245
|
"args": ["mcp"]
|
|
239
246
|
}
|
|
@@ -241,6 +248,9 @@ Add to Claude Desktop or Claude Code manually:
|
|
|
241
248
|
}
|
|
242
249
|
```
|
|
243
250
|
|
|
251
|
+
Claude Desktop uses the same `mcpServers` shape in
|
|
252
|
+
`claude_desktop_config.json`.
|
|
253
|
+
|
|
244
254
|
Or, if you use Claude Code, install the plugin instead — it bundles the MCP
|
|
245
255
|
server, five slash commands (`/docs-add`, `/docs-search`, `/docs-list`,
|
|
246
256
|
`/docs-refresh`, `/docs-remove`), and a meta-skill that teaches Claude
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
"""CLI regression tests."""
|
|
2
2
|
|
|
3
|
+
from importlib.metadata import version
|
|
4
|
+
|
|
3
5
|
import pytest
|
|
4
6
|
|
|
7
|
+
import docpull
|
|
5
8
|
from docpull.cli import create_parser
|
|
6
9
|
|
|
7
10
|
|
|
11
|
+
def test_runtime_version_matches_package_metadata():
|
|
12
|
+
assert docpull.__version__ == version("docpull")
|
|
13
|
+
|
|
14
|
+
|
|
8
15
|
def test_parser_rejects_removed_js_flag():
|
|
9
16
|
"""Ensure the removed JavaScript flag stays unavailable."""
|
|
10
17
|
parser = create_parser()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""End-to-end tests for the stdio MCP server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
pytest.importorskip("mcp")
|
|
11
|
+
pytest.importorskip("mcp.client.stdio")
|
|
12
|
+
|
|
13
|
+
from mcp.client.stdio import stdio_client
|
|
14
|
+
|
|
15
|
+
from mcp import ClientSession, StdioServerParameters
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.mark.asyncio
|
|
19
|
+
async def test_stdio_server_lists_and_calls_tools(tmp_path):
|
|
20
|
+
env = os.environ.copy()
|
|
21
|
+
env["XDG_CONFIG_HOME"] = str(tmp_path / "config")
|
|
22
|
+
env["XDG_DATA_HOME"] = str(tmp_path / "data")
|
|
23
|
+
|
|
24
|
+
server = StdioServerParameters(
|
|
25
|
+
command=sys.executable,
|
|
26
|
+
args=["-m", "docpull", "mcp"],
|
|
27
|
+
env=env,
|
|
28
|
+
)
|
|
29
|
+
async with stdio_client(server) as (read, write), ClientSession(read, write) as session:
|
|
30
|
+
await session.initialize()
|
|
31
|
+
|
|
32
|
+
tools = await session.list_tools()
|
|
33
|
+
names = {tool.name for tool in tools.tools}
|
|
34
|
+
assert names == {
|
|
35
|
+
"fetch_url",
|
|
36
|
+
"ensure_docs",
|
|
37
|
+
"list_sources",
|
|
38
|
+
"list_indexed",
|
|
39
|
+
"grep_docs",
|
|
40
|
+
"read_doc",
|
|
41
|
+
"add_source",
|
|
42
|
+
"remove_source",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
result = await session.call_tool("list_sources", {})
|
|
46
|
+
assert result.isError is False
|
|
47
|
+
assert result.structuredContent is not None
|
|
48
|
+
assert any(source["name"] == "react" for source in result.structuredContent["sources"])
|
|
49
|
+
|
|
50
|
+
rejected = await session.call_tool("fetch_url", {"url": "https://localhost/admin"})
|
|
51
|
+
assert rejected.isError is True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|