Phone Caller

WarnAudited by ClawScan on May 10, 2026.

Overview

The skill largely does what it claims, but its interactive phone server exposes unauthenticated public webhooks and stores/serves call data in ways users should review before installing.

Review before installing. Use dedicated provider keys, confirm every phone number and call purpose, avoid campaign use unless legally compliant, validate Twilio webhook signatures, restrict the public tunnel, fix the CALLER_PUBLIC_URL setup mismatch, and clean up /tmp audio/transcript files after calls.

Findings (7)

Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.

What this means

The agent can place real calls on the user's Twilio account when invoked.

Why it was flagged

The script can initiate real outbound Twilio calls to a user-supplied phone number. This is expected for the skill, but it is high-impact external communication and can incur cost.

Skill content
call = client.calls.create(
        from_=TWILIO_FROM,
        to=args.to,
        url=f"{url}/call/start?{params}"
Recommendation

Only use it with explicit user approval for the destination number, message/persona, and timing, especially for reservations, appointments, or campaign-like use.

What this means

Misconfigured or over-scoped credentials could allow unwanted calls, API charges, or exposure of phone conversation content to providers.

Why it was flagged

The skill requires high-value provider credentials that can spend money, place calls, and process conversation content. This is purpose-aligned, but the registry metadata declares no required env vars or primary credential.

Skill content
ELEVENLABS_API_KEY ... TWILIO_ACCOUNT_SID ... TWILIO_AUTH_TOKEN ... TWILIO_PHONE_NUMBER ... OPENAI_API_KEY
Recommendation

Use dedicated, least-privilege Twilio/OpenAI/ElevenLabs credentials where possible, monitor usage, and revoke keys if the skill is no longer needed.

What this means

Anyone who learns or guesses the tunnel URL could submit fake webhook traffic, consume OpenAI/ElevenLabs credits, manipulate call state, or inject content into summaries.

Why it was flagged

The public-facing webhook directly trusts POST parameters and sends speech text into GPT/TTS processing. The supplied code does not show Twilio request signature validation or another authentication check.

Skill content
@app.route("/call/respond", methods=["POST"])
def call_respond():
    call_sid  = request.values.get("CallSid", "unknown")
    user_said = request.values.get("SpeechResult", "").strip()
    ...
    ai_reply  = gpt_reply(call_sid, user_said)
    ...
    app.run(host="0.0.0.0", port=PORT, debug=False)
Recommendation

Validate Twilio signatures on all webhook routes, use hard-to-guess tunnel URLs, add an application secret, and reject requests that are not from Twilio.

What this means

A requester who knows or guesses a temporary filename could retrieve local temporary files, including potentially sensitive call artifacts.

Why it was flagged

The audio endpoint falls back to serving any matching filename in /tmp, not only files created and tracked by the skill. In interactive mode this endpoint is intended to be reachable through the public tunnel.

Skill content
@app.route("/audio/<filename>")
def serve_audio(filename):
    path = audio_files.get(filename) or f"/tmp/{filename}"
    if os.path.exists(path):
        return send_file(path, mimetype="audio/mpeg")
Recommendation

Serve only files in a dedicated skill-owned directory, require the filename to exist in the audio_files map, and avoid exposing arbitrary /tmp paths.

What this means

Private call details may remain on disk after the call and could be read by other local processes or exposed through overly broad file serving.

Why it was flagged

The server stores the call summary and full transcript in /tmp, but SKILL.md only mentions that a summary is sent via iMessage and does not describe local transcript retention or cleanup.

Skill content
log_path = f"/tmp/call_{call_sid[:8]}.txt"
with open(log_path, "w") as f:
    f.write(f"SUMMARY\n{summary}\n\nTRANSCRIPT\n{transcript}")
Recommendation

Document transcript storage, store logs in a private skill-owned directory with restrictive permissions, and add cleanup or an opt-out.

What this means

The skill may send messages from the user's local messaging setup and may fail or behave unexpectedly if the imsg tool is missing or configured differently.

Why it was flagged

The server invokes a local imsg command to send the call summary. Sending a summary is disclosed, but the required binary is not declared in the metadata or install requirements.

Skill content
subprocess.run(["imsg", "send", "--to", MASTER_PHONE, "--text", msg], capture_output=True)
Recommendation

Declare the required imsg dependency, make summary sending optional, and confirm MASTER_PHONE before use.

What this means

A scheduled call could occur at a later time, potentially causing surprise, cost, or unwanted contact if not tracked.

Why it was flagged

The skill documents a user-created cron job that can make a future phone call. This is disclosed and user-directed, but it is persistent behavior that may run later without active review.

Skill content
Use macOS cron for timed calls:
... crontab -e
45 8 24 2 * python3 /path/to/scripts/one_way_call.py --to "+1..." --text "Good morning!"
Recommendation

Use cron scheduling only for calls the user explicitly approves, log scheduled jobs, and remove the cron entry after it is no longer needed.