lipi-mcp
# lipi-mcp
MCP server for [Lipi](https://github.com/biraj/lipi) — Indic-first notes with romanized Devanagari search (`mero` → `मेरो`, `namaste` → `नमस्ते`) and Bikram Sambat dates. Connect Claude Desktop, Cursor, Codex, or any MCP host to your Lipi vault.
MCP is a thin stdio wrapper over the Lipi API — no data duplication, safe concurrent updates.
## Install — npx / bunx (no global install needed)
```bash
# run directly (always latest)
npx -y lipi-mcp --help
bunx lipi-mcp --help
# or pin version
npx -y lipi-mcp@0.1.0 --api https://lipi-api.bharosilo.com --token <jwt>
```
## Quickstart
1. **Get a token** — sign up at `https://lipi.bharosilo.com`, then copy the JWT from your browser (DevTools → localStorage `accessToken`), or call `POST https://lipi-api.bharosilo.com/v1/auth/login` directly.
3. **Run MCP**:
```bash
# prod (default)
LIPI_ACCESS_TOKEN=<jwt> npx -y lipi-mcp
# or explicit
LIPI_API_URL=https://lipi-api.bharosilo.com LIPI_ACCESS_TOKEN=<jwt> npx -y lipi-mcp
# dev
LIPI_API_URL=http://localhost:8080 LIPI_ACCESS_TOKEN=<jwt> npx -y lipi-mcp
# or
bunx lipi-mcp --api https://lipi-api.bharosilo.com --token <jwt>
```
4. **Configure your MCP host** — `claude_desktop_config.json` (Claude Desktop) or `~/.cursor/mcp.json` (Cursor):
```json
{
"mcpServers": {
"lipi": {
"command": "npx",
"args": ["-y", "lipi-mcp", "--api", "https://lipi-api.bharosilo.com"],
"env": {
"LIPI_ACCESS_TOKEN": "<paste-jwt-here>",
"LIPI_REFRESH_TOKEN": "<optional-refresh-token>"
}
}
}
}
```
For local dev:
```json
{
"mcpServers": {
"lipi": {
"command": "npx",
"args": ["-y", "lipi-mcp", "--api", "http://localhost:8080"],
"env": {
"LIPI_API_URL": "http://localhost:8080",
"LIPI_ACCESS_TOKEN": "<paste-jwt-here>"
}
}
}
}
```
With `bunx`:
```json
{
"mcpServers": {
"lipi": {
"command": "bunx",
"args": ["lipi-mcp", "--api", "https://lipi-api.bharosilo.com"],
"env": { "LIPI_ACCESS_TOKEN": "<jwt>" }
}
}
}
```
Restart the host. You should see 9 tools: `lipi_login`, `lipi_list_notes`, `lipi_read_note`, `lipi_read_note_by_name`, `lipi_create_note`, `lipi_update_note`, `lipi_rename_note`, `lipi_delete_note`, `lipi_search`.
## Tools
| Tool | Maps to | Notes |
|---|---|---|
| `lipi_login` | `POST /v1/auth/login` | Caches token for session; also verifies via `GET /v1/me` |
| `lipi_list_notes` | `GET /v1/notes` / `?tree=1` | Flat `NoteMeta[]` or `NoteTree[]` |
| `lipi_read_note` | `GET /v1/notes/:id` | Full `Note` + ETag |
| `lipi_read_note_by_name` | `GET /v1/notes-by-name?name=` | Wikilink resolver `[[Name]]` |
| `lipi_create_note` | `POST /v1/notes` | Idempotent on `(user_id, path)` |
| `lipi_update_note` | `PUT /v1/notes/:id` + `If-Match` | Requires `ifMatch` = `updatedAt` (RFC3339Nano); 409 on stale |
| `lipi_rename_note` | `PATCH /v1/notes/:id` | 409 if path taken |
| `lipi_delete_note` | `DELETE /v1/notes/:id` | 204 → `{deleted:true}` |
| `lipi_search` | `GET /v1/search?q=` | Romanized: `mero` → `मेरो` (+2 exact / +1 prefix) |
Auth: `Authorization: Bearer <jwt>` + `Cookie: lipi_refresh=<token>` (auto refresh on 401 → retry once).
## Env / Flags
| Flag / Env | Default | Description |
|---|---|---|
| `--api` / `LIPI_API_URL` | `https://lipi-api.bharosilo.com` | Lipi API base URL (`http://localhost:8080` for dev) |
| `--token` / `LIPI_ACCESS_TOKEN` | — | JWT (15m) |
| `--refresh` / `LIPI_REFRESH_TOKEN` | — | Opaque refresh (30d), HttpOnly `lipi_refresh` at rest |
## Dev
```bash
bun install
bun run build
node dist/index.js --help
# inspect with MCP Inspector
npx @modelcontextprotocol/inspector node dist/index.js
```
## Publish
```bash
bun run build
npm publish --access public
# then users can npx -y lipi-mcp@latest
```
TDQS
Scored across 9 tools
Each tool maps to a distinct action/resource pair: create, read, update, rename, delete, list, search, and login are clearly separated. The only mild overlap is between lipi_read_note and lipi_read_note_by_name, but their id-vs-name distinction is described well enough to avoid real confusion.
All tools share the lipi_ prefix and mostly follow a verb_noun pattern like lipi_create_note and lipi_delete_note. lipi_login and lipi_search are verb-only exceptions, but the overall style remains predictable and uniform.
Nine tools is a well-scoped set for a note management server: authentication, CRUD, renaming, listing, and search are all covered without unnecessary duplication. Each tool earns its place.
The tool surface covers the full note lifecycle: create, read by id, read by name, update with optimistic concurrency, rename/move, delete, list, and search. Auth is handled via lipi_login, and no obvious dead-end operations are missing for the stated domain.