Give your LangChain agent an iMessage thread it can prove.
Install one StructuredTool, check connection readiness, and finish only when the matching reply reaches the active invocation. The same tool fits LangGraph agents.
Keep a persistent WebSocket consumer running.
Confirm readiness before invoking the tool.
The same tool call receives the matching inbound message.
Start with one controlled thread
Start the 7-day trial (card required), copy your API key, then install the Python package and run the reply-backed proof. Compare plans and limits. AI agent texting costs.
Start your 7-day trialOne invocation, one proof boundary
One controlled exchange
It opens a listener, sends one plain-text message, and waits for that recipient's reply in the same chat.
Persistent inbound work
The tool closes its listener when it returns. Keep your own long-running WebSocket consumer connected with the same account API key for ongoing replies.
The package is a bounded proof tool, not a delivery guarantee, group messaging tool, webhook server, or conversation store. It works with LangChain directly and with the LangChain runtime inside LangGraph.
1. Install the public Python package
Install the current release from PyPI in the environment where your LangChain or LangGraph agent runs.
python3 -m pip install langchain-claw-messengerCurrent public release: v0.1.0. Inspect the package, Apache 2.0 license, and release metadata on PyPI.
2. Prepare one controlled thread
Use one registered phone in E.164 format that you control. Keep the API key and recipient outside code, notebooks, screenshots, and logs.
export CLAW_API_KEY="cm_live_REDACTED"
export CONTROLLED_TEST_PHONE_E164="+14155550101"3. Connect your app and check readiness
Keep your app's WebSocket consumer connected with the same account API key. Check readiness below before running the tool. Published v0.1.0 opens a listener during each call but does not check readiness automatically.
curl -fsS https://claw-messenger.onrender.com/api/agent/readiness \
-H "Authorization: Bearer $CLAW_API_KEY"open listenerGET /api/agent/readinesssend{"ready":true,"action":"send_controlled_test"}If readiness is false, fix the connection before invoking the tool. Keep both your app listener and the tool call running through the reply step.
4. Run the working code example
The person holding the controlled phone should be ready to reply in the same thread while this call waits.
import json
import os
from langchain_claw_messenger import create_claw_messenger_tool
tool = create_claw_messenger_tool()
result = json.loads(
tool.invoke(
{
"recipient_e164": os.environ["CONTROLLED_TEST_PHONE_E164"],
"message": "This is my Claw Messenger test. Reply yes.",
"timeout_seconds": 300,
}
)
)
if result["proof_status"] != "reply_received":
raise RuntimeError(f"Two-way proof failed: {result['proof_status']}")
print("Matching reply reached the LangChain tool invocation")In an async agent, call await tool.ainvoke(...). The sync path deliberately refuses to nest another event loop.
5. Finish on the matching reply
Reply once from the controlled phone. The package matches the sender and chat, then returns a privacy-safe result to the active tool call.
proof_status: reply_received is the setup finish line.
A result with accepted, delivered, orread describes the outbound message. It does not prove the next inbound message can reach your agent.
Use the same tool in LangGraph
create_claw_messenger_tool() returns a LangChain StructuredTool. Add it to the tool set already bound to your model or agent runtime, then make reply_received the only state that can mark setup complete.
tools = [create_claw_messenger_tool()]
# Bind tools to the model or agent runtime used by your graph.
# Allow only registered recipients.
# Treat only proof_status == "reply_received" as setup complete.If you want to build the long-running graph loop yourself, use the separate LangGraph WebSocket and REST tutorial. This page stays focused on the installable package and its bounded proof contract.
If the proof stops halfway
The tool returns configuration_error
Use a valid E.164 recipient, nonempty message, and timeout between 1 and 900 seconds. Check the API key and connection if the call raises an error.
The send succeeds, but the tool times out
Reply from the exact registered phone in the same thread before the timeout. A different sender or chat will not satisfy the match.
The result says accepted or delivered
Keep waiting for reply_received. Outbound state is useful diagnostics, but it is below the two-way finish line.
LangChain and LangGraph iMessage questions
Does one LangChain tool call keep listening for later replies?
One LangChain tool call listens for one matching reply only while that invocation stays open. Ongoing inbound replies require a separate long-running WebSocket consumer using the same account API key.
Can a LangGraph agent call this tool?
Yes. It is a LangChain StructuredTool and can join the tool set used by a LangGraph agent runtime.
What counts as a working thread?
One controlled message leaves the tool, then the matching reply reaches that active invocation. Delivery status alone is not the finish.