
Dokumen-Pintar
β 1from firdausmntp
62 format-aware tools for AI to read and edit Word, Excel, and PDF files with precision β plus academic document linting for Indonesian standards.
Why Dokumen-Pintar
Most filesystem MCP servers stop at "read this file, write that file." Dokumen-Pintar treats documents as structured data the AI can navigate. Tell an agent to update a paragraph by index, set a cell by Sheet1!B2, walk a JSON tree with JSONPath, generate a DOCX from Markdown - it works the same way across every supported format.
Every mutating tool snapshots the file first. Every action lands in an audit log. Every path is sandboxed to roots you opt in. The default config is sensible; the profiles cover the rest.
Features
<table> <tr> <td width="50%" valign="top">Multi-root Sandbox β Define multiple workspace roots with per-root writable control. All paths outside the sandbox are rejected.
10 Formats β Plain text, Markdown, LaTeX, JSON / YAML, CSV / TSV, XML / SVG, DOCX, XLSX, PPTX, PDF.
62 MCP Tools - File & content CRUD, structured access, batch operations, search, versioning, metadata, authoring, image extraction, sections, templates, TOC, bibliography, document compare, lint - all exposed as callable tools.
Authoring β Generate DOCX or PDF from a JSON spec or Markdown source via compose_docx / compose_pdf / compose_from_markdown.
Structured Access β JSONPath for JSON / YAML, XPath for XML, cell / range / sheet for XLSX, paragraph / table for DOCX, slide for PPTX, page for PDF.
Automatic Versioning β Copy-on-write snapshots on every write. Undo, diff, restore, and purge anytime.
Metadata Layer β Read, write, delete, or strip EXIF, OOXML core properties, and PDF docinfo through one consistent API.
Audit Trail β Every mutation logged to JSONL with timestamp and operation details.
2 Transports β stdio (Claude Desktop, Cursor, VS Code, Windsurf) and HTTP / SSE.
</td> </tr> </table>Supported Formats
| Format | Read | Write | Structured Query | Search |
|---|---|---|---|---|
| Plain text / Markdown | β | β | β | β |
| JSON | β | β | JSONPath $.key | β |
| YAML | β | β | JSONPath $.key | β |
| CSV / TSV | β | β | row:N Β· col:NAME Β· cell:row:N,col:NAME | β |
| XML / SVG | β | β | XPath //node | β |
| DOCX | β | β | paragraph:N Β· table:N | β |
| XLSX | β | β | cell:Sheet!A1 Β· range: Β· sheet: | β |
| PPTX | β | β | slide:N Β· slide_title:N | β |
| β | β | page:N Β· outline Β· metadata | β |
Tools Overview
62 MCP tools organized by category:
| Category | Tools |
|---|---|
| Workspace | workspace_list_roots Β· workspace_stat Β· workspace_tree Β· workspace_diagnose |
| File CRUD | file_create Β· file_delete Β· file_rename Β· file_copy Β· file_move |
| Content | content_read Β· content_write Β· content_append Β· content_insert Β· content_replace Β· content_delete_range Β· content_patch Β· content_diff |
| Structured | struct_get Β· struct_set Β· struct_delete Β· struct_meta |
| Metadata | metadata_read Β· metadata_write Β· metadata_delete Β· metadata_strip Β· metadata_read_batch |
| Authoring | validate_spec Β· compose_docx Β· compose_pdf Β· compose_from_markdown Β· compose_to_markdown |
| Sections | section_extract Β· section_merge |
| Images | image_list Β· image_extract Β· image_extract_all Β· image_replace |
| Templates | template_list Β· template_install Β· template_render Β· template_render_named |
| TOC & Bibliography | toc_generate Β· bibliography_check Β· bibliography_format |
| Compare & Lint | document_compare Β· document_lint Β· document_lint_fix |
| Batch | batch_rename Β· batch_replace_content Β· batch_replace_structured Β· batch_delete |
| Search | search_filename Β· search_content Β· search_in_format |
| Versioning | version_list Β· version_diff Β· version_restore Β· version_undo Β· version_purge |
| Semantic * | search_semantic Β· semantic_index_path Β· semantic_stats |
<sub>* Only registered when <code>semantic_search.enabled = true</code> and the <code>[semantic]</code> extra is installed.</sub>
Full parameter reference: docs/TOOLS.md
Architecture
flowchart TD
Client["AI Client\n(Claude, Cursor, VS Code, ...)"]
Client -->|"MCP protocol\n(stdio or HTTP/SSE)"| Server
subgraph Server["dokumen-pintar server"]
PG["PathGuard\nsandboxed multi-root"]
H["Handlers\n9 format parsers"]
V["Versions\ncopy-on-write snapshots"]
A["AuditLog\nJSONL mutation log"]
S["Search\nfilename + content"]
SE["Semantic\nvector index (optional)"]
end
Server --> FS["Filesystem\n(sandboxed workspace roots)"]Full details: docs/ARCHITECTURE.md
Testing
pip install -e ".[dev]"
pytestHTML coverage report: htmlcov/index.html
Performance numbers and methodology: docs/BENCHMARK.md
Documentation
| Document | Contents |
|---|---|
| USAGE.md | Workspace URIs, tool examples, practical recipes |
| CONFIG.md | All config fields with types, defaults, and notes |
| TOOLS.md | Full reference for all 62 tools |
| ARCHITECTURE.md | Module map, request flow, versioning, safety |
| BENCHMARK.md | Performance baselines and methodology |
| profiles/ | Six pre-tuned config profiles (personal, developer, research, ...) |
| AGENTS.md | Contributor guide: conventions, dev workflow, PR process |
Contributing
git clone https://github.com/firdausmntp/Dokumen-Pintar.git
cd Dokumen-Pintar
pip install -e ".[dev]"
ruff check src/ # lint
mypy src/dokumen_pintar/ # type check
pytest # test + coveragePRs welcome. All tests must pass and coverage must stay at 100%. Read AGENTS.md before submitting - it covers conventions, the handler protocol, and how to add a new format or tool.
License
MIT β 2026 firdausmntp
<p align="center"> <sub>Built by <a href="https://github.com/firdausmntp">firdausmntp</a></sub> </p>
pip install dokumen-pintarQuick Start
1. Install
pip install dokumen-pintargit clone https://github.com/firdausmntp/Dokumen-Pintar.git
cd Dokumen-Pintar
pip install -e ".[dev]"pip install dokumen-pintar[semantic]2. Create a Config
dokumen-pintar-initOr create one manually:
{
"roots": [
{ "name": "documents", "path": "~/Documents", "writable": true },
{ "name": "projects", "path": "~/Projects", "writable": true }
]
}All other fields are optional with sensible defaults. See docs/CONFIG.md.
3. Run
dokumen-pintar --config dokumen-pintar.config.jsonAd-hoc roots without a config file
Override or replace config roots from the command line β handy for one-off sessions or scripting:
# Single writable root, no config file required
dokumen-pintar --root docs:/path/to/folder
# Multiple roots, mix read-only and writable, choose stdio transport
dokumen-pintar \
--root project:/repo:rw \
--root refs:/library:ro \
--transport stdio
# Force every root to read-only (overrides config + --root)
dokumen-pintar --config myconfig.json --read-only
# Path-only shorthand (root name derived from basename)
dokumen-pintar --root /home/me/DocumentsHealth check
dokumen-pintar-doctor --config dokumen-pintar.config.jsonVerifies config validity, root existence, .mcpdocs snapshot writability,
registered handlers, and optional semantic-search dependencies.
4. Connect to an AI Client
<details> <summary><b>Claude Desktop</b></summary>Add to your claude_desktop_config.json:
{
"mcpServers": {
"dokumen-pintar": {
"command": "dokumen-pintar",
"args": ["--config", "/path/to/dokumen-pintar.config.json"]
}
}
}Use the same stdio transport. Point your IDE's MCP settings to the dokumen-pintar command and config path.
{
"transport": {
"stdio": false,
"http": { "enabled": true, "port": 7878 }
}
}Start the server and connect your client to http://127.0.0.1:7878.
Usage Examples
# List available workspace roots
workspace_list_roots()
# Read a Word document
content_read(path="documents:/reports/q1.docx")
# Create a new file
file_create(path="documents:/notes/todo.txt", content="Hello World")
# Find & replace inside a file
content_replace(path="documents:/notes/todo.txt", old="World", new="Everyone")
# Full-text search across all PDFs
search_content(query="budget 2024", format="pdf")
# Read an Excel cell
structured_get(path="documents:/data.xlsx", expr="cell:Sheet1!B2")
# Update a JSON key
structured_set(path="documents:/config.json", expr="$.database.port", value=5432)
# Delete an XML node
structured_delete(path="documents:/data.xml", expr="//item[@id='old']")
# Batch rename (dry-run first)
batch_rename(glob="*.txt", pattern="draft_", replacement="final_", dry_run=true)
# Undo last change
version_undo(path="documents:/reports/q1.docx")Full guide with recipes: docs/USAGE.md
No common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.