# utyagi24/klarpdf architecture

> Architecture diagram of the GitHub repository utyagi24/klarpdf, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-15). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/utyagi24/klarpdf
- Repository: https://github.com/utyagi24/klarpdf

## Overview

KlarPDF is an offline Windows PDF viewer and editor, with a separate MCP bridge exposing document operations to agents. In the desktop workflow, a user opens a PDF, navigates and edits its virtual document, then saves edits through the materialization engine. The MCP server offers a parallel agent-facing route for queries, tables, annotations, redaction, and transforms. The sampled source establishes several model and viewer relationships; some UI wiring and MCP subsystems are only documented or indexed, so uncertain links are omitted.

Main entry points: [`klarpdf/mcp_bridge/server.py`](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/server.py) (MCP server), [`klarpdf/mcp_bridge/queries.py`](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/queries.py) (Document queries), [`main_window.py`](https://github.com/utyagi24/klarpdf/blob/main/main_window.py) (Document window), [`viewer/pdf_view.py`](https://github.com/utyagi24/klarpdf/blob/main/viewer/pdf_view.py) (PDF view)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Desktop app"]
  node_app["App lifecycle<br/>[app.py]"]
  node_window["Document window<br/>[main_window.py]"]
  node_pages["Page organizer<br/>[thumbnail_panel.py]"]
  node_outline["Outline panel<br/>[outline_panel.py]"]
  node_annotations_panel["Annotations panel"]
end

subgraph group_viewer["Viewing and markup"]
  node_pdfview["PDF view<br/>[pdf_view.py]"]
  node_search["Search<br/>[search.py]"]
  node_overlay["Markup tools<br/>[annotations.py]"]
end

subgraph group_model["PDF document model"]
  node_vdoc["Virtual document"]
  node_pageedits["Page edits<br/>[page_edits.py]"]
  node_marks["Content marks<br/>[content_marks.py]"]
  node_foreign["Foreign annotations<br/>[foreign_annots.py]"]
  node_engine["Save engine<br/>[edit_engine.py]"]
  node_text["Page text<br/>[page_text.py]"]
end

subgraph group_mcp["MCP bridge"]
  node_mcpserver["MCP server<br/>[server.py]"]
  node_queries["Document queries<br/>[queries.py]"]
  node_tables["Table extraction<br/>[tables.py]"]
  node_headings["Heading tools<br/>[headings.py]"]
  node_redaction["Redaction tools<br/>[redaction.py]"]
  node_transforms["Document transforms<br/>[transforms.py]"]
  node_replies["MCP replies<br/>[replies.py]"]
end

node_user(("PDF user"))
node_agent(("MCP client"))

node_user -->|"opens PDF"| node_app
node_app -->|"creates window"| node_window
node_window -->|"opens document"| node_vdoc
node_user -->|"reads and navigates"| node_pdfview
node_pdfview -->|"displays pages"| node_vdoc
node_window -->|"organizes pages"| node_pages
node_window -.->|"shows outline"| node_outline
node_window -->|"lists annotations"| node_annotations_panel
node_pdfview -->|"routes search"| node_search
node_search -->|"searches text"| node_text
node_pdfview -->|"routes markup"| node_overlay
node_overlay -->|"edits annotations"| node_pageedits
node_pageedits -->|"uses mark descriptors"| node_marks
node_pageedits -->|"handles foreign marks"| node_foreign
node_vdoc -->|"materializes on save"| node_engine
node_agent -->|"requests tools"| node_mcpserver
node_mcpserver -->|"dispatches queries"| node_queries
node_mcpserver -->|"dispatches table tools"| node_tables
node_mcpserver -->|"dispatches heading tools"| node_headings
node_mcpserver -->|"dispatches redaction"| node_redaction
node_mcpserver -->|"dispatches transforms"| node_transforms
node_queries -->|"queries document"| node_vdoc
node_queries -->|"reads page text"| node_text
node_queries -->|"formats results"| node_replies
node_tables -->|"uses query helpers"| node_queries
node_tables -->|"formats results"| node_replies
node_headings -->|"uses query helpers"| node_queries
node_headings -->|"uses table helpers"| node_tables
node_redaction -->|"applies redactions"| node_pageedits

click node_app "https://github.com/utyagi24/klarpdf/blob/main/app.py"
click node_window "https://github.com/utyagi24/klarpdf/blob/main/main_window.py"
click node_pages "https://github.com/utyagi24/klarpdf/blob/main/organize/thumbnail_panel.py"
click node_outline "https://github.com/utyagi24/klarpdf/blob/main/organize/outline_panel.py"
click node_annotations_panel "https://github.com/utyagi24/klarpdf/blob/main/organize/annotations_panel.py"
click node_pdfview "https://github.com/utyagi24/klarpdf/blob/main/viewer/pdf_view.py"
click node_search "https://github.com/utyagi24/klarpdf/blob/main/viewer/search.py"
click node_overlay "https://github.com/utyagi24/klarpdf/blob/main/viewer/annotations.py"
click node_vdoc "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/virtual_document.py"
click node_pageedits "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/page_edits.py"
click node_marks "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/content_marks.py"
click node_foreign "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/foreign_annots.py"
click node_engine "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/edit_engine.py"
click node_text "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/page_text.py"
click node_mcpserver "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/server.py"
click node_queries "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/queries.py"
click node_tables "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/tables.py"
click node_headings "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/headings.py"
click node_redaction "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/redaction.py"
click node_transforms "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/transforms.py"
click node_replies "https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/replies.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_window,node_pages,node_outline,node_annotations_panel,node_user,node_agent toneBlue
class node_pdfview,node_search,node_overlay toneAmber
class node_vdoc,node_pageedits,node_marks,node_foreign,node_engine,node_text toneMint
class node_mcpserver,node_queries,node_tables,node_headings,node_redaction,node_transforms,node_replies toneRose
```

## Components

### Desktop app

- [App lifecycle](https://github.com/utyagi24/klarpdf/blob/main/app.py): `app.py`
- [Document window](https://github.com/utyagi24/klarpdf/blob/main/main_window.py): `main_window.py`
- [Page organizer](https://github.com/utyagi24/klarpdf/blob/main/organize/thumbnail_panel.py): `organize/thumbnail_panel.py`
- [Outline panel](https://github.com/utyagi24/klarpdf/blob/main/organize/outline_panel.py): `organize/outline_panel.py`
- [Annotations panel](https://github.com/utyagi24/klarpdf/blob/main/organize/annotations_panel.py): `organize/annotations_panel.py`

### Viewing and markup

- [PDF view](https://github.com/utyagi24/klarpdf/blob/main/viewer/pdf_view.py): `viewer/pdf_view.py`
- [Search](https://github.com/utyagi24/klarpdf/blob/main/viewer/search.py): `viewer/search.py`
- [Markup tools](https://github.com/utyagi24/klarpdf/blob/main/viewer/annotations.py): `viewer/annotations.py`

### PDF document model

- [Virtual document](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/virtual_document.py): `klarpdf/model/virtual_document.py`
- [Page edits](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/page_edits.py): `klarpdf/model/page_edits.py`
- [Content marks](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/content_marks.py): `klarpdf/model/content_marks.py`
- [Foreign annotations](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/foreign_annots.py): `klarpdf/model/foreign_annots.py`
- [Save engine](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/edit_engine.py): `klarpdf/model/edit_engine.py`
- [Page text](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/model/page_text.py): `klarpdf/model/page_text.py`

### MCP bridge

- [MCP server](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/server.py): `klarpdf/mcp_bridge/server.py`
- [Document queries](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/queries.py): `klarpdf/mcp_bridge/queries.py`
- [Table extraction](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/tables.py): `klarpdf/mcp_bridge/tables.py`
- [Heading tools](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/headings.py): `klarpdf/mcp_bridge/headings.py`
- [Redaction tools](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/redaction.py): `klarpdf/mcp_bridge/redaction.py`
- [Document transforms](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/transforms.py): `klarpdf/mcp_bridge/transforms.py`
- [MCP replies](https://github.com/utyagi24/klarpdf/blob/main/klarpdf/mcp_bridge/replies.py): `klarpdf/mcp_bridge/replies.py`

### Other components

- **PDF user**
- **MCP client**

## Connections

- PDF user → App lifecycle: opens PDF (evidence: `app.py`)
- App lifecycle → Document window: creates window (evidence: `app.py`)
- Document window → Virtual document: opens document (evidence: `main_window.py`)
- PDF user → PDF view: reads and navigates
- PDF view → Virtual document: displays pages (evidence: `viewer/pdf_view.py`)
- Document window → Page organizer: organizes pages (evidence: `main_window.py`)
- Document window → Outline panel: shows outline (evidence: `main_window.py`)
- Document window → Annotations panel: lists annotations (evidence: `organize/annotations_panel.py`)
- PDF view → Search: routes search (evidence: `viewer/pdf_view.py`)
- Search → Page text: searches text (evidence: `viewer/search.py`)
- PDF view → Markup tools: routes markup (evidence: `viewer/pdf_view.py`)
- Markup tools → Page edits: edits annotations (evidence: `viewer/annotations.py`)
- Page edits → Content marks: uses mark descriptors (evidence: `klarpdf/model/page_edits.py`)
- Page edits → Foreign annotations: handles foreign marks (evidence: `klarpdf/model/page_edits.py`)
- Virtual document → Save engine: materializes on save (evidence: `klarpdf/model/virtual_document.py`)
- MCP client → MCP server: requests tools
- MCP server → Document queries: dispatches queries (evidence: `klarpdf/mcp_bridge/server.py`)
- MCP server → Table extraction: dispatches table tools (evidence: `klarpdf/mcp_bridge/server.py`)
- MCP server → Heading tools: dispatches heading tools (evidence: `klarpdf/mcp_bridge/server.py`)
- MCP server → Redaction tools: dispatches redaction (evidence: `klarpdf/mcp_bridge/server.py`)
- MCP server → Document transforms: dispatches transforms (evidence: `klarpdf/mcp_bridge/server.py`)
- Document queries → Virtual document: queries document (evidence: `klarpdf/mcp_bridge/queries.py`)
- Document queries → Page text: reads page text (evidence: `klarpdf/mcp_bridge/queries.py`)
- Document queries → MCP replies: formats results (evidence: `klarpdf/mcp_bridge/queries.py`)
- Table extraction → Document queries: uses query helpers (evidence: `klarpdf/mcp_bridge/tables.py`)
- Table extraction → MCP replies: formats results (evidence: `klarpdf/mcp_bridge/tables.py`)
- Heading tools → Document queries: uses query helpers (evidence: `klarpdf/mcp_bridge/headings.py`)
- Heading tools → Table extraction: uses table helpers (evidence: `klarpdf/mcp_bridge/headings.py`)
- Redaction tools → Page edits: applies redactions (evidence: `klarpdf/mcp_bridge/redaction.py`)
