Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ai/mcp-server/CHATGPT_SUBMISSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Use these in ChatGPT developer mode on web and mobile before submitting:
Expected: calls `hostr_listings_availability`; preserves date-only values as `2026-08-01T00:00:00Z` style values when dates are in 2026.

3. `Book this instant-book stay for two nights`
Expected: asks for missing listing/date/price details if needed; calls `hostr_reservations_bookAndPay` only after intent is concrete; if payment is required, shows only the QR/invoice to the user and then calls `hostr_swaps_watch`.
Expected: asks for missing listing/date/price details if needed; calls `hostr_orders_bookAndPay` only after intent is concrete; if payment is required, shows only the QR/invoice to the user and then calls `hostr_swaps_watch`.

4. `Create a listing for my spare room`
Expected: asks for missing required fields; uploads images through `hostr_images_upload`; previews with `hostr_listings_create` and `dryRun: true`; does not publish until explicit approval.
Expand Down
16 changes: 8 additions & 8 deletions ai/mcp-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ hostr_listings_edit
hostr_listings_availability
hostr_listings_reviews
hostr_listings_reservationGroups
hostr_reservations_negotiateOffer
hostr_reservations_negotiateAccept
hostr_reservations_pay
hostr_reservations_commit
hostr_reservations_cancel
hostr_orders_negotiateOffer
hostr_orders_negotiateAccept
hostr_orders_pay
hostr_orders_commit
hostr_orders_cancel
hostr_updates
hostr_thread_view
hostr_thread_message
Expand Down Expand Up @@ -261,9 +261,9 @@ Agents should use the workflow docs from `hostr://mcp/action-input-types`, but t

