Developers · MCP Beta
Let your assistant ask your cameras.
Add Watchful to Claude, ChatGPT or your own agent as an MCP connector. It can ask what your cameras saw, get alerts, and start or stop what Watchful watches for. Only with your consent, and only what you allow: answers and alerts, and at the third level pictures and short clips of the moments Watchful returns.
https://net.belike.vip/cloud/mcpQuick start
Claude (claude.ai, the desktop app)
Settings → Connectors → Add custom connector. Name it Watchful, paste the address above, and press Connect. Claude opens Watchful's consent page: sign in, pick the stations and the access, Allow. Then ask: "Is anyone in the living room?"
Claude Code
claude mcp add --transport http watchful https://net.belike.vip/cloud/mcp
Then run /mcp in Claude Code and choose Authenticate for watchful.
ChatGPT and other assistants
Any client that speaks MCP over Streamable HTTP with the MCP authorization flow connects with the address alone; it discovers the rest. Where connectors are added in developer mode, add a custom connector with the address above and OAuth.
A self-hosted agent (OpenClaw and others)
No browser sign-in? The owner makes an agent key in their Watchful account and gives it to the agent, which sends it as a Bearer token:
curl -s https://net.belike.vip/cloud/mcp \
-H "Authorization: Bearer wak_…" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ask","arguments":{"question":"Did anyone come to the door today?"}}}'
Use cases
The assistant brings the reasoning and its other tools (messages, a smart home, a calendar, a ticket system); Watchful brings the eyes. A few ways they work together:
When did you last see my cat?
- The assistant calls
askwith the question as you said it. - Watchful reads its memory: "Miso was on the kitchen windowsill at 4:12 PM, then walked toward the hallway." The answer has a link; tapping it opens that moment in the Watchful app.
- If it was hours ago, the assistant can ask on: "Has the cat been near the front door since?"
Let me know when it starts to rain, and if it does, close the blinds.
- The agent calls
subscribe_alertswith its webhook, thenstart_watching: "Tell me when it starts to rain on the balcony." - When rain starts, Watchful's alert reaches the webhook within seconds. The agent closes the blinds with its own smart-home tool (Home Assistant, for example) and messages you.
- It asks once more to confirm, "Are the living room blinds closed?", and calls
stop_watchingwhen the job is done.
Did everyone on the east wing come to breakfast?
- At 9:30 the staff's agent asks the dining room camera who came, and
recent_alertsfor anything overnight. - If someone is missing, it messages the nurse on shift: "Room 4 hasn't been to breakfast. Last seen in the corridor at 6:50."
- The nurse replies in the chat; the agent asks Watchful again when she says she's checked.
Tell the floor team when the checkout queue gets long.
- Every five minutes in opening hours, the agent asks: "How many people are waiting at the checkouts?"
- Over five, it posts to the store's channel: "7 waiting at checkout. Open till 3?", and notes it on the day's report.
- At closing it asks for the day: "When was the queue longest today?" for the rota.
Is the site safe to close?
- At the end of the last shift the agent runs its checklist with Watchful: "Is the loading bay door closed? Is anything in the forklift lane? Is anyone still on the floor?"
- Every yes-or-no goes into the closing report; anything wrong opens a ticket for the duty manager with Watchful's answer and the time.
- The manager closes the ticket when it's sorted, and the agent asks once more to be sure.
Privacy and permissions
The short version: an assistant gets words about what the cameras saw, on the stations the owner picked, for as long as the owner allows. Pictures and short clips only at the third level, and only of the moments Watchful itself returns; it never changes how the station is set up, and the owner can see and stop it at any moment.
Answers say what they’re based on. Watchful tells the assistant which period it searched, and the assistant passes that on. It never claims to have watched the feed.
What a connection can and cannot do, by access
| Ask | Ask and watch | Ask, watch and see | |
|---|---|---|---|
| Ask about now and the past, in words | Yes | Yes | Yes |
| List the cameras and whether they are live | Yes | Yes | Yes |
| Read alerts, and get them by webhook | Yes | Yes | Yes |
| Start, list and stop standing requests | No | Yes | Yes |
| A camera's picture now, and the pictures behind an answer | No | No | Yes, a bare person blurred first |
| Short clips (20 s) of the moments Watchful answers or alerts with, as links that work for a day | No | No | Yes, a bare person blurred first |
| Live video, whole recordings, or a clip of any time it chooses | Never | Never | Never |
| A "Watch live" link that opens a camera in the owner's own Watchful app | Yes | Yes | Yes |
| A link that opens the moment in the owner's Watchful app | Yes | Yes | Yes |
| Settings, cameras (add, remove, rename), recording, storage | Never | Never | Never |
| Pairing, devices, other connections, the owner's account | Never | Never | Never |
| Deleting history, moments or recordings | Never | Never | Never |
| The owner's conversation, or questions the station asked the owner | Never | Never | Never |
| Speaking through the station's speaker | Never | Never | Never |
| Stations the owner did not pick, or anyone else's | Never | Never | Never |
How it is enforced
- Twice: in the cloud and on the station. Watchful Cloud only offers and runs the tools the access allows. The station also gives the connection its own key, a device named "Agent · …", that reaches only a short list of requests for its level (questions, cameras, alerts; standing requests at Watch; pictures at See) and is refused everything else, whatever the cloud asked.
- Its own lane. An assistant's question never interrupts the owner's, it never answers a question the station put to the owner, and at Ask an instruction like "start watching" or "rename the camera" is politely refused.
- Seen by the owner. Everything it asks shows in the station's activity, marked with its name.
The owner's controls
What passes through, and what is kept
| Data | Where it goes |
|---|---|
| Questions and answers | Pass through Watchful Cloud between the assistant and the station; the cloud keeps only the last action's first words for the owner's card. The station keeps them in its own activity, at home. |
| Pictures (See only) | Cut and blurred on the station, passed through to the assistant, not kept by Watchful Cloud. What the assistant does with them is up to its own policy; the consent page says so. |
| Alerts | Words and times only. The station sends them up only while it has a connected assistant; the cloud forwards them to webhooks, signed, and keeps when the last one went. |
| Tokens | Kept by the cloud as one-way hashes; codes work once. Turn off deletes them. |
| Video | At Ask and at Ask and watch, none. At Ask, watch and see, short clips (5 s before to 15 s after) of the moments Watchful returned, cut and blurred on the station and played through a link that works for a day and stops the moment the owner turns the connection off or lowers it; Watchful Cloud keeps a clip only briefly in memory while it plays. Every answer and alert also carries a link, https://www.belike.vip/app/v/<station>?t=<time>&cam=<camera>, that opens the moment in the owner's own Watchful app; it holds no key. |
Sign-in (OAuth)
Watchful follows the MCP authorization spec: OAuth 2.1, authorization code with PKCE, public clients. A call without a token answers 401 with a WWW-Authenticate header that points to the metadata.
| What | Where |
|---|---|
| Protected resource metadata | https://net.belike.vip/.well-known/oauth-protected-resource/cloud/mcp |
| Authorization server metadata | https://net.belike.vip/.well-known/oauth-authorization-server |
| Client registration (RFC 7591) | POST https://net.belike.vip/cloud/oauth/register, or use an https client-id metadata document as the client id |
| Authorization | https://net.belike.vip/cloud/oauth/authorize: response_type=code, code_challenge with S256, state, scope = ask, watch or see as a hint (the owner chooses; pictures are never pre-selected) |
| Token | POST https://net.belike.vip/cloud/oauth/token: authorization_code and refresh_token |
| Revocation (RFC 7009) | POST https://net.belike.vip/cloud/oauth/revoke |
Redirect addresses must be https, localhost, or an app's own scheme, and must match what was registered. Codes are good once, for five minutes. Access tokens last an hour; refresh tokens rotate on every use and end with the connection (90 days, or the moment the owner turns it off). The granted access comes back as scope in the token answer.
Agent keys
For an agent that cannot open a browser for the owner, the owner makes a key in Connected agents → Make an agent key. It starts with wak_, is shown once, works as a Bearer token on the MCP address, has Ask access, and shows on its own card with the same Turn off, Renew and Pause all.
Alerts to agents
An always-on agent need not ask in a loop. Call subscribe_alerts with a public https address and Watchful POSTs each new alert there within seconds: falls, someone at the door, a standing request coming true, a camera going quiet. Alerts reach a webhook only while the connection is on and not paused, and only for the stations it was given. The owner sees on its card where alerts go and when the last one went.
POST https://your-agent.example/watchful
Content-Type: application/json
X-Watchful-Timestamp: 1792302173
X-Watchful-Signature: sha256=5d1c…
{"type":"watchful.alert","id":"3ec39f652826:1842","station":{"id":"3ec39f652826","name":"Dell"},
"ts":1792302171.4,"time":"2026-10-18 09:02 UTC","camera":"outside","kind":"alert","severity":"",
"headline":"It started to rain on the balcony.","detail":"At 9:02 AM.",
"link":"https://www.belike.vip/app/v/3ec39f652826?t=1792302165&cam=c85750bb","clip_available":true,"connection":"OpenClaw"}
Check every delivery before acting on it: the signature is an HMAC-SHA256 of the timestamp, a dot, and the raw body, with the secret subscribe_alerts gave you. Refuse old timestamps (say, over five minutes).
# Python
import hmac, hashlib, time
def genuine(secret, headers, body: bytes):
ts = headers["X-Watchful-Timestamp"]
want = "sha256=" + hmac.new(secret.encode(), ts.encode() + b"." + body, hashlib.sha256).hexdigest()
return abs(time.time() - int(ts)) < 300 and hmac.compare_digest(want, headers["X-Watchful-Signature"])
// Node
const crypto = require("crypto");
const genuine = (secret, h, raw) => {
const want = "sha256=" + crypto.createHmac("sha256", secret).update(h["x-watchful-timestamp"] + "." + raw).digest("hex");
return Math.abs(Date.now() / 1000 - +h["x-watchful-timestamp"]) < 300 &&
crypto.timingSafeEqual(Buffer.from(want), Buffer.from(h["x-watchful-signature"]));
};
Answer with any 2xx. A failed delivery is tried once more a few seconds later. Webhooks must be https on a public address.
Tools
tools/list shows only what the connection's access allows; a tool above it answers with an error that says so.
| Tool | Access | Arguments | Returns |
|---|---|---|---|
list_cameras | Ask | none | The stations this connection may use, online or not, and each one's cameras with whether they are live. |
ask | Ask | question (required), station (name or id, when there are several) | Watchful's answer in a sentence or two, with the time and a link that opens the moment in the owner's app. It looks with its cameras or reads its memory, as the question needs; up to a minute when it has to look. With see, the picture behind the answer comes first. |
recent_alerts | Ask | limit (1 to 20, default 5), station | The latest alerts, newest first: time, headline, detail and a link to each moment. |
subscribe_alerts | Ask | url (public https) | New alerts POSTed to your webhook as they happen. Answers with the signing secret, once. Calling again replaces the webhook. |
unsubscribe_alerts | Ask | none | No more alerts to the webhook. |
list_watches | Watch | station | The standing requests running now, each with its id. |
start_watching | Watch | instruction (required), station | Watchful's confirmation of what it will watch for ("Okay, I'll tell you when it starts to rain."). Its alerts reach the owner and your webhook. |
stop_watching | Watch | id (required), station | The request stopped. |
get_picture | See | camera (name, default the main one), at (a moment's unix time or its moment link), station | The camera's picture now, or the picture at that moment, as an image (JPEG, up to 960 wide), a bare person blurred, and as a link that works for a day. |
get_clip | See | at (required: a moment's unix time or its moment link), camera, station | A private link to a 20-second clip of that moment (5 s before, 15 s after), cut on the station when asked; works for a day. Only when the owner asks for a clip. |
Answers are text, with a link to the moment and a "Watch live in Watchful" link (https://www.belike.vip/app/live/<station>?cam=<camera>): live video is never sent to an assistant, it hands the owner that link. At see, an answer about moments carries one picture per moment, up to four (the latest); when there are more, it says how many and when, so the assistant can offer them and fetch each with get_picture and at. Clips are never attached: the answer says one is available, and get_clip makes it when the owner asks. Questions that work well: "Is anyone home?", "Did you see where I left my keys?", "When did the dog last go out?", "How many people came to the shop today?"
→ {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"ask","arguments":{"question":"Is anyone in the living room?"}}}
← {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"Nobody is in the living room.\nThe last person left at 11:33 PM.\n(Dell, 2026-10-17 21:24 UTC)"}],"isError":false}}
Protocol
MCP over Streamable HTTP. Send JSON-RPC with POST to the address; answers come back as application/json (no server-sent stream, so GET answers 405). Single messages and batches both work; notifications answer 202. Protocol versions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05 are accepted. Methods: initialize, ping, tools/list, tools/call.
Errors
| You get | Because |
|---|---|
401 + WWW-Authenticate | No token, or one that expired or was turned off. Sign in again (or refresh). |
Tool result with isError: true | The owner paused all assistants, the station is offline, the question needs a station because there are several, or the station could not answer in time. The text says which. |
| An answer that says it can only ask | The connection has Ask access and the question was really an instruction (start watching, rename a camera). The owner can give Ask and watch. |
| A tool error naming the access it needs | The tool is above the connection's access (a watch tool at Ask, get_picture below See). |
Coming next
- Listed connectors. Watchful in Claude's and ChatGPT's connector directories, so owners add it with one tap.
Building something with Watchful? Write to yogev77@gmail.com.