Metadata-Version: 2.5
Name: monika-mcp
Version: 0.1.1
Summary: Authenticated MCP access to local MoniKa chat databases and a multi-instance router
Project-URL: Homepage, https://github.com/maxswjeon/MoniKa
Project-URL: Repository, https://github.com/maxswjeon/MoniKa
Project-URL: Issues, https://github.com/maxswjeon/MoniKa/issues
License-Expression: MIT
Requires-Python: >=3.11
Requires-Dist: mcp>=2.0.0
Requires-Dist: sqlcipher3>=0.6.2
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == 'test'
Description-Content-Type: text/markdown

# MoniKa MCP

This directory provides two authenticated Streamable HTTP MCP services:

- `monika-mcp`: lists chatroom databases, reports session/account and DEK availability, reads bounded decrypted message rows, and checks for messages after a Unix timestamp.
- `monika-mcp-router`: concurrently probes several instances and routes an allow-listed read tool to a named instance.

Raw DEKs never appear in MCP responses. Both services require the `monika:read` bearer-token scope. They bind to loopback by default; use a TLS reverse proxy for remote access. Plain HTTP instance URLs are rejected except on loopback.

`instance_status` discloses the 40-hex Kakao profile-directory identifier as `profile_id` and the distinct 32-hex `hashed_talk_user_id` when the process scan confirms a signed-in session. Cached identity survives logout, so `account` is deliberately `null` for signed-out, interstitial, candidate, and unknown states. The response includes `observed_at` so callers can judge freshness.

## Install

Install the released package from PyPI:

```powershell
uv tool install monika-mcp
monika-mcp
```

Run the router instead with `monika-mcp-router`. To work from a source checkout:

```powershell
uv sync --all-packages
uv run --package monika-mcp monika-mcp
```

Create an opaque token, then configure its SHA-256 digest (not the token itself):

```powershell
$token = python -c "import secrets; print(secrets.token_urlsafe(32))"
$digest = python -c "import hashlib,sys; print(hashlib.sha256(sys.argv[1].encode()).hexdigest())" $token
$env:MONIKA_MCP_TOKENS_JSON = '{"' + $digest + '":{"client_id":"local-client","scopes":["monika:read"],"expires_at":1893456000}}'
```

For an instance, set `MONIKA_USER_DIR` and `MONIKA_MCP_ISSUER_URL`; optionally set `MONIKA_CACHE_DB` and `MONIKA_MCP_PUBLIC_URL`, then run `monika-mcp`. The issuer is mandatory so a deployment cannot accidentally advertise a fake authorization server.

For the router, copy `instances.example.json` outside the repository, restrict its filesystem ACL because it contains upstream bearer tokens, set `MONIKA_MCP_INSTANCES` to that path, and run `monika-mcp-router`. Router callers use a separate token configured through `MONIKA_MCP_TOKENS_JSON`.

For private remote access, follow the [recommended tailnet router deployment](DEPLOYMENT.md). The preferred layout keeps the router on loopback behind Tailscale Serve. Direct binding to the current Tailscale IPv4 is also available by setting `MONIKA_ROUTER_HOST=tailnet`; it requires the Tailscale CLI and does not provide TLS by itself.

Maintainers: see [`PUBLISHING.md`](PUBLISHING.md) for the PyPI Trusted Publishing setup and release procedure.

The included opaque-token verifier is suitable for a small private deployment when tokens are generated randomly, scoped, short-lived, and distributed securely. For centrally managed deployments, replace it with JWT signature/audience validation or RFC 7662 introspection against your OAuth 2.1 authorization server. Configure real issuer/resource URLs and terminate TLS at a trusted reverse proxy. Do not expose either default loopback HTTP port directly.
