Give your LangChain agent an iMessage thread it can prove.
Install one StructuredTool, let it check connection readiness, and finish only when the matching reply reaches the active invocation. The same tool fits LangGraph agents.
The tool starts a bounded WebSocket reply consumer.
Nothing leaves until authenticated readiness passes.
The same tool call receives the matching inbound message.
Start with one controlled thread
Start the 7-day trial, copy your API key, then return here to install the Python package and run the reply-backed proof.
Start your 7-day trialOne invocation, one proof boundary
One controlled exchange
It opens the listener, checks readiness, sends one plain-text message, and waits for that recipient's reply in the same chat.
Persistent inbound work
The listener closes when the tool returns. Use your own long-running WebSocket consumer or webhook for production conversations.
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. Let the tool connect and check readiness
The tool opens its reply listener first. It then calls the authenticated readiness endpoint before sending. The API key stays in the authorization header, never in the readiness URL.
open listenerGET /api/agent/readinesssend{"ready":true,"action":"send_controlled_test"}If readiness fails, the tool returns configuration_errorwith a connect action and sends nothing. Keep the invocation 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
Confirm the API key is current, the recipient uses E.164 format, and the listener can connect. A failed readiness check is designed to send nothing.
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 or webhook.
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.