noteker
by andras-tkcs
README.md
# Noteker
**Noteker** is a macOS MCP server that converts handwritten PDF notes into clean Markdown using Claude Vision. Give it a PDF, get back structured text — no OCR engine, no separate models, no setup beyond an Anthropic API key.
Designed for notes exported from **Noteshelf3** on iPad, but works with any handwritten PDF.
---
## How it works
```
Claude ──MCP stdio──▶ noteker
│
┌──────────▼──────────┐
│ PyMuPDF │
│ PDF → PNG per page │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Claude Vision API │
│ transcribe + format │
└──────────┬──────────┘
│
clean Markdown ──▶ Claude
```
Each page is rendered to an image and sent to Claude Vision, which transcribes the handwriting and formats it as Markdown in a single pass. Blank pages are skipped automatically. Pages are processed in batches of at most 5 — requests spanning more pages are automatically split into sequential batches and stitched back into one combined Markdown result.
Both tools are read-only: they never modify the source PDF or any other file.
---
## Tools
| Tool | Description |
|------|-------------|
| `noteker_process_pdf(file_path, note_context="", page_start=None, page_end=None)` | Transcribe a local PDF of handwritten notes. Returns clean Markdown. `note_context` is an optional hint (e.g. `"team meeting 2025-06-20"`) that helps Claude resolve ambiguous words. `page_start` / `page_end` are 1-based inclusive page bounds — omit both to process the whole document (capped at `max_pages`). Internally, pages are sent to Claude Vision in batches of at most 5 regardless of range size. |
| `noteker_status()` | Return version, config path, and whether the API key is set. |
---
## Installation
### As a Claude Desktop extension (recommended)
1. Download the latest `noteker-x.y.z.mcpb` from the [Releases](../../releases) page.
2. Double-click it (or drag it into Claude Desktop → Settings → Extensions) to install.
3. When prompted, paste your Anthropic API key — Claude Desktop stores it securely and passes it to Noteker as `ANTHROPIC_API_KEY`.
That's it — no separate config file or MCP registration step needed. Extra settings (model, `max_pages`, `dpi`) are still read from `~/.noteker/config/settings.yaml` if you want to override the defaults (see [Configuration](#configuration)).
### From source
**Requirements:** Python 3.11+, macOS
```bash
git clone https://github.com/andras-tkcs/noteker
cd noteker
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
```
Copy and edit the config:
```bash
cp config/settings.yaml.example config/settings.yaml
# Edit config/settings.yaml — add your Anthropic API key
```
Register Noteker with Claude (see [MCP registration](#mcp-registration)) using the path `.venv/bin/noteker`.
---
## Configuration
Config file location:
| Context | Path |
|---------|------|
| Claude Desktop extension | `~/.noteker/config/settings.yaml` |
| From source | `config/settings.yaml` (next to `pyproject.toml`) |
| Override | Set `NOTEKER_CONFIG_DIR` environment variable |
```yaml
anthropic:
# API key from console.anthropic.com → API Keys
# Can also be set via the ANTHROPIC_API_KEY environment variable.
api_key: sk-ant-api03-...
# Model used for transcription.
# claude-sonnet-4-6 is recommended. Use claude-opus-4-8 for very difficult handwriting.
model: claude-sonnet-4-6
noteker:
# Maximum pages to process per PDF (safety cap).
max_pages: 50
# Rendering resolution. 150 DPI works well for most handwriting.
# Increase to 200 if the handwriting is very small.
dpi: 150
logging:
level: INFO
```
### Anthropic API key
Create a key at [console.anthropic.com](https://console.anthropic.com) → **API Keys**. It looks like `sk-ant-api03-...`.
You can set it in `settings.yaml` as shown above, or export it as an environment variable — Noteker checks both:
```bash
export ANTHROPIC_API_KEY=sk-ant-api03-...
```
Adding the export to `~/.zshrc` means you never need it in the config file.
---
## MCP registration
The Claude Desktop extension registers itself — no manual JSON editing needed.
For **Claude Code CLI**, add Noteker to the project's `.claude/settings.json` (the `.mcpb` format doesn't apply to Claude Code, which always uses a direct command path):
```json
{
"mcpServers": {
"noteker": {
"command": "/absolute/path/to/noteker/.venv/bin/noteker"
}
}
}
```
Or, with the API key passed directly instead of via `settings.yaml`:
```json
{
"mcpServers": {
"noteker": {
"command": "/absolute/path/to/noteker/.venv/bin/noteker",
"env": {
"ANTHROPIC_API_KEY": "sk-ant-api03-..."
}
}
}
}
```
After saving the config, restart Claude Code (or reload MCP servers) and run `noteker_status()` to confirm the setup.
---
## Usage
A typical session with both Noteker and [Loopline](https://github.com/andras-tkcs/loopline):
```
# 1. Find the PDF on Google Drive (via loopline)
drive_list_files(query="name contains 'Meeting Notes' and mimeType='application/pdf'")
→ file_id: "1aBcD..."
# 2. Download it locally (via loopline — drive_save_to_path)
drive_save_to_path(file_id="1aBcD...")
→ /Users/you/Downloads/Meeting Notes 2025-06-20.pdf
# 3. Transcribe the handwriting (via noteker)
noteker_process_pdf(
file_path="/Users/you/Downloads/Meeting Notes 2025-06-20.pdf",
note_context="product team standup"
)
→ ## Page 1
### Action items
- Follow up with design on the onboarding flow
...
```
Noteker is source-agnostic — any local PDF works, regardless of how it got there.
---
## Building the .mcpb
```bash
./scripts/build_mcpb.sh
```
Output: `noteker-<version>.mcpb`. The build script creates a virtual environment at `server/venv` with all dependencies installed, so the extension has no runtime dependency on `uv` or `pip`. It still links against the Python 3.13 framework install used to build it, and PyMuPDF ships arch-specific wheels — build on the same OS/CPU architecture (arm64 macOS) you're targeting.
---
## License
Apache 2.0 — see [LICENSE](LICENSE).
TDQS
A4.4/5.0
Scored across 2 tools
Disambiguation5/5
Only two tools with clearly distinct purposes: one processes PDFs into Markdown, the other returns server status. No overlap whatsoever.
Naming Consistency5/5
Both tools use the same prefix 'noteker_' and follow a verb_noun pattern ('process_pdf', 'status'), making naming predictable and consistent.
Tool Count4/5
With only two tools, the server is minimal but well-scoped for its stated purpose of converting handwritten notes from PDFs. Slightly low but reasonable.
Completeness4/5
The core functionality (PDF conversion) is fully covered, and a status tool is provided. Minor gaps like batch processing or format options are absent but not essential.
Maintenance
ActivityStale
ResponsivenessNo issues