- New listing: call `hostr_profile_edit` if profile details need updating, then `hostr_listings_create` with `dryRun: true`, show the preview, and repeat with `dryRun: false` only after approval. The live listing path ensures seller config is published.
- Edit listing: call `hostr_listings_edit` with `dryRun: true`, review the returned listing/event preview, then repeat with `dryRun: false`.
- Search and reserve: call `hostr_listings_search`, then `hostr_listings_availability`, then `hostr_reservations_negotiateOffer` with `dryRun: true`; repeat with `dryRun: false` to send the private negotiate-stage reservation DM.
- Negotiation: call `hostr_updates` to inspect thread/trade ids. Use `hostr_reservations_negotiateOffer` with `tradeId` and `amount` to send a follow-up offer, `hostr_reservations_negotiateAccept` to accept the latest offer, or `hostr_reservations_cancel` to cancel the private negotiation or committed reservation.
- Payment: for normal instant-book payment, call `hostr_reservations_bookAndPay`. After showing the returned QR/invoice, call the read-only `hostr_swaps_watch` with `swapId`, `tradeId`, and `reservationWaitSeconds`; it has no `dryRun` parameter and does not require approval. Use `hostr_swaps_recoverAll` only for explicit manual recovery/debug flows.
- Search and reserve: call `hostr_listings_search`, then `hostr_listings_availability`, then `hostr_orders_negotiateOffer` with `dryRun: true`; repeat with `dryRun: false` to send the private negotiate-stage reservation DM.
- Negotiation: call `hostr_updates` to inspect thread/trade ids. Use `hostr_orders_negotiateOffer` with `tradeId` and `amount` to send a follow-up offer, `hostr_orders_negotiateAccept` to accept the latest offer, or `hostr_orders_cancel` to cancel the private negotiation or committed reservation.
- Payment: for normal instant-book payment, call `hostr_orders_bookAndPay`. After showing the returned QR/invoice, call the read-only `hostr_swaps_watch` with `swapId`, `tradeId`, and `reservationWaitSeconds`; it has no `dryRun` parameter and does not require approval. Use `hostr_swaps_recoverAll` only for explicit manual recovery/debug flows.
- Messaging: call `hostr_updates`, choose recipient pubkeys from the thread/trade, call `hostr_thread_message` with `dryRun: true`, then repeat with `dryRun: false`.
- Listing management/profile/trips/bookings: call `hostr_listings_list` to inspect listing inventory, `hostr_profile_show` to inspect the current profile, `hostr_profile_edit` to preview/publish profile changes, `hostr_trips_list` for guest-side reservations, and `hostr_bookings_list` for reservations on listings authored by the authenticated user.
- Escrow compatibility: call `hostr_escrow_methods` with a seller pubkey before payment when the agent needs to explain compatible escrow services or ask the user to choose a non-default service.
Expand Down
14 changes: 7 additions & 7 deletions ai/mcp-server/chatgpt-app-submission.json
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@
"destructive_justification": "Does not delete, overwrite, revoke access, send irreversible messages, or perform irreversible transactions."
}
},
"hostr_reservations_bookAndPay": {
"hostr_orders_bookAndPay": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand All @@ -356,7 +356,7 @@
"destructive_justification": "Starts a booking handoff and payment prompt but does not delete, overwrite, revoke access, or settle funds by itself."
}
},
"hostr_reservations_cancel": {
"hostr_orders_cancel": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand All @@ -368,7 +368,7 @@
"destructive_justification": "Cancels a private negotiation or committed reservation after approval."
}
},
"hostr_reservations_commit": {
"hostr_orders_commit": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand All @@ -380,7 +380,7 @@
"destructive_justification": "Publishes a committed paid reservation after a payment proof is available."
}
},
"hostr_reservations_negotiateAccept": {
"hostr_orders_negotiateAccept": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand All @@ -392,7 +392,7 @@
"destructive_justification": "Sends private reservation negotiation events that cannot be unsent after live execution."
}
},
"hostr_reservations_negotiateOffer": {
"hostr_orders_negotiateOffer": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand All @@ -404,7 +404,7 @@
"destructive_justification": "Sends private reservation negotiation events that cannot be unsent after live execution."
}
},
"hostr_reservations_pay": {
"hostr_orders_pay": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand All @@ -416,7 +416,7 @@
"destructive_justification": "Creates manual escrow funding state for a reservation trade after approval."
}
},
"hostr_reservations_review": {
"hostr_orders_review": {
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
Expand Down
54 changes: 27 additions & 27 deletions ai/mcp-server/scripts/codex-ai-e2e.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ function buildPhases(runMode) {
{
prompt:
"Please draft that five-star Hostr trip review now and show me the preview. If it cannot be published yet, the preview is enough.",
when: missingTool("hostr_reservations_review"),
when: missingTool("hostr_orders_review"),
},
],
},
Expand All @@ -525,34 +525,34 @@ function buildPhases(runMode) {
prompt:
"For the reservation offer examples, use the same $20 stay total. Preview sending that counteroffer and preview accepting the latest offer; don't send or pay anything.",
when: missingAnyTool(
"hostr_reservations_negotiateOffer",
"hostr_reservations_negotiateAccept",
"hostr_orders_negotiateOffer",
"hostr_orders_negotiateAccept",
),
},
{
prompt:
"Please retry the reservation offer preview with the same $20 total; don't send it.",
when: failedTool("hostr_reservations_negotiateOffer"),
when: failedTool("hostr_orders_negotiateOffer"),
},
{
prompt:
"Please retry the latest-offer acceptance preview; don't accept it live.",
when: failedTool("hostr_reservations_negotiateAccept"),
when: failedTool("hostr_orders_negotiateAccept"),
},
{
prompt:
"Please switch back to my guest account and preview the negotiated payment check for this reservation; don't pay anything.",
when: failedTool("hostr_reservations_pay"),
when: failedTool("hostr_orders_pay"),
},
{
prompt:
"Please also preview the final reservation publication check from a saved paid proof or payment record; don't publish anything.",
when: missingTool("hostr_reservations_commit"),
when: missingTool("hostr_orders_commit"),
},
{
prompt:
"Please try the final reservation publication preview anyway; if the proof is missing, let Hostr return that as the preview result. Don't publish anything.",
when: missingTool("hostr_reservations_commit"),
when: missingTool("hostr_orders_commit"),
},
],
},
Expand Down Expand Up @@ -878,7 +878,7 @@ async function handleCodexLine(line) {
const observedTradeId = findStringByKey(item.result, "tradeId");
if (
observedTradeId &&
["hostr_reservations_bookAndPay", "hostr_swaps_watch"].includes(item.tool)
["hostr_orders_bookAndPay", "hostr_swaps_watch"].includes(item.tool)
) {
latestTradeId = observedTradeId;
}
Expand Down Expand Up @@ -1238,7 +1238,7 @@ function noHostrToolCalls(phaseStart) {
function missingSwapWatchAfterBooking(phaseStart) {
const calls = phaseToolCalls(phaseStart);
return (
calls.some((call) => call.tool === "hostr_reservations_bookAndPay") &&
calls.some((call) => call.tool === "hostr_orders_bookAndPay") &&
calls.every((call) => call.tool !== "hostr_swaps_watch")
);
}
Expand Down Expand Up @@ -1286,13 +1286,13 @@ function validatePhase(label, phase, phaseStart, result) {

function roleActionWasSatisfied(role, calls) {
if (role === "guest") {
return calls.some((call) => call.tool === "hostr_reservations_bookAndPay");
return calls.some((call) => call.tool === "hostr_orders_bookAndPay");
}
if (role === "host") {
return (
calls.some((call) => call.tool === "hostr_bookings_list") &&
calls.some((call) =>
["hostr_thread_message", "hostr_reservations_cancel"].includes(call.tool),
["hostr_thread_message", "hostr_orders_cancel"].includes(call.tool),
)
);
}
Expand All @@ -1304,7 +1304,7 @@ function roleActionWasSatisfied(role, calls) {

function needsBookingConfirmation(phaseStart) {
const calls = phaseToolCalls(phaseStart);
if (calls.some((call) => call.tool === "hostr_reservations_bookAndPay")) {
if (calls.some((call) => call.tool === "hostr_orders_bookAndPay")) {
return false;
}
const lastMessage = phaseAgentMessages(phaseStart).at(-1) ?? "";
Expand All @@ -1315,7 +1315,7 @@ function needsBookingConfirmation(phaseStart) {

function needsGuestLogin(phaseStart) {
const calls = phaseToolCalls(phaseStart);
if (calls.some((call) => call.tool === "hostr_reservations_bookAndPay")) {
if (calls.some((call) => call.tool === "hostr_orders_bookAndPay")) {
return false;
}
const connectedGuest = calls.some(
Expand All @@ -1332,7 +1332,7 @@ function needsStayClarification(phaseStart) {
const calls = phaseToolCalls(phaseStart);
if (
calls.some((call) =>
["hostr_listings_search", "hostr_reservations_bookAndPay"].includes(
["hostr_listings_search", "hostr_orders_bookAndPay"].includes(
call.tool,
),
)
Expand All @@ -1349,7 +1349,7 @@ function needsGuestPreferences(phaseStart) {
const calls = phaseToolCalls(phaseStart);
if (
calls.some((call) =>
["hostr_listings_search", "hostr_reservations_bookAndPay"].includes(
["hostr_listings_search", "hostr_orders_bookAndPay"].includes(
call.tool,
),
)
Expand All @@ -1374,7 +1374,7 @@ function needsAddressClarification(phaseStart) {
function needsPaymentConfirmation(phaseStart) {
const calls = phaseToolCalls(phaseStart);
const hasInvoice = calls.some((call) => {
if (call.tool !== "hostr_reservations_bookAndPay" || call.status !== "completed") {
if (call.tool !== "hostr_orders_bookAndPay" || call.status !== "completed") {
return false;
}
return Boolean(
Expand Down Expand Up @@ -1431,12 +1431,12 @@ function evaluate({ exitCode }) {
"hostr_listings_availability",
"hostr_listings_reviews",
"hostr_listings_reservationGroups",
"hostr_reservations_bookAndPay",
"hostr_reservations_negotiateOffer",
"hostr_reservations_negotiateAccept",
"hostr_reservations_pay",
"hostr_reservations_commit",
"hostr_reservations_review",
"hostr_orders_bookAndPay",
"hostr_orders_negotiateOffer",
"hostr_orders_negotiateAccept",
"hostr_orders_pay",
"hostr_orders_commit",
"hostr_orders_review",
"hostr_swaps_watch",
"hostr_swaps_list",
"hostr_swaps_recoverAll",
Expand All @@ -1446,7 +1446,7 @@ function evaluate({ exitCode }) {
"hostr_bookings_list",
"hostr_thread_message",
"hostr_escrow_involve",
"hostr_reservations_cancel",
"hostr_orders_cancel",
"hostr_profile_show",
"hostr_profile_lookup",
"hostr_profile_edit",
Expand Down Expand Up @@ -1563,7 +1563,7 @@ function toolFailureWasRecovered(index, failedCall) {

function observedBookAndPayInvoice() {
for (const call of toolCalls) {
if (call.tool !== "hostr_reservations_bookAndPay" || call.status !== "completed") {
if (call.tool !== "hostr_orders_bookAndPay" || call.status !== "completed") {
continue;
}
const invoice = findString(call.result, (value) =>
Expand Down Expand Up @@ -1591,7 +1591,7 @@ function aiDisplayedPaymentQr(messages) {

function toolDisplayedLightningInvoice(invoice) {
return toolCalls.some((call) => {
if (call.tool !== "hostr_reservations_bookAndPay" || call.status !== "completed") {
if (call.tool !== "hostr_orders_bookAndPay" || call.status !== "completed") {
return false;
}
const text = summarizeToolResult(call.result);
Expand All @@ -1601,7 +1601,7 @@ function toolDisplayedLightningInvoice(invoice) {

function toolDisplayedPaymentQr() {
return toolCalls.some((call) => {
if (call.tool !== "hostr_reservations_bookAndPay" || call.status !== "completed") {
if (call.tool !== "hostr_orders_bookAndPay" || call.status !== "completed") {
return false;
}
return /!\[[^\]]*(qr|payment|invoice|lightning)[^\]]*\]\([^)]+\)|payment-qr|qr code|scan|create-qr-code/i.test(
Expand Down
Loading
Loading