Litmark
A local research application: import papers, read short cited summaries, write Markdown notes, inspect the cited PDF passages, and chat with a coding agent that can search the project and edit its files.
Import papers → ask questions → write a sourced note → inspect the evidence → refine the note.
Everything you write stays as ordinary files in a movable project directory:
notes/*.md, documents/<id>/original.pdf, references.json. The application
is a convenient view onto those files, not their owner.
Install
python -m pip install litmark # core reader and editor
python -m pip install 'litmark[claude]' # plus the agent adapter
Requires Python 3.11+. Tested on macOS and Linux. The published wheel contains the compiled browser assets — you do not need Node, npm, or a second web server to run this application.
With pipx or uv:
pipx install litmark
uv tool install litmark
Use
litmark init ./my-research
litmark serve ./my-research --open
serve binds to 127.0.0.1, prints the local URL, and serves exactly one
project per process. Reopening an existing project needs no initialization, and
init never overwrites existing material.
Reaching it through a proxy or port-forward
By default the server binds to loopback and rejects any Host header that is
not a loopback name. That second check is what stops a malicious page from
using DNS rebinding to talk to your local server — but behind a reverse proxy
or a port-forward the header carries the proxy's hostname, so the check would
reject every real request. Widen it explicitly:
# Bind beyond loopback; any Host header is then accepted.
litmark serve ./my-research --host 0.0.0.0
# Or name the proxy's hostname and keep the check strict.
litmark serve ./my-research --host 0.0.0.0 --allow-host papers.internal
The per-process session credential embedded in the served page remains the access control in both cases. On an untrusted network prefer an SSH tunnel, which keeps the default loopback binding intact:
ssh -N -L 8765:127.0.0.1:8765 you@the-machine
Check your environment at any time:
litmark doctor ./my-research
doctor reports on the workspace, the optional agent dependency, the runtime
it needs, and whether authentication is configured — without printing secrets.
Agent configuration
The agent backend is the Claude Agent SDK for Python, behind a provider-neutral adapter. Provider credentials and billing are separate from installing this application; a consumer chat subscription does not by itself grant SDK access.
The reader and editor work with no agent account at all. Import and text extraction still run; automatic summaries wait until an agent is configured, and the interface says so plainly.
Project layout
| Path | Purpose |
|---|---|
project.toml |
Schema version and non-secret project settings. |
documents/<id>/original.pdf |
Original immutable PDF. |
documents/<id>/metadata.json |
Identity, hash, filename, title, page count, status. |
documents/<id>/pages.json |
Per-page text, character geometry, offset mapping. |
documents/<id>/summary.md |
Editable, cited summary. |
notes/*.md |
User and agent notes. |
references.json |
Versioned source registry. |
references.bib |
Generated BibTeX bibliography of the imported documents. |
.research/state.sqlite |
Conversations, events, jobs, run state, change log. |
.research/history/ |
Previous file contents, for review and undo. |
.research/runs/ |
Staged agent edits and run diagnostics. |
Citations
A citation is an ordinary Markdown link with an application-specific destination:
The identification argument relies on a mobility restriction.
[Assumption 2, p. 12](source:ref-001)
ref-001 resolves through references.json, which records the document, the
immutable PDF content hash, the one-based physical page number, the quoted
passage, and normalized highlight rectangles. Reference resolution validates
where a passage is, not whether it supports the claim — you assess that by
reading the evidence.
Bibliography
Write .bib in the sidebar generates references.bib in the project
directory, and Download fetches the same file without writing it. There is
one entry per imported document — a .bib entry is a work, so the page each
reference points at travels in the \cite[p.~12]{key} command the export
returns alongside the entries, not in the entry itself.
Entries carry only what the PDF actually supplies. A paper with no author
metadata gets an entry with no author field and a warning saying so; nothing
is filled in from general knowledge. The output is deterministic, so exporting
an unchanged bibliography rewrites nothing, and a .bib you edited by hand is
copied into .research/history/ before it is replaced.
Development
uv venv && uv pip install -e . --group dev
npm --prefix frontend install
npm --prefix frontend run build # writes src/litmark/static/
uv run pytest
uv run litmark serve ./my-research --reload
npm run dev runs the frontend with hot reload against a server started
separately on port 8765.
Tests
uv run pytest # server and acceptance criteria
uv run pytest --runslow # plus: build the wheel, install it clean, serve it
npm --prefix frontend test # renderer unit tests, and the bundle run in a DOM
# Real-browser checks (A2 live preview, A6 highlight geometry under zoom).
# Point it at a project whose open note contains a source: citation.
litmark serve ./my-research &
LITMARK_BASE_URL=http://127.0.0.1:8765/ npm --prefix frontend run test:browser
The browser suite drives headless Firefox over Marionette. Headless Chromium is
deliberately not used: under some sandboxes it cannot reach loopback HTTP — it
returns an empty document where curl succeeds — so a Chromium suite passes
without having checked anything.
Scope
v0.1 covers ingestion of text-based PDFs, cited summaries, Markdown live-preview editing, PDF evidence with highlights, chat with one agent backend, and manual references. Deferred: OCR, URL downloads, Word/HTML ingestion, Zotero integration, semantic search, multiple agent providers, arbitrary analysis execution, multi-user collaboration, full mobile editing, and public hosting.
License
MIT.
Metadata
Release files for litmark 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| litmark-0.1.0.tar.gz | 2.9 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| litmark-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 5.8 MB
Release files / litmark-0.1.0.tar.gz
| Download URL | litmark-0.1.0.tar.gz |
|---|---|
| Size | 2.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
704e2698f2739cad1ee29ff975b237148bb79d0e049ea7200dafec1d34e2030e
|
|
BLAKE2b-256 checksum How to use checksums |
fa3630bf375e6aad86c13f66d7daba577a6b99f6d4798a07cb3670c448800d06
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / litmark-0.1.0-py3-none-any.whl
| Download URL | litmark-0.1.0-py3-none-any.whl |
|---|---|
| Size | 2.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
79ec0269a9152d336ec9f33887b501717f5895d38d19b2cd52c48bd272b8577c
|
|
BLAKE2b-256 checksum How to use checksums |
bf9a835c811936b3e048987ffbdbdef4b60efa03b4a7c12b5232d33e46112ef2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for litmark 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.