These instructions are for AI assistants working in this project.
Always open @/openspec/AGENTS.md when the request:
- Mentions planning or proposals (words like proposal, spec, change, plan)
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
- Sounds ambiguous and you need the authoritative spec before coding
Use @/openspec/AGENTS.md to learn:
- How to create and apply change proposals
- Spec format and conventions
- Project structure and guidelines
Keep this managed block so 'openspec update' can refresh the instructions.
Sanskrit Upaya ("Sanskrit Method/Tool") is a cross-platform Sanskrit dictionary desktop application built in Go. It provides fast full-text search across 36 digitized Sanskrit dictionaries from the Cologne Digital Sanskrit Dictionaries project.
Repository: github.com/licht1stein/sanskrit-upaya
sanskrit-upaya/
βββ cmd/
β βββ desktop/ # Fyne UI application
β β βββ main.go # Main app with UI, search, state management
β β βββ bundled.go # SVG icons (star, star-filled)
β βββ indexer/main.go # One-time tool to build SQLite DB from JSON
β βββ mcp/main.go # MCP server for LLM integration
βββ pkg/
β βββ dictdata/ # Embedded dictionary metadata JSON
β βββ download/ # First-run database download from server
β βββ ocr/ # Google Cloud Vision OCR for Sanskrit/Devanagari
β βββ gcloud/ # Google Cloud CLI utilities (shared between desktop and MCP)
β βββ search/search.go # SQLite FTS5 search engine + dict filtering
β βββ state/state.go # User settings, history, starred articles (SQLite)
β βββ transliterate/ # IAST β SLP1 β Devanagari conversion
βββ .github/workflows/ # GitHub Actions for cross-platform builds
βββ sanskrit.db # Pre-built FTS5 database (generated, ~670MB) - NOT in repo
βββ shell.nix # Nix development environment
βββ go.mod
The dictionary database (~670MB) is NOT bundled with the binary. On first run:
- App checks for
~/.local/share/sanskrit-dictionary/sanskrit.db - If missing, shows download dialog with progress bar
- Downloads from
https://sanskrit.myke.blog/dict.dbwith secret header - Saves to data directory
Server setup (nginx on sanskrit.myke.blog):
- Database file:
/mnt/photos/sanskrit.db - Protected by header:
X-Sanskrit-Mitra: mitra-2024-sanskrit-app - Without header: 403 Forbidden
pkg/download/download.go handles the download logic with progress callback.
- 4 Search Modes: Exact, Prefix, Contains (fuzzy), Full-text (reverse)
- Dictionary Selection: Filter search by dictionary, grouped by language direction (saβen, saβde, etc.)
- Starred Articles: Save favorite articles with star/unstar functionality
- Search History: Track and recall previous searches
- Result Grouping: Toggle between grouped (by word) and ungrouped views
- Zoom Control: 50%-200% UI scaling with Ctrl/Cmd +/-
- Keyboard Navigation: Arrow keys to navigate results, Ctrl/Cmd+K to focus search
- Transliteration: Auto-converts between IAST and Devanagari for search
- OCR Support: Recognize Sanskrit/Devanagari text from images (PNG, JPG, TIFF, PDF) via Google Cloud Vision
- MCP Server: LLM integration via Model Context Protocol for Claude Code and other MCP clients
- SQLite FTS5 for search - O(log n) indexed lookups vs O(n) regex scanning
- Pure Go SQLite - Uses
modernc.org/sqlite(no CGO required) - Fyne for UI - Cross-platform GUI (Windows, macOS, Linux, Android, iOS)
- Separate state DB - User settings stored in
~/.local/share/sanskrit-dictionary/state.db - BreakVer versioning - See https://www.taoensso.com/break-versioning
# First time: download dependencies
go mod tidy
# Build the search database (only needed once)
# Dictionary JSON files from: https://github.com/ashtadhyayi-com/data
go run ./cmd/indexer -input /path/to/csl-json/ashtadhyayi.com/ -output sanskrit.db
# Run desktop app
go run ./cmd/desktop
# Build release binary
go build -o sanskrit-upaya ./cmd/desktop
# Build MCP server
go build -o sanskrit-mcp ./cmd/mcpThe desktop app includes OCR functionality for recognizing Sanskrit/Devanagari text from images.
- Click the OCR button in the toolbar (or press Ctrl/Cmd+O)
- If first time, complete the setup wizard (requires Google Cloud CLI)
- Drop an image file (PNG, JPG, TIFF, PDF) onto the window
- View and edit the recognized text
- Click Search to look up recognized words in the dictionary
The desktop app includes a setup wizard that guides you through:
- Installing Google Cloud CLI (if not present)
- Authenticating with your Google account
- Creating a GCP project for Vision API
- Enabling the Vision API
- Setting up Application Default Credentials
Free tier: 1000 images/month, then $1.50/1000.
- Ctrl/Cmd+O: Open OCR window
The MCP (Model Context Protocol) server enables LLMs like Claude to search Sanskrit dictionaries directly. It runs as a stdio-based server communicating via JSON-RPC 2.0.
Add to your Claude Code MCP settings (~/.config/claude/claude_desktop_config.json or similar):
{
"mcpServers": {
"sanskrit": {
"command": "/path/to/sanskrit-mcp"
}
}
}| Tool | Description |
|---|---|
sanskrit_search |
Search dictionaries with 4 modes: exact, prefix, fuzzy, reverse |
sanskrit_list_dictionaries |
List all 36 dictionaries with descriptions |
sanskrit_get_article |
Retrieve full article content by ID |
sanskrit_transliterate |
Convert between IAST and Devanagari |
sanskrit_ocr |
OCR Sanskrit/Devanagari text from images (requires GCP setup) |
- "Search for 'yoga' in Monier-Williams dictionary"
- "What does 'dharma' mean? Search in exact mode"
- "Transliterate 'namaste' to Devanagari"
- "List available Sanskrit dictionaries"
- "OCR this Sanskrit manuscript image"
The sanskrit_ocr tool requires Google Cloud Vision API credentials. Run the setup command:
sanskrit-mcp ocr-setupThis will:
- Check/install gcloud CLI authentication
- Create a GCP project
sanskrit-upaya-ocr - Enable Vision API
- Configure Application Default Credentials
Free tier: 1000 images/month, then $1.50/1000.
The MCP server requires the dictionary database at ~/.local/share/sanskrit-dictionary/sanskrit.db. Run the desktop app first to download it, or place the database manually.
nix-shell # Enter dev environment with all dependencies
go run ./cmd/desktopReleases are built automatically via GitHub Actions on tag push.
Uses BreakVer: v<major>.<minor>.<non-breaking>
- Major: Breaking changes (rare, signals major overhaul)
- Minor: May contain breaking changes (read changelog)
- Non-breaking: Bug fixes, safe updates (always safe to upgrade)
# Create and push a tag
git tag v1.0.0
git push origin v1.0.0GitHub Actions will automatically:
- Build binaries for Linux (amd64), Windows (amd64), macOS (Intel), macOS (Apple Silicon)
- Create a GitHub Release with all artifacts
- Generate release notes from commits
You can manually trigger the workflow from GitHub Actions UI (workflow_dispatch) to test builds without creating a release.
Binary names include the version tag (e.g., for v1.0.0):
sanskrit-upaya-v1.0.0-linux-amd64- Linux x86_64sanskrit-upaya-v1.0.0-windows-amd64.exe- Windows x86_64sanskrit-upaya-v1.0.0-macos-intel- macOS Intel (x86_64)sanskrit-upaya-v1.0.0-macos-apple-silicon- macOS Apple Silicon (arm64)
When updating the dictionary database on the server:
- Upload new database to server
- Get SHA256 checksum:
sha256sum /path/to/sanskrit.db - Update
ExpectedChecksuminpkg/download/download.go - Create new release - users will auto-download on next app start
-- Main search database (sanskrit.db)
dicts(code, name, from_lang, to_lang, favorite)
articles(id, dict_code, content)
words(id, word_iast, word_deva, article_id, dict_code)
words_fts(word_iast, word_deva) -- FTS5 virtual table
articles_fts(content) -- FTS5 virtual table
-- User state database (~/.local/share/sanskrit-dictionary/state.db)
settings(key, value) -- Key-value store (zoom, selected_dicts, etc.)
history(id, query, count, last_used) -- Search history
starred(id, article_id, word, dict_code, created_at) -- Starred articlesscaledTheme- Custom theme wrapper for zoom functionalityGroupedResult/DictEntry- Data structures for result groupingpillLabel- Custom widget for dictionary code badgescreateArticleContent()- Renders article with search term highlightingdoSearch()- Main search function with background goroutinenavigateTo()- Displays selected result with star button- Dialog builders for: History, Starred Articles, Dictionary Selection
OCRWindow- Separate window for OCR functionality- Drop zone UI with drag-and-drop support
- Processing state with spinner and cancel
- Result editor with copy/search integration
- File validation (extension, size limits)
OCRSetupWizard- GUI wizard for Google Cloud setup- Step-by-step progress through: auth β project β API β ADC
- Real-time command output streaming
- Error handling with re-run capability
- Billing setup integration
Search(query, mode, dictCodes)- Main search with optional dict filteringGetDicts()- Returns all dictionary metadataGetArticle(id)- Retrieves single article (for starred view)- Supports 4 search modes: ModeExact, ModePrefix, ModeFuzzy, ModeReverse
Get/Set/GetBool/SetBool- Key-value settingsAddHistory/SearchHistory/GetRecentHistory- Search historyStarArticle/UnstarArticle/IsStarred/GetStarredArticles- Starring
IASTToDevanagari()/DevanagariToIAST()ToSearchTerms()- Returns both IAST and Devanagari variants for searchIsDevanagari()- Detects script type
- MCP server using
github.com/modelcontextprotocol/go-sdk/mcp - 5 tools:
sanskrit_search,sanskrit_list_dictionaries,sanskrit_get_article,sanskrit_transliterate,sanskrit_ocr ocr-setupsubcommand for automated Google Cloud setup- Lazy database initialization (checks on first tool call)
- Embedded dictionary descriptions from
pkg/dictdata/dictionaries.json
- Google Cloud Vision API client wrapper
NewClient(ctx)- Creates client using Application Default CredentialsRecognizeText/RecognizeFile/RecognizeBase64- OCR methodsCheckCredentials(ctx)- Verifies API access- Image format validation (PNG, JPG, TIFF, PDF) via magic bytes
- 30-second timeout, 20MB size limit
- Shared Google Cloud CLI utilities
IsInstalled(),IsAuthenticated()- CLI status checksHasApplicationDefaultCredentials()- ADC checkGetOrCreateOCRProjectID()- Persistent project ID managementRunCommand(),RunCommandAsync()- Command execution with output streamingOpenBrowser()- Platform-specific browser opening
- GitHub Actions workflow for cross-platform releases
- Database checksum verification and auto-redownload
- Theme switching (light/dark/system)
- Devanagari virtual keyboard
- Mobile builds with bundled database
- Export starred articles
- Dictionary info/about dialog
Dictionary data from Cologne Digital Sanskrit Dictionaries:
- 36 dictionaries
- ~1.3M words
- ~1.3M articles
- JSON format from ashtadhyayi.com
- Database uses WAL mode and mmap for fast reads
- Bulk indexing: ~44 seconds for 1.3M words
- Database size: ~670MB
- Queries limited to 1000 results
- First search may be slow (memory mapping), subsequent searches are fast
fyne.io/fyne/v2- Cross-platform UI frameworkmodernc.org/sqlite- Pure Go SQLitegithub.com/modelcontextprotocol/go-sdk/mcp- MCP server SDK (for cmd/mcp)cloud.google.com/go/vision/v2- Google Cloud Vision API (for OCR)
- "Database not loaded" - Run indexer first to create
sanskrit.db - Devanagari not rendering - Install Noto Sans Devanagari font
- Slow first search - Normal, database is memory-mapped on first access
- Always build ./sanskrit locally