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.
- restyle_mcp-0.1.0/.env.example +6 -0
- restyle_mcp-0.1.0/.gitignore +15 -0
- restyle_mcp-0.1.0/Dockerfile +26 -0
- restyle_mcp-0.1.0/PKG-INFO +9 -0
- restyle_mcp-0.1.0/README.md +50 -0
- restyle_mcp-0.1.0/pyproject.toml +22 -0
- restyle_mcp-0.1.0/railway.toml +13 -0
- restyle_mcp-0.1.0/uv.lock +2263 -0
- restyle_mcp-0.1.0/voice_mcp/__init__.py +106 -0
- restyle_mcp-0.1.0/voice_mcp/persona.md +22 -0
- restyle_mcp-0.1.0/voice_mcp/rag.py +108 -0
- restyle_mcp-0.1.0/voice_mcp/stripper.py +26 -0
|
@@ -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)
|