claude-phone-local 2.0.0
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.
- package/.env.example +108 -0
- package/Dockerfile +84 -0
- package/LICENSE +22 -0
- package/README.md +231 -0
- package/claude-api-server/package-lock.json +832 -0
- package/claude-api-server/package.json +20 -0
- package/claude-api-server/server.js +540 -0
- package/claude-api-server/structured.js +208 -0
- package/cli/README.md +231 -0
- package/cli/bin/check-publish-safety.js +53 -0
- package/cli/bin/claude-phone.js +23 -0
- package/cli/bin/cli-main.js +284 -0
- package/cli/bin/postinstall.js +20 -0
- package/cli/lib/commands/api-server.js +77 -0
- package/cli/lib/commands/backup.js +69 -0
- package/cli/lib/commands/config/path.js +30 -0
- package/cli/lib/commands/config/reset.js +73 -0
- package/cli/lib/commands/config/show.js +86 -0
- package/cli/lib/commands/device/add.js +143 -0
- package/cli/lib/commands/device/list.js +55 -0
- package/cli/lib/commands/device/remove.js +83 -0
- package/cli/lib/commands/doctor.js +422 -0
- package/cli/lib/commands/logs.js +186 -0
- package/cli/lib/commands/restore.js +172 -0
- package/cli/lib/commands/setup.js +1246 -0
- package/cli/lib/commands/start.js +346 -0
- package/cli/lib/commands/status.js +139 -0
- package/cli/lib/commands/stop.js +101 -0
- package/cli/lib/commands/uninstall.js +183 -0
- package/cli/lib/commands/update.js +205 -0
- package/cli/lib/config.js +113 -0
- package/cli/lib/docker.js +384 -0
- package/cli/lib/mcp-register.js +108 -0
- package/cli/lib/network.js +109 -0
- package/cli/lib/platform.js +85 -0
- package/cli/lib/port-check.js +135 -0
- package/cli/lib/prereqs/checks/compose.js +147 -0
- package/cli/lib/prereqs/checks/disk.js +89 -0
- package/cli/lib/prereqs/checks/docker.js +155 -0
- package/cli/lib/prereqs/checks/network.js +78 -0
- package/cli/lib/prereqs/checks/node.js +95 -0
- package/cli/lib/prereqs/installers/docker-desktop.js +248 -0
- package/cli/lib/prereqs/installers/docker.js +229 -0
- package/cli/lib/prereqs/installers/node.js +254 -0
- package/cli/lib/prereqs/platform.js +175 -0
- package/cli/lib/prereqs/utils/execute.js +208 -0
- package/cli/lib/prereqs/utils/rollback.js +223 -0
- package/cli/lib/prereqs/utils/sudo.js +177 -0
- package/cli/lib/prereqs.js +228 -0
- package/cli/lib/prerequisites.js +115 -0
- package/cli/lib/process-manager.js +176 -0
- package/cli/lib/utils.js +78 -0
- package/cli/lib/validators.js +219 -0
- package/cli/lib/voice-downloader.js +79 -0
- package/docker/entrypoint.sh +110 -0
- package/docker/supervisord.conf +78 -0
- package/docker-compose.yml +40 -0
- package/docs/CLAUDE-CODE-SKILL.md +45 -0
- package/docs/LANGUAGES.md +113 -0
- package/docs/MCP-SERVER.md +111 -0
- package/docs/TROUBLESHOOTING.md +288 -0
- package/mcp-server/index.js +159 -0
- package/mcp-server/package-lock.json +1201 -0
- package/mcp-server/package.json +9 -0
- package/package.json +73 -0
- package/stt-local/Dockerfile +12 -0
- package/stt-local/server.py +45 -0
- package/tts-local/Dockerfile +9 -0
- package/tts-local/server.py +83 -0
- package/voice-app/API-QUERY-CONTRACT.md +238 -0
- package/voice-app/DEPLOYMENT.md +176 -0
- package/voice-app/Dockerfile +20 -0
- package/voice-app/README-OUTBOUND.md +316 -0
- package/voice-app/config/devices.json.example +18 -0
- package/voice-app/index.js +273 -0
- package/voice-app/lib/audio-fork.js +465 -0
- package/voice-app/lib/claude-bridge.js +113 -0
- package/voice-app/lib/connection-retry.js +58 -0
- package/voice-app/lib/conversation-loop.js +490 -0
- package/voice-app/lib/device-registry.js +171 -0
- package/voice-app/lib/http-server.js +242 -0
- package/voice-app/lib/logger.js +35 -0
- package/voice-app/lib/multi-registrar.js +133 -0
- package/voice-app/lib/outbound-handler.js +299 -0
- package/voice-app/lib/outbound-routes.js +417 -0
- package/voice-app/lib/outbound-session.js +324 -0
- package/voice-app/lib/query-routes.js +484 -0
- package/voice-app/lib/registrar.js +144 -0
- package/voice-app/lib/sip-handler.js +490 -0
- package/voice-app/lib/tts-service.js +205 -0
- package/voice-app/lib/whisper-client.js +140 -0
- package/voice-app/package.json +38 -0
- package/voice-app/static/gotit-beep.wav +0 -0
- package/voice-app/static/hold-music.wav +0 -0
- package/voice-app/static/ready-beep.wav +0 -0
- package/voice-app/test/freeswitch-retry.test.js +100 -0
package/.env.example
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# ====================================
|
|
2
|
+
# Claude Phone Configuration
|
|
3
|
+
# ====================================
|
|
4
|
+
# Copy this to .env and fill in your values
|
|
5
|
+
|
|
6
|
+
# ====================================
|
|
7
|
+
# Network Configuration
|
|
8
|
+
# ====================================
|
|
9
|
+
|
|
10
|
+
# Your server's LAN IP (CRITICAL for RTP audio)
|
|
11
|
+
# This IP goes into SDP packets so 3CX knows where to send audio
|
|
12
|
+
EXTERNAL_IP=10.0.0.100
|
|
13
|
+
|
|
14
|
+
# ====================================
|
|
15
|
+
# Drachtio Configuration
|
|
16
|
+
# ====================================
|
|
17
|
+
|
|
18
|
+
DRACHTIO_HOST=127.0.0.1
|
|
19
|
+
DRACHTIO_PORT=9022
|
|
20
|
+
DRACHTIO_SECRET=cymru
|
|
21
|
+
|
|
22
|
+
# SIP port for Contact header (5070 for 3CX SBC mode, 5060 for direct registration)
|
|
23
|
+
# This MUST match the port in docker-compose.yml drachtio command
|
|
24
|
+
DRACHTIO_SIP_PORT=5060
|
|
25
|
+
|
|
26
|
+
# ====================================
|
|
27
|
+
# FreeSWITCH Configuration
|
|
28
|
+
# ====================================
|
|
29
|
+
|
|
30
|
+
FREESWITCH_HOST=127.0.0.1
|
|
31
|
+
FREESWITCH_PORT=8021
|
|
32
|
+
FREESWITCH_SECRET=JambonzR0ck$
|
|
33
|
+
|
|
34
|
+
# ====================================
|
|
35
|
+
# 3CX / SIP Configuration
|
|
36
|
+
# ====================================
|
|
37
|
+
|
|
38
|
+
# Your 3CX server hostname or IP
|
|
39
|
+
SIP_DOMAIN=your-3cx-server.3cx.us
|
|
40
|
+
SIP_REGISTRAR=10.0.0.50
|
|
41
|
+
|
|
42
|
+
# Default extension for outbound calls
|
|
43
|
+
SIP_EXTENSION=9000
|
|
44
|
+
SIP_AUTH_ID=your-auth-id
|
|
45
|
+
SIP_PASSWORD=your-password
|
|
46
|
+
|
|
47
|
+
# Default caller ID for outbound PSTN calls
|
|
48
|
+
DEFAULT_CALLER_ID=+15551234567
|
|
49
|
+
|
|
50
|
+
# ====================================
|
|
51
|
+
# Claude API Server
|
|
52
|
+
# ====================================
|
|
53
|
+
|
|
54
|
+
# URL to your Claude API server (runs on your API server with Claude Max)
|
|
55
|
+
CLAUDE_API_URL=http://10.0.0.200:3333
|
|
56
|
+
|
|
57
|
+
# ====================================
|
|
58
|
+
# Speech-to-text / Text-to-speech mode
|
|
59
|
+
# ====================================
|
|
60
|
+
# "local" = faster-whisper + Piper, run as Docker containers here, no API keys
|
|
61
|
+
# "cloud" = original ElevenLabs (TTS) + OpenAI (STT), requires paid API keys
|
|
62
|
+
|
|
63
|
+
STT_MODE=local
|
|
64
|
+
TTS_MODE=local
|
|
65
|
+
|
|
66
|
+
# ---- local mode settings ----
|
|
67
|
+
# These use Docker service names (bridge network) — correct default for
|
|
68
|
+
# Docker Desktop on Windows. Only change to 127.0.0.1 if you switch to a
|
|
69
|
+
# native Linux Docker engine with network_mode: host.
|
|
70
|
+
STT_LOCAL_URL=http://stt-local:9001
|
|
71
|
+
TTS_LOCAL_URL=http://tts-local:9002
|
|
72
|
+
AUDIO_BASE_URL=http://voice-app:3000
|
|
73
|
+
PIPER_VOICE=en_US-lessac-medium
|
|
74
|
+
WHISPER_MODEL=small
|
|
75
|
+
|
|
76
|
+
# ---- cloud mode settings (only needed if STT_MODE/TTS_MODE=cloud) ----
|
|
77
|
+
# ELEVENLABS_API_KEY=your-elevenlabs-api-key
|
|
78
|
+
# ELEVENLABS_VOICE_ID=your-default-voice-id
|
|
79
|
+
# OPENAI_API_KEY=your-openai-api-key
|
|
80
|
+
|
|
81
|
+
# ====================================
|
|
82
|
+
# Application Settings
|
|
83
|
+
# ====================================
|
|
84
|
+
|
|
85
|
+
# HTTP server port for API and audio file serving
|
|
86
|
+
HTTP_PORT=3000
|
|
87
|
+
|
|
88
|
+
# WebSocket port for audio streaming from FreeSWITCH
|
|
89
|
+
WS_PORT=3001
|
|
90
|
+
|
|
91
|
+
# Audio files directory
|
|
92
|
+
AUDIO_DIR=/app/audio
|
|
93
|
+
|
|
94
|
+
# ====================================
|
|
95
|
+
# Outbound Call Settings
|
|
96
|
+
# ====================================
|
|
97
|
+
|
|
98
|
+
# Maximum conversation turns for outbound calls
|
|
99
|
+
MAX_CONVERSATION_TURNS=10
|
|
100
|
+
|
|
101
|
+
# Ring timeout in seconds
|
|
102
|
+
OUTBOUND_RING_TIMEOUT=30
|
|
103
|
+
|
|
104
|
+
# ====================================
|
|
105
|
+
# Optional: Debug
|
|
106
|
+
# ====================================
|
|
107
|
+
|
|
108
|
+
# DEBUG=voice-app:*
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# claude-phone-local - single image containing all five services.
|
|
2
|
+
#
|
|
3
|
+
# Layout:
|
|
4
|
+
# FreeSWITCH : from the drachtio MRF base image (already compiled)
|
|
5
|
+
# drachtio : binary lifted from the official drachtio-server image
|
|
6
|
+
# Node 20 : copied from node:20-slim into /opt/node
|
|
7
|
+
# Python venv : /opt/venv with faster-whisper (STT) + piper-tts (TTS)
|
|
8
|
+
# supervisord : runs all five as one container
|
|
9
|
+
#
|
|
10
|
+
# All persistent state lives in /data (voices, models, audio, config) so a
|
|
11
|
+
# `docker compose down && up` never re-downloads anything.
|
|
12
|
+
|
|
13
|
+
FROM drachtio/drachtio-server AS drachtio
|
|
14
|
+
FROM node:20-slim AS nodesrc
|
|
15
|
+
|
|
16
|
+
FROM drachtio/drachtio-freeswitch-mrf
|
|
17
|
+
|
|
18
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
19
|
+
|
|
20
|
+
# drachtio needs these boost/tcmalloc libs, which the FreeSWITCH image lacks.
|
|
21
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
22
|
+
libboost-thread1.74.0 \
|
|
23
|
+
libboost-log1.74.0 \
|
|
24
|
+
libboost-filesystem1.74.0 \
|
|
25
|
+
libgoogle-perftools4 \
|
|
26
|
+
python3 python3-venv \
|
|
27
|
+
supervisor curl ca-certificates ffmpeg \
|
|
28
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
29
|
+
|
|
30
|
+
COPY --from=drachtio /usr/local/bin/drachtio /usr/local/bin/drachtio
|
|
31
|
+
# drachtio refuses to start without its config file, even when every setting
|
|
32
|
+
# is supplied on the command line.
|
|
33
|
+
COPY --from=drachtio /etc/drachtio.conf.xml /etc/drachtio.conf.xml
|
|
34
|
+
RUN ldd /usr/local/bin/drachtio | grep "not found" && exit 1 || echo "drachtio libs OK"
|
|
35
|
+
|
|
36
|
+
# Node into /opt/node so it cannot collide with /usr/local/freeswitch
|
|
37
|
+
COPY --from=nodesrc /usr/local/bin/node /opt/node/bin/node
|
|
38
|
+
COPY --from=nodesrc /usr/local/lib/node_modules /opt/node/lib/node_modules
|
|
39
|
+
RUN ln -sf /opt/node/bin/node /usr/bin/node \
|
|
40
|
+
&& ln -sf /opt/node/lib/node_modules/npm/bin/npm-cli.js /usr/bin/npm \
|
|
41
|
+
&& node --version && npm --version
|
|
42
|
+
|
|
43
|
+
# Python services
|
|
44
|
+
RUN python3 -m venv /opt/venv \
|
|
45
|
+
&& /opt/venv/bin/pip install --no-cache-dir --upgrade pip \
|
|
46
|
+
&& /opt/venv/bin/pip install --no-cache-dir \
|
|
47
|
+
fastapi "uvicorn[standard]" python-multipart faster-whisper piper-tts
|
|
48
|
+
# piper CLI must be on PATH for the TTS sidecar to shell out to it
|
|
49
|
+
RUN ln -sf /opt/venv/bin/piper /usr/bin/piper
|
|
50
|
+
|
|
51
|
+
COPY stt-local/server.py /opt/stt/server.py
|
|
52
|
+
COPY tts-local/server.py /opt/tts/server.py
|
|
53
|
+
|
|
54
|
+
# Node app (deps first for layer caching)
|
|
55
|
+
WORKDIR /app
|
|
56
|
+
COPY voice-app/package*.json ./
|
|
57
|
+
RUN npm install --omit=dev
|
|
58
|
+
COPY voice-app/ ./
|
|
59
|
+
|
|
60
|
+
# FreeSWITCH NAT fixes, carried over from the old compose file.
|
|
61
|
+
# - apply-nat-acl "nat.auto" treats 172.16/12 as local. The LAN (172.16.x) and
|
|
62
|
+
# the Docker bridge (172.18.x) both fall in that range, so FreeSWITCH decided
|
|
63
|
+
# the 3CX SBC was local and skipped external-IP substitution, putting the
|
|
64
|
+
# container IP in the SDP and breaking RTP in both directions.
|
|
65
|
+
# - local-network-acl "none" stops any further "this peer is local" guessing.
|
|
66
|
+
RUN sed -i '/apply-nat-acl/d' /usr/local/freeswitch/conf/sip_profiles/mrf.xml && sed -i '/<param name="ext-sip-ip"/a\ <param name="local-network-acl" value="none"/>' /usr/local/freeswitch/conf/sip_profiles/mrf.xml && grep -q 'local-network-acl' /usr/local/freeswitch/conf/sip_profiles/mrf.xml && echo "mrf.xml NAT patches applied"
|
|
67
|
+
|
|
68
|
+
COPY docker/supervisord.conf /etc/supervisor/supervisord.conf
|
|
69
|
+
COPY docker/entrypoint.sh /usr/local/bin/claude-phone-entrypoint
|
|
70
|
+
# Windows checkouts can introduce CRLF, which makes the shebang "bash
|
|
71
|
+
# and the container restart-loops. Normalise before making it executable.
|
|
72
|
+
RUN tr -d '
|
|
73
|
+
|
|
74
|
+
# voice-app writes generated audio here and reads devices.json from here
|
|
75
|
+
ENV AUDIO_DIR=/data/audio \
|
|
76
|
+
PIPER_VOICES_DIR=/data/voices \
|
|
77
|
+
HF_HOME=/data/models/huggingface \
|
|
78
|
+
DEVICES_CONFIG=/data/config/devices.json
|
|
79
|
+
RUN rm -rf /app/config && ln -s /data/config /app/config \
|
|
80
|
+
&& rm -rf /app/audio && ln -s /data/audio /app/audio
|
|
81
|
+
|
|
82
|
+
EXPOSE 3000 3001 5070/udp 5070/tcp 5080/udp 5080/tcp 30000-30100/udp
|
|
83
|
+
|
|
84
|
+
ENTRYPOINT ["/usr/local/bin/claude-phone-entrypoint"]
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Original work Copyright (c) NetworkChuck (https://github.com/theNetworkChuck/claude-phone)
|
|
4
|
+
Modified work Copyright (c) 2025 Deepak Chougale
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="Claude Phone" width="200">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Claude Phone (Local)
|
|
6
|
+
|
|
7
|
+
Voice interface for Claude Code via SIP/3CX. Call your AI, and your AI can call you.
|
|
8
|
+
|
|
9
|
+
> **Based on [theNetworkChuck/claude-phone](https://github.com/theNetworkChuck/claude-phone).**
|
|
10
|
+
> This is a modified fork of NetworkChuck's original project. All credit for the
|
|
11
|
+
> original design and implementation goes to him — see [Credits](#credits).
|
|
12
|
+
>
|
|
13
|
+
> **What this fork changes:** speech runs fully offline (faster-whisper + Piper
|
|
14
|
+
> instead of OpenAI Whisper and ElevenLabs, so no API keys), English/Hindi/Marathi
|
|
15
|
+
> with automatic language detection, barge-in so you can interrupt mid-sentence,
|
|
16
|
+
> an MCP server so Claude can phone *you*, and the whole stack in a **single
|
|
17
|
+
> Docker container** with a persistent `./data` volume.
|
|
18
|
+
|
|
19
|
+
## What is this?
|
|
20
|
+
|
|
21
|
+
Claude Phone gives your Claude Code installation a phone number:
|
|
22
|
+
|
|
23
|
+
- **Inbound** — call an extension and talk to Claude. Ask it to check your PC,
|
|
24
|
+
run commands, or answer questions. It has real shell access to the host.
|
|
25
|
+
- **Outbound** — Claude can call *you* when it needs a decision, then talk it
|
|
26
|
+
through. Available over HTTP or as an [MCP tool](docs/MCP-SERVER.md).
|
|
27
|
+
|
|
28
|
+
Everything speech-related is **local and free**. The only paid piece is the
|
|
29
|
+
Claude Code CLI itself.
|
|
30
|
+
|
|
31
|
+
## Prerequisites
|
|
32
|
+
|
|
33
|
+
Manual, one time:
|
|
34
|
+
|
|
35
|
+
- **Docker Desktop** (WSL2 backend on Windows)
|
|
36
|
+
- **Claude Code CLI**, logged in — `claude --version`
|
|
37
|
+
- **Node.js 18+** on the host, for `claude-api-server`
|
|
38
|
+
- A **SIP extension** on 3CX (or any SIP PBX)
|
|
39
|
+
|
|
40
|
+
Everything else — speech models, voices, device config — is downloaded and
|
|
41
|
+
generated automatically on first run.
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git clone <your-fork> claude-phone-local
|
|
47
|
+
cd claude-phone-local
|
|
48
|
+
cp .env.example .env
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Edit `.env` — the three that matter:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
EXTERNAL_IP=172.16.14.225 # this PC's LAN IP (ipconfig / ip addr)
|
|
55
|
+
SIP_REGISTRAR=172.16.14.225 # your LOCAL 3CX SBC, not the cloud domain
|
|
56
|
+
SIP_EXTENSION=17512 # plus SIP_AUTH_ID and SIP_PASSWORD
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Start it:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
docker compose up -d --build # first run downloads ~2GB of models
|
|
63
|
+
docker compose logs -f # watch the bootstrap
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
In a second terminal, start the host-side Claude wrapper:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
cd claude-api-server
|
|
70
|
+
CLAUDE_MODEL=claude-sonnet-5 node server.js
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
When you see this, call your extension:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
[MULTI-REGISTRAR] Maya SUCCESS - Registered as ext 17512
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Architecture
|
|
80
|
+
|
|
81
|
+
One container, one host process:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Phone → 3CX cloud → 3CX SBC (HOST :5060)
|
|
85
|
+
│
|
|
86
|
+
┌─────────────▼───────────────────────────┐
|
|
87
|
+
│ claude-phone container │
|
|
88
|
+
│ drachtio · FreeSWITCH · voice-app │
|
|
89
|
+
│ faster-whisper · Piper │
|
|
90
|
+
└─────────────┬───────────────────────────┘
|
|
91
|
+
│ host.docker.internal:3333
|
|
92
|
+
▼
|
|
93
|
+
claude-api-server (HOST) → claude.exe (HOST)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Inside the container everything talks over `127.0.0.1`. Persistent state lives
|
|
97
|
+
in `./data` — models, voices and config survive `docker compose down`.
|
|
98
|
+
|
|
99
|
+
See [CLAUDE.md](CLAUDE.md) for the full architecture and design decisions.
|
|
100
|
+
|
|
101
|
+
## Languages
|
|
102
|
+
|
|
103
|
+
English, Hindi and Marathi, detected per utterance — switch language mid-call
|
|
104
|
+
and she follows, replying in the same language with a matching voice.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
STT_LANGUAGE=auto
|
|
108
|
+
SUPPORTED_LANGS=en,hi,mr
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Details and the accuracy/speed trade-off: [docs/LANGUAGES.md](docs/LANGUAGES.md).
|
|
112
|
+
|
|
113
|
+
## Talking to her
|
|
114
|
+
|
|
115
|
+
- **Interrupt any time.** Start speaking and she stops — no waiting for her to
|
|
116
|
+
finish.
|
|
117
|
+
- **Hang up by saying so:** "goodbye", "bye", "end call", "close the call",
|
|
118
|
+
"बंद करो", "ठेवतो".
|
|
119
|
+
- **One session per call.** The whole call is a single Claude conversation, so
|
|
120
|
+
she remembers what you said two questions ago.
|
|
121
|
+
- **She fills the silence** with a soft hold tone and the occasional spoken
|
|
122
|
+
line while she works, instead of going dead.
|
|
123
|
+
|
|
124
|
+
## Claude calling you
|
|
125
|
+
|
|
126
|
+
Register the [MCP server](docs/MCP-SERVER.md) and ask in plain language:
|
|
127
|
+
|
|
128
|
+
> "Run the migration and call me if anything needs a decision."
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
cd mcp-server && npm install
|
|
132
|
+
claude mcp add claude-phone --scope user \
|
|
133
|
+
--env PHONE_DEFAULT_TO=17510 \
|
|
134
|
+
-- node /absolute/path/to/mcp-server/index.js
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Configuration
|
|
138
|
+
|
|
139
|
+
Common knobs in `.env`:
|
|
140
|
+
|
|
141
|
+
| Variable | Default | Purpose |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `EXTERNAL_IP` | — | This PC's LAN IP, for RTP |
|
|
144
|
+
| `WHISPER_MODEL` | `medium` | `small` is ~3x faster, weaker on Marathi |
|
|
145
|
+
| `STT_LANGUAGE` | `auto` | Or pin `en` / `hi` / `mr` |
|
|
146
|
+
| `CLAUDE_TIMEOUT` | `180` | Seconds before giving up |
|
|
147
|
+
| `VAD_NOISE_MULT` | `2.5` | How far above the noise floor counts as speech |
|
|
148
|
+
| `BARGE_MULT` | `1.6` | How hard it is to interrupt her |
|
|
149
|
+
| `PHONE_ENABLE_MCP` | off | Give the phone agent your MCP tools (slower) |
|
|
150
|
+
|
|
151
|
+
## API endpoints
|
|
152
|
+
|
|
153
|
+
**voice-app (3000)**
|
|
154
|
+
|
|
155
|
+
| Method | Endpoint | Purpose |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| POST | `/api/outbound-call` | Start an outbound call |
|
|
158
|
+
| GET | `/api/call/:id` | Call status |
|
|
159
|
+
| POST | `/api/call/:id/hangup` | End a call |
|
|
160
|
+
| GET | `/api/devices` | List configured devices |
|
|
161
|
+
|
|
162
|
+
**claude-api-server (3333, host)**
|
|
163
|
+
|
|
164
|
+
| Method | Endpoint | Purpose |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| POST | `/ask` | Send a prompt |
|
|
167
|
+
| GET | `/health` | Health check |
|
|
168
|
+
|
|
169
|
+
## Security
|
|
170
|
+
|
|
171
|
+
`claude-api-server` runs the CLI with `--dangerously-skip-permissions`. That
|
|
172
|
+
means **no prompts, all tools, full access to this PC as your user**, with your
|
|
173
|
+
normal `~/.claude` config. Anyone who can reach port 3333 can run commands as
|
|
174
|
+
you — keep it bound to localhost.
|
|
175
|
+
|
|
176
|
+
Never commit `data/config/devices.json` or `.env`; both are gitignored, and a
|
|
177
|
+
`prepublishOnly` guard blocks publishing if they would ship.
|
|
178
|
+
|
|
179
|
+
## Troubleshooting
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
docker compose logs -f
|
|
183
|
+
docker logs claude-phone 2>&1 | grep -Ei "CALL |error|503"
|
|
184
|
+
curl http://127.0.0.1:3333/health
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Straight to voicemail, connected-but-silent, slow answers, restart loops and
|
|
188
|
+
more: **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)**.
|
|
189
|
+
|
|
190
|
+
## Documentation
|
|
191
|
+
|
|
192
|
+
- [CLAUDE.md](CLAUDE.md) — architecture and design decisions
|
|
193
|
+
- [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) — every failure mode we hit
|
|
194
|
+
- [docs/LANGUAGES.md](docs/LANGUAGES.md) — Hindi/Marathi setup
|
|
195
|
+
- [docs/MCP-SERVER.md](docs/MCP-SERVER.md) — letting Claude call you
|
|
196
|
+
- [README-LOCAL-MODE.md](README-LOCAL-MODE.md) — Windows + 3CX specifics
|
|
197
|
+
- [voice-app/README-OUTBOUND.md](voice-app/README-OUTBOUND.md) — outbound API
|
|
198
|
+
- [voice-app/DEPLOYMENT.md](voice-app/DEPLOYMENT.md) — production notes
|
|
199
|
+
- [cli/README.md](cli/README.md) — CLI reference
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT — same as the original project.
|
|
204
|
+
|
|
205
|
+
## Credits
|
|
206
|
+
|
|
207
|
+
This project is a fork of **[claude-phone by NetworkChuck](https://github.com/theNetworkChuck/claude-phone)**
|
|
208
|
+
(`https://github.com/theNetworkChuck/claude-phone.git`). The original concept,
|
|
209
|
+
SIP/3CX integration and conversation design are his work — this fork only adapts
|
|
210
|
+
it for fully-offline speech and multilingual use.
|
|
211
|
+
|
|
212
|
+
If you find this useful, go support the original:
|
|
213
|
+
|
|
214
|
+
- Original repository: <https://github.com/theNetworkChuck/claude-phone>
|
|
215
|
+
- NetworkChuck on YouTube: <https://www.youtube.com/@NetworkChuck>
|
|
216
|
+
|
|
217
|
+
### Changes in this fork
|
|
218
|
+
|
|
219
|
+
| Area | Original | This fork |
|
|
220
|
+
|------|----------|-----------|
|
|
221
|
+
| STT | OpenAI Whisper API (key required) | faster-whisper, local (no key) |
|
|
222
|
+
| TTS | ElevenLabs API (key required) | Piper, local (no key) |
|
|
223
|
+
| Languages | English | English, Hindi, Marathi (auto-detected) |
|
|
224
|
+
| Containers | Multiple services | Single container via supervisord |
|
|
225
|
+
| Persistence | — | `./data` volume; models survive restarts |
|
|
226
|
+
| Setup | Manual model/config steps | Automated on first run |
|
|
227
|
+
| Conversation | Wait for her to finish | Barge-in — interrupt any time |
|
|
228
|
+
| Outbound | HTTP API | HTTP API + MCP server |
|
|
229
|
+
|
|
230
|
+
Cloud STT/TTS remain available as an opt-in (`STT_MODE=cloud` / `TTS_MODE=cloud`)
|
|
231
|
+
for anyone who prefers the original behaviour.
|