docslicer 0.2.1__tar.gz → 0.2.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.
- {docslicer-0.2.1/src/docslicer.egg-info → docslicer-0.2.2}/PKG-INFO +111 -7
- {docslicer-0.2.1 → docslicer-0.2.2}/README.md +110 -6
- {docslicer-0.2.1 → docslicer-0.2.2}/pyproject.toml +1 -1
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/__init__.py +1 -1
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_orchestrator.py +1 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_result.py +2 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/cli.py +7 -2
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/mcp/_store.py +9 -2
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/mcp/server.py +208 -84
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/shared_orchestrator.py +7 -1
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_08_chunk_builder.py +11 -7
- {docslicer-0.2.1 → docslicer-0.2.2/src/docslicer.egg-info}/PKG-INFO +111 -7
- {docslicer-0.2.1 → docslicer-0.2.2}/LICENSE +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/LICENSE-COMMERCIAL.md +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/setup.cfg +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_config.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/color_utils.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/cpu.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/df_aggregation/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/df_aggregation/registry_aggregator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/df_aggregation/text_merge.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/df_export/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/df_export/export_debug.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/df_export/reorder_columns.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/io/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/io/yaml_compilers/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/io/yaml_compilers/exhibit_patterns.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/io/yaml_compilers/hierarchy_type_patterns.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/io/yaml_compilers/page_label_patterns.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/io/yaml_loader.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/gutter_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/layouts.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/line_merger.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/line_number_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/reading_order.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/layout/shape_processor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/oxm_package.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/parallel.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/password.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/safe_call.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/table/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/table/table_header.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/table/table_normalize.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/table/table_schema.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/text_utils.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/_utils/timing.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/config/common_author_names.csv +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/config/exhibit_patterns.yaml +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/config/hierarchy_type_patterns.yaml +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/config/page_label_patterns.yaml +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/docx_orchestrator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/native_metadata.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_01_package_reader.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_02_run_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_03_chart_point_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_04_table_cell_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_05_paragraph_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_06_line_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/docx/step_07_style_prefiller.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/extract_boxes.js +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/html_orchestrator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/native_metadata.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_01_box_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_01_static_box_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_02_box_cleaner.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_03_page_label_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_04_line_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_05_table_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/html/step_06_style_prefiller.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/mcp/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/consolidate.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/generator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/ocr_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/page_analysis.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/schema.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/metadata/text_fallback.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/_availability.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/ocr_orchestrator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/step_01_word_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/step_02_word_colorizer.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/step_03_shape_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/step_04_text_cleaner.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/ocr/step_05_font_size_estimator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/coordinates.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/form_fields.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/form_label_link.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/line_classification.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/page_rotation.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/script_thresholds.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/struct_context.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/_utils/struct_tree.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/native_metadata.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/pdf_orchestrator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_01_word_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_02_image_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_03_shape_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_04_link_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_05_struct_group.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_06_style_prefiller.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_07_stream_group.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_08_reading_order.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_09_word_relationships.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_10_cell_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_11_page_label_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_12_cell_grouper.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_13_line_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pdf/step_14_table_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/native_metadata.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/pptx_orchestrator.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_01_package_reader.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_02_run_extractor.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_03_chart_point_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_04_table_cell_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_05_paragraph_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_06_reading_order.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_07_line_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/pptx/step_08_style_prefiller.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/config.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/cookie_consent.js +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/dispatcher.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/fetchers/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/fetchers/http_fetcher.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/fetchers/sec_fetcher.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/models.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/scraping/stealth_init.js +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/__init__.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_01_navigation_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_02_toc_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_03_exhibit_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_04_section_classifier.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_05_heading_detector.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_06_hierarchy_builder.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer/shared/step_07_block_merger.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer.egg-info/SOURCES.txt +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer.egg-info/dependency_links.txt +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer.egg-info/entry_points.txt +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer.egg-info/requires.txt +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/src/docslicer.egg-info/top_level.txt +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_api.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_charts.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_document_parser.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_errors.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_exports.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_loose_box_reconstruction.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_packaging.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_smoke.py +0 -0
- {docslicer-0.2.1 → docslicer-0.2.2}/tests/test_table_cell_newlines.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docslicer
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Deterministic hierarchical document parser and chunker
|
|
5
5
|
Author-email: "Market Framer Inc." <jelle@docslicer.ai>
|
|
6
6
|
License-Expression: AGPL-3.0-only
|
|
@@ -60,7 +60,9 @@ Dynamic: license-file
|
|
|
60
60
|
|
|
61
61
|
# DocSlicer
|
|
62
62
|
|
|
63
|
-
[](https://pypi.org/project/docslicer/) [](LICENSE) [](LICENSE-COMMERCIAL.md)
|
|
63
|
+
[](https://pypi.org/project/docslicer/) [](https://pypi.org/project/docslicer/) [](LICENSE) [](LICENSE-COMMERCIAL.md)
|
|
64
|
+
|
|
65
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=docslicer&config=%7B%22name%22%3A%22docslicer%22%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22docslicer%5Bmcp%5D%22%2C%22docslicer-mcp%22%5D%7D) [](https://cursor.com/install-mcp?name=docslicer&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJkb2NzbGljZXJbbWNwXSIsImRvY3NsaWNlci1tY3AiXX0%3D) [](https://github.com/DocSlicer/DocSlicer/releases/latest)
|
|
64
66
|
|
|
65
67
|
Lightning-fast (31 pages/sec), deterministic document parser and chunker for business documents. No LLM calls or heavy ML models.
|
|
66
68
|
|
|
@@ -68,9 +70,12 @@ DocSlicer turns PDFs, Word documents, HTML pages, and PowerPoint files into clea
|
|
|
68
70
|
|
|
69
71
|
Top score on [BizDocBench](https://github.com/DocSlicer/BizDocBench) (0.88 overall vs 0.70 for the next-best tool). 0.80 table accuracy, 0.98 content faithfulness, 0.85 heading recognition and hierarchy preservation, and 0.76 RAG retrieval performance.
|
|
70
72
|
|
|
71
|
-
**
|
|
72
|
-
|
|
73
|
-
-
|
|
73
|
+
**Two ways to use it:**
|
|
74
|
+
|
|
75
|
+
- **As a Python library — classic RAG.** The layout-aware chunker gives you clean, non-overlapping chunks, each carrying its full heading breadcrumb, ready to embed. [Jump to the API ↓](#parsing)
|
|
76
|
+
- **As an MCP server — vectorless RAG.** For when you want an answer out of a document right now. Claude, Cursor, or VS Code pulls the outline, picks the section it needs, and reads only that — no embedding, and no 200-page document in the context window. [Jump to setup ↓](#mcp-server)
|
|
77
|
+
|
|
78
|
+
### Quick start
|
|
74
79
|
|
|
75
80
|
```python
|
|
76
81
|
import docslicer
|
|
@@ -562,19 +567,49 @@ docslicer-mcp # stdio — what desktop clients launch
|
|
|
562
567
|
docslicer-mcp --transport http --port 8000
|
|
563
568
|
```
|
|
564
569
|
|
|
565
|
-
|
|
570
|
+
### Claude Desktop / Cowork — one-click install
|
|
571
|
+
|
|
572
|
+
Download `docslicer-X.Y.Z.mcpb` from the
|
|
573
|
+
[latest release](https://github.com/DocSlicer/DocSlicer/releases/latest) and
|
|
574
|
+
double-click it, or drag it onto the Claude Desktop window. You pick the folder
|
|
575
|
+
DocSlicer is allowed to read and write during install; no config file, and no
|
|
576
|
+
Python of your own — `uv` provisions the interpreter.
|
|
577
|
+
|
|
578
|
+
### Other clients
|
|
579
|
+
|
|
580
|
+
Every client below launches the server over stdio. `uvx` needs nothing
|
|
581
|
+
installed ahead of time:
|
|
566
582
|
|
|
567
583
|
```jsonc
|
|
568
584
|
{
|
|
569
585
|
"mcpServers": {
|
|
570
586
|
"docslicer": {
|
|
571
|
-
"command": "
|
|
587
|
+
"command": "uvx",
|
|
588
|
+
"args": ["--from", "docslicer[mcp]", "docslicer-mcp"],
|
|
572
589
|
"env": { "DOCSLICER_MCP_ROOT": "/Users/you/Documents" }
|
|
573
590
|
}
|
|
574
591
|
}
|
|
575
592
|
}
|
|
576
593
|
```
|
|
577
594
|
|
|
595
|
+
If you'd rather install it once and skip the resolve on every launch, use
|
|
596
|
+
`pip install 'docslicer[mcp]'` (or `uv tool install`) and set
|
|
597
|
+
`"command": "docslicer-mcp"` with no `args`.
|
|
598
|
+
|
|
599
|
+
| Client | Where the config goes |
|
|
600
|
+
| --- | --- |
|
|
601
|
+
| Claude Code | `claude mcp add docslicer -- uvx --from 'docslicer[mcp]' docslicer-mcp` |
|
|
602
|
+
| Cursor | `~/.cursor/mcp.json`, or `.cursor/mcp.json` per project |
|
|
603
|
+
| VS Code | `.vscode/mcp.json` (use a `servers` key instead of `mcpServers`) |
|
|
604
|
+
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
|
|
605
|
+
| Zed | `settings.json`, under `context_servers` |
|
|
606
|
+
|
|
607
|
+
> **On GUI-launched clients, prefer the `.mcpb`.** An app started from the dock
|
|
608
|
+
> does not inherit your shell `PATH` — on macOS that excludes
|
|
609
|
+
> `/opt/homebrew/bin` — so a bare `uvx` or `docslicer-mcp` can work in a
|
|
610
|
+
> terminal and fail when the client spawns it. Use an absolute path
|
|
611
|
+
> (`which uvx`) if you hit this. The extension sidesteps it entirely.
|
|
612
|
+
|
|
578
613
|
### How it works
|
|
579
614
|
|
|
580
615
|
A parsed document is far larger than a model's context window, so the server
|
|
@@ -641,6 +676,22 @@ can write anywhere the server process can.
|
|
|
641
676
|
|
|
642
677
|
---
|
|
643
678
|
|
|
679
|
+
## Command line
|
|
680
|
+
|
|
681
|
+
`docslicer` parses one document to JSON on stdout — for a quick look at a file,
|
|
682
|
+
or to pipe into `jq`.
|
|
683
|
+
|
|
684
|
+
```bash
|
|
685
|
+
docslicer report.pdf # chunks as JSON
|
|
686
|
+
docslicer report.pdf -o chunks.json # write to a file
|
|
687
|
+
docslicer report.pdf --no-chunking # blocks instead of chunks
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
It takes the same parsing and chunking options as `parse_document`; run
|
|
691
|
+
`docslicer --help` for the full list.
|
|
692
|
+
|
|
693
|
+
---
|
|
694
|
+
|
|
644
695
|
## Format-specific functions
|
|
645
696
|
|
|
646
697
|
If you know the format upfront and want explicit failure on unexpected input, use the
|
|
@@ -655,6 +706,47 @@ docslicer.parse_html("filing.html")
|
|
|
655
706
|
|
|
656
707
|
---
|
|
657
708
|
|
|
709
|
+
## Privacy Policy
|
|
710
|
+
|
|
711
|
+
Full policy: <https://docslicer.ai/privacy>
|
|
712
|
+
|
|
713
|
+
**What is collected.** Nothing. DocSlicer has no telemetry, analytics, crash
|
|
714
|
+
reporting, or usage tracking, and requires no account, licence key, or
|
|
715
|
+
registration.
|
|
716
|
+
|
|
717
|
+
**How your documents are used.** Parsing runs entirely on your own machine, in a
|
|
718
|
+
local process. Document contents are used only to produce the outline, text
|
|
719
|
+
slices, search results, and markdown you ask for, and are returned only to the
|
|
720
|
+
caller. Documents are never uploaded to DocSlicer or to any third party. When
|
|
721
|
+
running as an MCP server, `DOCSLICER_MCP_ROOT` bounds which directory tree may
|
|
722
|
+
be read from and written to.
|
|
723
|
+
|
|
724
|
+
**Where data is stored, and for how long.** Parsed results are cached on your
|
|
725
|
+
own disk — by default `~/.cache/docslicer-mcp`, configurable with
|
|
726
|
+
`DOCSLICER_MCP_CACHE`. The cache is pruned to a size ceiling
|
|
727
|
+
(`DOCSLICER_MCP_CACHE_MAX_MB`, default 2048 MB); otherwise it persists until you
|
|
728
|
+
delete it, and deleting the directory removes it permanently with no copy
|
|
729
|
+
retained elsewhere. Nothing is written outside the cache directory and any
|
|
730
|
+
output path you supply.
|
|
731
|
+
|
|
732
|
+
**Network access and third parties.** No network request is made for a local
|
|
733
|
+
file. Requests leave your machine only when you pass an `http(s)` source: that
|
|
734
|
+
URL is fetched directly from the host you named, and for HTML pages Playwright
|
|
735
|
+
may load the subresources that page references, exactly as a browser would.
|
|
736
|
+
Requests to `sec.gov` send a `User-Agent` header identifying the client, as the
|
|
737
|
+
SEC fair-access policy requires. These hosts are third parties chosen by you,
|
|
738
|
+
not by DocSlicer, and their own policies govern what they log. Set
|
|
739
|
+
`DOCSLICER_MCP_ALLOW_URLS=0` to reject remote sources entirely.
|
|
740
|
+
|
|
741
|
+
**Third-party clients.** When DocSlicer runs as an MCP server, the client
|
|
742
|
+
(Claude, Cursor, …) handles the conversation under its own privacy policy.
|
|
743
|
+
DocSlicer is not a party to that and receives nothing from it.
|
|
744
|
+
|
|
745
|
+
**Contact.** Privacy questions: jelle@docslicer.ai · Issues:
|
|
746
|
+
<https://github.com/DocSlicer/DocSlicer/issues>
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
658
750
|
## License
|
|
659
751
|
|
|
660
752
|
DocSlicer is **dual-licensed**:
|
|
@@ -663,3 +755,15 @@ DocSlicer is **dual-licensed**:
|
|
|
663
755
|
- **[Commercial license](LICENSE-COMMERCIAL.md)** — for embedding DocSlicer in a closed-source or proprietary product, or offering it as part of a hosted/SaaS service without releasing your source.
|
|
664
756
|
|
|
665
757
|
See [LICENSE-COMMERCIAL.md](LICENSE-COMMERCIAL.md) for details, or reach out about a commercial license.
|
|
758
|
+
|
|
759
|
+
---
|
|
760
|
+
|
|
761
|
+
<!--
|
|
762
|
+
Ownership marker for the official MCP registry (registry.modelcontextprotocol.io).
|
|
763
|
+
The registry verifies a PyPI package by looking for this exact line in the
|
|
764
|
+
project description, which is this README — so it only takes effect once a
|
|
765
|
+
release carrying it is published. Namespace matches the GitHub org that owns
|
|
766
|
+
the repository. Leave it in place; removing it breaks re-publication.
|
|
767
|
+
-->
|
|
768
|
+
|
|
769
|
+
mcp-name: io.github.DocSlicer/docslicer
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# DocSlicer
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/docslicer/) [](LICENSE) [](LICENSE-COMMERCIAL.md)
|
|
3
|
+
[](https://pypi.org/project/docslicer/) [](https://pypi.org/project/docslicer/) [](LICENSE) [](LICENSE-COMMERCIAL.md)
|
|
4
|
+
|
|
5
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=docslicer&config=%7B%22name%22%3A%22docslicer%22%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22docslicer%5Bmcp%5D%22%2C%22docslicer-mcp%22%5D%7D) [](https://cursor.com/install-mcp?name=docslicer&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJkb2NzbGljZXJbbWNwXSIsImRvY3NsaWNlci1tY3AiXX0%3D) [](https://github.com/DocSlicer/DocSlicer/releases/latest)
|
|
4
6
|
|
|
5
7
|
Lightning-fast (31 pages/sec), deterministic document parser and chunker for business documents. No LLM calls or heavy ML models.
|
|
6
8
|
|
|
@@ -8,9 +10,12 @@ DocSlicer turns PDFs, Word documents, HTML pages, and PowerPoint files into clea
|
|
|
8
10
|
|
|
9
11
|
Top score on [BizDocBench](https://github.com/DocSlicer/BizDocBench) (0.88 overall vs 0.70 for the next-best tool). 0.80 table accuracy, 0.98 content faithfulness, 0.85 heading recognition and hierarchy preservation, and 0.76 RAG retrieval performance.
|
|
10
12
|
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
-
|
|
13
|
+
**Two ways to use it:**
|
|
14
|
+
|
|
15
|
+
- **As a Python library — classic RAG.** The layout-aware chunker gives you clean, non-overlapping chunks, each carrying its full heading breadcrumb, ready to embed. [Jump to the API ↓](#parsing)
|
|
16
|
+
- **As an MCP server — vectorless RAG.** For when you want an answer out of a document right now. Claude, Cursor, or VS Code pulls the outline, picks the section it needs, and reads only that — no embedding, and no 200-page document in the context window. [Jump to setup ↓](#mcp-server)
|
|
17
|
+
|
|
18
|
+
### Quick start
|
|
14
19
|
|
|
15
20
|
```python
|
|
16
21
|
import docslicer
|
|
@@ -502,19 +507,49 @@ docslicer-mcp # stdio — what desktop clients launch
|
|
|
502
507
|
docslicer-mcp --transport http --port 8000
|
|
503
508
|
```
|
|
504
509
|
|
|
505
|
-
|
|
510
|
+
### Claude Desktop / Cowork — one-click install
|
|
511
|
+
|
|
512
|
+
Download `docslicer-X.Y.Z.mcpb` from the
|
|
513
|
+
[latest release](https://github.com/DocSlicer/DocSlicer/releases/latest) and
|
|
514
|
+
double-click it, or drag it onto the Claude Desktop window. You pick the folder
|
|
515
|
+
DocSlicer is allowed to read and write during install; no config file, and no
|
|
516
|
+
Python of your own — `uv` provisions the interpreter.
|
|
517
|
+
|
|
518
|
+
### Other clients
|
|
519
|
+
|
|
520
|
+
Every client below launches the server over stdio. `uvx` needs nothing
|
|
521
|
+
installed ahead of time:
|
|
506
522
|
|
|
507
523
|
```jsonc
|
|
508
524
|
{
|
|
509
525
|
"mcpServers": {
|
|
510
526
|
"docslicer": {
|
|
511
|
-
"command": "
|
|
527
|
+
"command": "uvx",
|
|
528
|
+
"args": ["--from", "docslicer[mcp]", "docslicer-mcp"],
|
|
512
529
|
"env": { "DOCSLICER_MCP_ROOT": "/Users/you/Documents" }
|
|
513
530
|
}
|
|
514
531
|
}
|
|
515
532
|
}
|
|
516
533
|
```
|
|
517
534
|
|
|
535
|
+
If you'd rather install it once and skip the resolve on every launch, use
|
|
536
|
+
`pip install 'docslicer[mcp]'` (or `uv tool install`) and set
|
|
537
|
+
`"command": "docslicer-mcp"` with no `args`.
|
|
538
|
+
|
|
539
|
+
| Client | Where the config goes |
|
|
540
|
+
| --- | --- |
|
|
541
|
+
| Claude Code | `claude mcp add docslicer -- uvx --from 'docslicer[mcp]' docslicer-mcp` |
|
|
542
|
+
| Cursor | `~/.cursor/mcp.json`, or `.cursor/mcp.json` per project |
|
|
543
|
+
| VS Code | `.vscode/mcp.json` (use a `servers` key instead of `mcpServers`) |
|
|
544
|
+
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
|
|
545
|
+
| Zed | `settings.json`, under `context_servers` |
|
|
546
|
+
|
|
547
|
+
> **On GUI-launched clients, prefer the `.mcpb`.** An app started from the dock
|
|
548
|
+
> does not inherit your shell `PATH` — on macOS that excludes
|
|
549
|
+
> `/opt/homebrew/bin` — so a bare `uvx` or `docslicer-mcp` can work in a
|
|
550
|
+
> terminal and fail when the client spawns it. Use an absolute path
|
|
551
|
+
> (`which uvx`) if you hit this. The extension sidesteps it entirely.
|
|
552
|
+
|
|
518
553
|
### How it works
|
|
519
554
|
|
|
520
555
|
A parsed document is far larger than a model's context window, so the server
|
|
@@ -581,6 +616,22 @@ can write anywhere the server process can.
|
|
|
581
616
|
|
|
582
617
|
---
|
|
583
618
|
|
|
619
|
+
## Command line
|
|
620
|
+
|
|
621
|
+
`docslicer` parses one document to JSON on stdout — for a quick look at a file,
|
|
622
|
+
or to pipe into `jq`.
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
docslicer report.pdf # chunks as JSON
|
|
626
|
+
docslicer report.pdf -o chunks.json # write to a file
|
|
627
|
+
docslicer report.pdf --no-chunking # blocks instead of chunks
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
It takes the same parsing and chunking options as `parse_document`; run
|
|
631
|
+
`docslicer --help` for the full list.
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
584
635
|
## Format-specific functions
|
|
585
636
|
|
|
586
637
|
If you know the format upfront and want explicit failure on unexpected input, use the
|
|
@@ -595,6 +646,47 @@ docslicer.parse_html("filing.html")
|
|
|
595
646
|
|
|
596
647
|
---
|
|
597
648
|
|
|
649
|
+
## Privacy Policy
|
|
650
|
+
|
|
651
|
+
Full policy: <https://docslicer.ai/privacy>
|
|
652
|
+
|
|
653
|
+
**What is collected.** Nothing. DocSlicer has no telemetry, analytics, crash
|
|
654
|
+
reporting, or usage tracking, and requires no account, licence key, or
|
|
655
|
+
registration.
|
|
656
|
+
|
|
657
|
+
**How your documents are used.** Parsing runs entirely on your own machine, in a
|
|
658
|
+
local process. Document contents are used only to produce the outline, text
|
|
659
|
+
slices, search results, and markdown you ask for, and are returned only to the
|
|
660
|
+
caller. Documents are never uploaded to DocSlicer or to any third party. When
|
|
661
|
+
running as an MCP server, `DOCSLICER_MCP_ROOT` bounds which directory tree may
|
|
662
|
+
be read from and written to.
|
|
663
|
+
|
|
664
|
+
**Where data is stored, and for how long.** Parsed results are cached on your
|
|
665
|
+
own disk — by default `~/.cache/docslicer-mcp`, configurable with
|
|
666
|
+
`DOCSLICER_MCP_CACHE`. The cache is pruned to a size ceiling
|
|
667
|
+
(`DOCSLICER_MCP_CACHE_MAX_MB`, default 2048 MB); otherwise it persists until you
|
|
668
|
+
delete it, and deleting the directory removes it permanently with no copy
|
|
669
|
+
retained elsewhere. Nothing is written outside the cache directory and any
|
|
670
|
+
output path you supply.
|
|
671
|
+
|
|
672
|
+
**Network access and third parties.** No network request is made for a local
|
|
673
|
+
file. Requests leave your machine only when you pass an `http(s)` source: that
|
|
674
|
+
URL is fetched directly from the host you named, and for HTML pages Playwright
|
|
675
|
+
may load the subresources that page references, exactly as a browser would.
|
|
676
|
+
Requests to `sec.gov` send a `User-Agent` header identifying the client, as the
|
|
677
|
+
SEC fair-access policy requires. These hosts are third parties chosen by you,
|
|
678
|
+
not by DocSlicer, and their own policies govern what they log. Set
|
|
679
|
+
`DOCSLICER_MCP_ALLOW_URLS=0` to reject remote sources entirely.
|
|
680
|
+
|
|
681
|
+
**Third-party clients.** When DocSlicer runs as an MCP server, the client
|
|
682
|
+
(Claude, Cursor, …) handles the conversation under its own privacy policy.
|
|
683
|
+
DocSlicer is not a party to that and receives nothing from it.
|
|
684
|
+
|
|
685
|
+
**Contact.** Privacy questions: jelle@docslicer.ai · Issues:
|
|
686
|
+
<https://github.com/DocSlicer/DocSlicer/issues>
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
598
690
|
## License
|
|
599
691
|
|
|
600
692
|
DocSlicer is **dual-licensed**:
|
|
@@ -603,3 +695,15 @@ DocSlicer is **dual-licensed**:
|
|
|
603
695
|
- **[Commercial license](LICENSE-COMMERCIAL.md)** — for embedding DocSlicer in a closed-source or proprietary product, or offering it as part of a hosted/SaaS service without releasing your source.
|
|
604
696
|
|
|
605
697
|
See [LICENSE-COMMERCIAL.md](LICENSE-COMMERCIAL.md) for details, or reach out about a commercial license.
|
|
698
|
+
|
|
699
|
+
---
|
|
700
|
+
|
|
701
|
+
<!--
|
|
702
|
+
Ownership marker for the official MCP registry (registry.modelcontextprotocol.io).
|
|
703
|
+
The registry verifies a PyPI package by looking for this exact line in the
|
|
704
|
+
project description, which is this README — so it only takes effect once a
|
|
705
|
+
release carrying it is published. Namespace matches the GitHub org that owns
|
|
706
|
+
the repository. Leave it in place; removing it breaks re-publication.
|
|
707
|
+
-->
|
|
708
|
+
|
|
709
|
+
mcp-name: io.github.DocSlicer/docslicer
|
|
@@ -20,7 +20,7 @@ try:
|
|
|
20
20
|
from importlib.metadata import version as _pkg_version
|
|
21
21
|
__version__ = _pkg_version("docslicer")
|
|
22
22
|
except Exception:
|
|
23
|
-
__version__ = "0.2.
|
|
23
|
+
__version__ = "0.2.2"
|
|
24
24
|
|
|
25
25
|
from ._config import ParseConfig
|
|
26
26
|
from ._result import ParseResult, Chunk, Block, Table, TableCell, Chart, ChartPoint, BBox, HierarchyNode, HierarchyTree
|
|
@@ -306,6 +306,7 @@ def _build_blocks(df_blocks: pd.DataFrame, extra_fields: list[str] | None = None
|
|
|
306
306
|
link_url=_str_list(row, "link_url"),
|
|
307
307
|
table_ids=_str_list(row, "table_id"),
|
|
308
308
|
chart_ids=_str_list(row, "chart_id"),
|
|
309
|
+
token_count=int(row.get("token_count", 0) or 0),
|
|
309
310
|
extra=_extra(row, _extra_fields),
|
|
310
311
|
))
|
|
311
312
|
return out
|
|
@@ -134,6 +134,7 @@ class Block:
|
|
|
134
134
|
link_url: list[str] # unique URLs found in block
|
|
135
135
|
table_ids: list[str] # table IDs referenced in block
|
|
136
136
|
chart_ids: list[str] = field(default_factory=list) # chart IDs referenced in block (docx/pptx)
|
|
137
|
+
token_count: int = 0 # counted like Chunk.token_count, for budgeting a read
|
|
137
138
|
extra: dict = field(default_factory=dict) # caller-requested extra fields from the pipeline df
|
|
138
139
|
|
|
139
140
|
@classmethod
|
|
@@ -151,6 +152,7 @@ class Block:
|
|
|
151
152
|
link_url=d.get("link_url", []),
|
|
152
153
|
table_ids=[_norm_id(v) for v in d.get("table_ids", [])],
|
|
153
154
|
chart_ids=[_norm_id(v) for v in d.get("chart_ids", [])],
|
|
155
|
+
token_count=d.get("token_count", 0),
|
|
154
156
|
extra=d.get("extra", {}),
|
|
155
157
|
)
|
|
156
158
|
|
|
@@ -112,10 +112,15 @@ def main():
|
|
|
112
112
|
print(f"Error: {exc}", file=sys.stderr)
|
|
113
113
|
sys.exit(1)
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
# --no-chunking stops the pipeline before chunks exist, so blocks are the
|
|
116
|
+
# unit it has to return; serializing chunks regardless printed an empty
|
|
117
|
+
# list for the one flag whose whole purpose is to produce output faster.
|
|
118
|
+
records = result.blocks if args.no_chunking else result.chunks
|
|
119
|
+
label = "blocks" if args.no_chunking else "chunks"
|
|
120
|
+
out = json.dumps([r.to_dict() for r in records], indent=2)
|
|
116
121
|
|
|
117
122
|
if args.output:
|
|
118
123
|
Path(args.output).write_text(out, encoding="utf-8")
|
|
119
|
-
print(f"Wrote {len(
|
|
124
|
+
print(f"Wrote {len(records)} {label} to {args.output}")
|
|
120
125
|
else:
|
|
121
126
|
print(out)
|
|
@@ -21,6 +21,7 @@ from collections import OrderedDict
|
|
|
21
21
|
from dataclasses import dataclass
|
|
22
22
|
from pathlib import Path
|
|
23
23
|
|
|
24
|
+
from .. import __version__
|
|
24
25
|
from .._result import ParseResult
|
|
25
26
|
|
|
26
27
|
_MEMORY_LIMIT = 8 # ParseResults kept hot in RAM
|
|
@@ -137,8 +138,14 @@ def resolve_output(path: str, base: Path | None = None) -> Path:
|
|
|
137
138
|
|
|
138
139
|
|
|
139
140
|
def make_doc_id(source: str, options: dict) -> str:
|
|
140
|
-
"""Stable handle for a (source, options, file-version)
|
|
141
|
-
|
|
141
|
+
"""Stable handle for a (source, options, file-version, docslicer-version) quad.
|
|
142
|
+
|
|
143
|
+
The version is in the fingerprint because a cached parse is a snapshot of
|
|
144
|
+
what the pipeline produced at the time, fields and all. A release that adds
|
|
145
|
+
one — block token counts, say — would otherwise be served stale records
|
|
146
|
+
missing it, and a missing field reads as a zero rather than an error.
|
|
147
|
+
"""
|
|
148
|
+
fingerprint = {"source": source, "options": options, "docslicer": __version__}
|
|
142
149
|
if not is_url(source):
|
|
143
150
|
try:
|
|
144
151
|
stat = Path(source).stat()
|