Events
MCP Events as webhooks. A connected app is notified when an enquiry comes in, a viewing is booked or a suggestion is waiting.
Athaus supports MCP Events following the "Triggers & Events" draft, and of it the delivery by webhook. An app subscribes to an event, and Athaus sends it a signed message each time it happens. Today ChatGPT uses this; Claude does not subscribe to events over MCP.
Each of the two servers has its own events, and a subscription is created at the server its connection belongs to. So far the events of Athaus für Makler are built; the list per server is below, generated from the contract.
How it works
List the events
events/list needs sign-in, like every call, and names the built events of the server it is asked at. For each event it returns the name, a description, the delivery mode (webhook), the schema of the filters (inputSchema) and the schema of the data (payloadSchema).
Subscribe
events/subscribe needs an OAuth connection with the event's right; a key cannot subscribe.
{
"name": "inquiry.received",
"arguments": { "objekt_id": "0f6b9a3e-2c11-4d5e-9a77-4b1d2e3f4a5b" },
"delivery": { "mode": "webhook", "url": "https://example.com/hook", "secret": "whsec_..." }
}- The address must be
https, every one of its IP addresses public, without redirects, at most 2048 characters. - The secret has the form
whsec_plus Base64 of 24 to 64 bytes. - The IDs in the filter must belong to your office.
Verify the address
Before the first subscription, Athaus sends a signed verification to the address:
{ "type": "verification", "challenge": "..." }The receiver answers within 10 seconds with 2xx and { "challenge": "..." }. A verification holds for 24 hours per person, app and address.
Renew or end
A subscription lasts between 10 minutes and 24 hours, 24 hours if not specified, never forever; the response gives refreshBefore. Subscribing to the same subscription again renews it; its ID stays the same. A new secret replaces the old one, which keeps signing for another 15 minutes. events/unsubscribe with name, filter and address ends it and answers {}. At most 50 subscriptions run per person and app.
A delivery
POST /hook HTTP/1.1
content-type: application/json
webhook-id: evt_6f1c...
webhook-timestamp: 1790000000
webhook-signature: v1,<base64>
x-mcp-subscription-id: sub_9a2e...
user-agent: athaus-mcp-events
{ "eventId": "evt_6f1c...", "name": "inquiry.received", "timestamp": "...", "data": { ... }, "cursor": null }- Signature per Standard Webhooks: HMAC-SHA256 with the secret over
webhook-id.webhook-timestamp.body, Base64, prefixed withv1,. During a rotation two signatures stand separated by a space. webhook-idis the event's ID and the same on every attempt: that is how the receiver spots a retry.- Data contains only IDs and a short sentence (
satz), never the content of a message. The app fetches that with the tools, such asget_inquiry. - Time and size: 10 seconds per attempt, at most 256 KiB.
- Retries: four attempts, immediately and after about 30 seconds, 2 and 8 minutes.
2xxcounts as delivered.410and413are not retried. - Before each attempt Athaus checks consent, right and membership. If one is missing, the subscription is revoked.
- An event that an app triggered itself is not sent back to the same app.
Errors
| Code | Meaning |
|---|---|
-32602 | Wrong parameters, with data such as delivery.url:<reason> or delivery.secret |
-32011 | The event does not exist |
-32012 | Not allowed; data.reason is authentication_required, access_closed, oauth_connection_required (a key), insufficient_scope, arguments_not_in_account or ended_by_user |
-32013 | Too many subscriptions ({ "limit": "subscriptions", "max": 50 }) |
-32014 | Not supported: a delivery mode other than webhook, events/poll, events/stream |
-32015 | Verifying the address failed |
-32603 | Events are not set up on the server (events_not_configured) |
In the app
Under Settings, MCP server each connected app shows the events it has subscribed to. Unsubscribe stops a subscription; the app's next renewal then gets ended_by_user. Disconnect ends all subscriptions of that connection.
Athaus für Makler
inquiry.received
A new enquiry about a property in your portfolio, through Athaus, a portal or email. Where it came from is in quelle. Requires the right lesen.
- Filters:
objekt_id - Fields in
data:anfrage_id,objekt_id,quelle,satz
message.received
An enquirer has written again in an existing enquiry. Requires the right lesen.
- Filters:
objekt_id,anfrage_id - Fields in
data:anfrage_id,objekt_id,nachricht_id,satz
viewing.booked
An enquirer has booked a slot at a viewing or moved to another one. Requires the right lesen.
- Filters:
objekt_id - Fields in
data:termin_id,anfrage_id,objekt_id,beginn,umgebucht,satz
viewing.cancelled
An enquirer has given up their slot at a viewing. The viewing itself may stay. Requires the right lesen.
- Filters:
objekt_id - Fields in
data:termin_id,anfrage_id,objekt_id,beginn,satz
proposal.pending
The Athaus agent has prepared something that waits for a yes: a draft reply, a rejection, a change to a property. Requires the right lesen.
- Filters:
objekt_id,anfrage_id - Fields in
data:vorschlag_id,vorschlag_art,geht_hinaus,anfrage_id,objekt_id,satz
file.processed
A document on a property has been read, such as a brochure or an energy certificate. What is now on the property or waits as a suggestion, you read with get_property. Requires the right lesen.
- Filters:
objekt_id - Fields in
data:objekt_id,datei_id,sorte,angaben,satz
viewing.upcoming
A viewing with guests is coming up: about a day and about an hour before. Requires the right lesen.
- Filters:
objekt_id - Fields in
data:termin_id,objekt_id,beginn,fenster,satz
social.received
A new comment or message in your social networks. Requires the right lesen.
- Filters:
objekt_id - Fields in
data:eingang_id,art,netz,objekt_id,satz
Athaus Immobiliensuche
matches.new
Your search orders have new matches, once per run and order. Requires the right suchen.
- Filters:
saved_search_id - Fields in
data:saved_search_id,count,satz
reply.received
A provider has replied to your enquiry, with a message or a rejection. Requires the right suchen.
- Filters:
inquiry_id - Fields in
data:inquiry_id,listing_id,satz
viewing.changed
The provider has moved or cancelled a booked viewing. For a moved one, the new start is in start. Requires the right suchen.
- Filters:
inquiry_id - Fields in
data:inquiry_id,listing_id,change,start,satz