Metadata-Version: 2.4
Name: plintho-mcp
Version: 0.2.0
Summary: MCP server + CLI for the plintho voice journal
Author: vtech-ai
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://plintho.app
Keywords: mcp,voice-journal,plintho
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: mcp>=1.0
Requires-Dist: httpx>=0.27

# plintho-mcp

A small CLI + [MCP](https://modelcontextprotocol.io) server that lets any
MCP-capable client (Claude Desktop, Cursor, Cline, Zed, …) query the
plintho voice-journal backend on behalf of a single user.

## Install

```bash
pipx install plintho-mcp          # recommended
pip  install plintho-mcp          # alternative
```

Or from source:

```bash
git clone https://github.com/vtech-ai/plintho-mcp.git
cd plintho-mcp
pipx install -e .
```

Requires Python 3.11+. Runtime deps: `mcp`, `httpx`. The package does
**not** pull in any of the plintho backend's heavy dependencies.

## Pair this device with your account

```bash
$ plintho-mcp login --name "MacBook Cursor"
配对码: WXYZ-2345
请在 plintho iOS app → Settings → MCP Access 输入此码
等待中...
✓ 已登录为 user-abc
```

The token is saved to `~/.plintho/mcp_token` (mode 600). The plaintext
exists only on this machine; the server stores only its sha256 hash.

## Wire into your MCP client

### Claude Desktop — `claude_desktop_config.json`

```json
{
  "mcpServers": {
    "plintho": { "command": "plintho-mcp" }
  }
}
```

### Claude Code

```bash
claude mcp add plintho -- plintho-mcp
```

### Cursor — `~/.cursor/mcp.json`

```json
{
  "mcpServers": {
    "plintho": { "command": "plintho-mcp" }
  }
}
```

Same `command` key works for Cline / Zed / Continue / any stdio-MCP client.

## Tools exposed

| Tool                   | What it does                                                            |
| ---------------------- | ----------------------------------------------------------------------- |
| `list_events_by_date`  | All events on a given date (YYYY-MM-DD or `today`/`yesterday`).         |
| `get_event_detail`     | One event's note (Markdown) + raw utterances.                           |
| `search_events`        | Free-text search across event titles/summaries/notes, optional date.    |
| `search_utterances`    | Substring search across raw transcribed utterances.                     |
| `get_daily_summary`    | Daily summary (日报) for a given date.                                   |

All tools are scoped to the user the token was issued to — there is no
`user_id` parameter and the server enforces ownership on every call.

## Collect local chat transcripts

`plintho-mcp collect` ships your Claude Code (`~/.claude/projects`) and
OpenClaw (`~/.openclaw/agents`) conversations to your plintho account so
they show up as chat events next to your voice notes. Only `text` blocks
are uploaded — tool calls, tool results and thinking stay on your machine.

```bash
plintho-mcp collect                    # one incremental run (same as `collect run`)
plintho-mcp collect --dry-run          # parse only, print what would upload
plintho-mcp collect install            # macOS: launchd job every 5 min
plintho-mcp collect status             # heartbeat + launchd last exit code
plintho-mcp collect uninstall
```

It reuses the token from `plintho-mcp login`; the server binds every
message to that token's owner, so there is no `--user-id` to get wrong.

Progress is tracked per file in `~/.plintho/collector_state.json` (the
first run imports offsets from the retired vmate `~/.vmate/chat_collector_state.json`
if present). Each run writes `~/.plintho/collector_last_run.json`;
`collect status` exits non-zero when the last run failed, the launchd job
last exited non-zero, or the heartbeat is stale.

The launchd plist points at the absolute path of the installed
`plintho-mcp` binary, so the job keeps working regardless of shell PATH
or which Python environments come and go.

Optional — upload a session the moment it ends via a Claude Code
`SessionEnd` hook (launchd still catches anything missed):

```json
{ "hooks": { "SessionEnd": [ { "hooks": [
  { "type": "command", "command": "plintho-mcp collect --file \"$transcript_path\"" }
] } ] } }
```

Cloud sessions (claude.ai/code) don't write to `~/.claude/projects` and
are not collected.

## Other commands

```bash
plintho-mcp whoami             # show current user_id / token name
plintho-mcp logout             # delete the local token file
plintho-mcp login --force      # re-pair (replaces existing token locally)
```

To revoke a token server-side, use the iOS app → Settings → MCP Access.

## Environment variables

| Var                | Default                       | Purpose                          |
| ------------------ | ----------------------------- | -------------------------------- |
| `PLINTHO_API_BASE` | `https://api.plintho.app`     | Backend URL.                     |
| `PLINTHO_HOME`     | `~/.plintho`                  | Token + config directory.        |
