restyle-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ # Copy to .env for local runs (FastMCP/anthropic read the env).
2
+ ANTHROPIC_API_KEY=sk-ant-...
3
+ VOICE_INDEX=./rag_index.pkl
4
+ VOICE_MODEL=claude-haiku-4-5-20251001
5
+ VOICE_K=6
6
+ MCP_TRANSPORT=stdio
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .env
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .DS_Store
9
+
10
+ # private data — NEVER commit. The RAG index is built from real
11
+ # correspondence and lives on a Railway volume, not in git.
12
+ *.pkl
13
+ rag_index*
14
+ corpora/
15
+ *.jsonl
@@ -0,0 +1,26 @@
1
+ FROM python:3.13-slim
2
+
3
+ RUN apt-get update && apt-get install -y --no-install-recommends \
4
+ ca-certificates \
5
+ && rm -rf /var/lib/apt/lists/*
6
+
7
+ COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
8
+
9
+ WORKDIR /app
10
+ COPY pyproject.toml ./
11
+ COPY voice_mcp ./voice_mcp
12
+ RUN uv sync
13
+
14
+ # Bake the embedding model into the image so the first call doesn't have to
15
+ # download it (and so it works offline).
16
+ RUN uv run python -c "from fastembed import TextEmbedding; TextEmbedding('BAAI/bge-small-en-v1.5')"
17
+
18
+ # The private RAG index lives on a Railway volume mounted at /data and is
19
+ # uploaded out-of-band (never in git): build locally with `voice-mcp-index
20
+ # build ~/voice-corpora`, then push rag_index.pkl to the volume.
21
+ ENV VOICE_INDEX=/data/rag_index.pkl
22
+ ENV MCP_TRANSPORT=http
23
+ ENV PORT=8000
24
+ EXPOSE 8000
25
+
26
+ CMD ["uv", "run", "voice-mcp"]
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: restyle-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server that restyles a draft into your own voice (runtime persona + local RAG exemplars + deterministic stripper). Style only, never content. One tool: restyle_as_me.
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: anthropic[vertex]>=0.40
7
+ Requires-Dist: fastembed>=0.4
8
+ Requires-Dist: fastmcp>=3.0.2
9
+ Requires-Dist: numpy>=1.26
@@ -0,0 +1,50 @@
1
+ # voice-mcp
2
+
3
+ An MCP server that restyles a draft into **Peter's voice** — and *only*
4
+ the style. One tool:
5
+
6
+ restyle_as_me(text, channel?) -> styled
7
+
8
+ Composition (the facts) stays with the calling model; this tool re-voices
9
+ a draft it already wrote, and **returns** the result so Peter reviews
10
+ before sending (review = send). It never changes content.
11
+
12
+ Design + rationale: `voice/plans/004-voice-mcp-restyle-tool.md`.
13
+
14
+ ## Pipeline
15
+
16
+ 1. **RAG** (`rag.py`) — cheap local fastembed (`BAAI/bge-small-en-v1.5`,
17
+ ONNX, CPU) over the *clean* corpus; cosine top-k, same-channel bonus.
18
+ Indexed on Peter's replies, queried with the draft: "past messages of
19
+ yours most like this one."
20
+ 2. **persona** (`persona.md`) — semicolons, terse, warm, first-name, no
21
+ sign-offs, **never em-dashes**; `{EXEMPLARS}` filled from RAG.
22
+ 3. **Haiku** rewrite (style only).
23
+ 4. **stripper** (`stripper.py`) — deterministic safety net: any leaked
24
+ em-dash -> semicolon; drop corporate sign-offs.
25
+
26
+ ## Build the index (local; never committed)
27
+
28
+ The index is built from `~/voice-corpora` (private correspondence) and
29
+ filters contamination (em-dash rows, automated/forwarded junk):
30
+
31
+ uv run voice-mcp-index build ~/voice-corpora ./rag_index.pkl
32
+ uv run voice-mcp-index query ./rag_index.pkl "got it will sign today" --channel email
33
+
34
+ For prod, upload `rag_index.pkl` to the Railway volume at
35
+ `/data/rag_index.pkl` (off GitHub — your data, your box).
36
+
37
+ ## Run
38
+
39
+ MCP_TRANSPORT=stdio uv run voice-mcp # local stdio
40
+ uv run voice-mcp # http on :8000
41
+
42
+ Needs `ANTHROPIC_API_KEY`. `VOICE_INDEX` points at the index
43
+ (`/data/rag_index.pkl` in prod).
44
+
45
+ ## Deploy
46
+
47
+ First-class `voice` server on **mcp.danenberg.ai** (the personal gateway),
48
+ next to gmail/imessage/whatsapp/linkedin/zep. Railway service + a volume at
49
+ `/data`; wire into the gateway `servers.json` + `shim-configs/`. Code lives
50
+ in a **private** git repo; the index never does.
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "restyle-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server that restyles a draft into your own voice (runtime persona + local RAG exemplars + deterministic stripper). Style only, never content. One tool: restyle_as_me."
9
+ requires-python = ">=3.11"
10
+ dependencies = [
11
+ "fastmcp>=3.0.2",
12
+ "anthropic[vertex]>=0.40",
13
+ "fastembed>=0.4",
14
+ "numpy>=1.26",
15
+ ]
16
+
17
+ [project.scripts]
18
+ voice-mcp = "voice_mcp:main"
19
+ voice-mcp-index = "voice_mcp.rag:main"
20
+
21
+ [tool.hatch.build.targets.wheel]
22
+ packages = ["voice_mcp"]
@@ -0,0 +1,13 @@
1
+ [build]
2
+ builder = "dockerfile"
3
+
4
+ [deploy]
5
+ startCommand = "uv run voice-mcp"
6
+ restartPolicyType = "always"
7
+
8
+ # Set in the Railway service:
9
+ # VOICE_INDEX=/data/rag_index.pkl (mount a volume at /data; upload the index there)
10
+ # ANTHROPIC_API_KEY=... (for the Haiku restyle call)
11
+ # VOICE_MODEL=claude-haiku-4-5-20251001 (optional override)
12
+ # VOICE_K=6 (optional; exemplars per call)
13
+ # MCP_TRANSPORT=http (default)