{"name":"com.reelquoteai/survey-tool","slug":"reelquoteai-survey-tool","title":"ReelQuoteAI Survey Tool","description":"Filmed moving surveys, itemized inventories, firm quotes and bookings for moving companies.","url":"https://mcp.market/server/reelquoteai-survey-tool","rating":null,"grade":"C","score":67,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":8,"stars":null,"forks":null,"downloads_week":null,"last_push_at":null,"license":null},"uptime":{"percent":100,"checks":7,"ok":7,"last_checked_at":"2026-09-21T02:30:57.476Z","last_ok_at":"2026-09-21T02:30:57.476Z","latency_ms":67},"claimed":false,"transport":"remote","callable_via_gateway":true,"default_price_micros":0,"repository":null,"website":"https://www.reelquoteai.com/developers","version":"1.1.0","remotes":[{"type":"streamable-http","url":"https://widget.reelquoteai.com/mcp","headers":[{"description":"Bearer <ReelQuoteAI API key>, issued to moving companies from their dashboard; a test key runs the sandbox.","isRequired":true,"isSecret":true,"name":"Authorization"}]}],"packages":[],"tools":[{"name":"acknowledge_gaps","description":"Record the customer's answer to the capture-gap prompts (inventory.gaps on GET /jobs/{id}). Body: { acknowledged: true } stamps \"nothing is missing\"; false clears it. The prompts themselves are recomputed from the current inventory on every read, so fixing a gap removes its prompt without this call. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"acknowledged":{"type":"boolean","description":"Default true"}},"required":["job_id"],"additionalProperties":false}},{"name":"approve_inventory","description":"Customer sign-off on the inventory, plus free-text notes. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"approved":{"type":"boolean","description":"Default true. false withdraws the sign-off."},"notes":{"type":"string","description":"Up to 2000 chars; absent leaves unchanged"}},"required":["job_id"],"additionalProperties":false}},{"name":"ballpark_estimate","description":"Instant estimate range from home size + addresses. Free; never bookable. Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"dwelling":{"type":"string","description":"A `dwelling` from GET /home-profiles","example":"2br_apt"},"move_date":{"type":"string","format":"date","description":"Lets date-based pricing apply. Optional but strongly recommended."},"origin":{"type":"object","properties":{"address":{"type":"string","description":"Free text as typed, or as resolved by /places/resolve"},"unit":{"type":"string","description":"Apartment or suite. A number like 2104 lets the floor be inferred."},"place_id":{"type":"string","description":"From /places/resolve, when address autocomplete was used"},"dwelling":{"type":"string","description":"apartment, condo, townhouse, house or storage — free text is normalised"}},"description":"One end of the move, as the customer gives it."},"destination":{"type":"object","properties":{"address":{"type":"string","description":"Free text as typed, or as resolved by /places/resolve"},"unit":{"type":"string","description":"Apartment or suite. A number like 2104 lets the floor be inferred."},"place_id":{"type":"string","description":"From /places/resolve, when address autocomplete was used"},"dwelling":{"type":"string","description":"apartment, condo, townhouse, house or storage — free text is normalised"}},"description":"One end of the move, as the customer gives it."},"distance_miles":{"type":"number","description":"Only used when no route can be found from the addresses"}},"required":["dwelling"],"additionalProperties":false}},{"name":"complete_upload","description":"Assemble a chunked upload. Body: { upload_id, parts: [{ part_number, etag }] }. Only after every part has been PUT; then call /submit. Scope: jobs:write.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"upload_id":{"type":"string","description":"From the multipart ticket"},"parts":{"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer","description":"1-based"},"etag":{"type":"string","description":"The ETag response header of that part's PUT"}}},"description":"Every part, in any order"}},"required":["job_id","upload_id","parts"],"additionalProperties":false}},{"name":"confirm_access","description":"Confirm floors / elevator / stairs / carry distance for both ends. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"origin":{"type":"object","properties":{"floor":{"type":"integer","description":"0–199"},"elevator":{"type":"boolean"},"stairs_flights":{"type":"integer","description":"0–30"},"parking_to_door_ft":{"type":"integer","description":"0–2000"}},"description":"What a customer can actually answer about one end. Only these fields are writable; inferred values are kept."},"destination":{"type":"object","properties":{"floor":{"type":"integer","description":"0–199"},"elevator":{"type":"boolean"},"stairs_flights":{"type":"integer","description":"0–30"},"parking_to_door_ft":{"type":"integer","description":"0–2000"}},"description":"What a customer can actually answer about one end. Only these fields are writable; inferred values are kept."},"move_date":{"type":["string","null"],"format":"date","description":"YYYY-MM-DD"}},"required":["job_id"],"additionalProperties":false}},{"name":"create_job","description":"Start a job (the survey container). Contact details are NOT accepted here — funnel rule. Send `Idempotency-Key` so a retry cannot create a second job. Scope: jobs:write.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"idempotency_key":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[\\x21-\\x7E]+$","description":"Any unique string per intended job (a UUID, your order id). For 24 hours, the same key with the same body returns the ORIGINAL 201 body with `Idempotent-Replayed: true` and creates nothing; the same key with a different body is a 422 `idempotency_key_reused`; the same key while the first request is still running is a 409 `idempotency_in_progress` with `Retry-After: 1`. Scoped to your account and partitioned by the calling key's kind and mode. Omit it and the request is never deduplicated."},"quote_kind":{"type":"string","enum":["ballpark","firm"],"default":"firm","description":"What the job is for. A firm job becomes bookable once filmed."},"dwelling":{"type":"string","description":"What the customer says their home is (any wording; stored beside what the video measures)","example":"2br_apt"},"move_date":{"type":"string","format":"date","description":"YYYY-MM-DD"},"origin":{"type":"object","properties":{"address":{"type":"string","description":"Free text as typed, or as resolved by /places/resolve"},"unit":{"type":"string","description":"Apartment or suite. A number like 2104 lets the floor be inferred."},"place_id":{"type":"string","description":"From /places/resolve, when address autocomplete was used"},"dwelling":{"type":"string","description":"apartment, condo, townhouse, house or storage — free text is normalised"}},"description":"One end of the move, as the customer gives it."},"destination":{"type":"object","properties":{"address":{"type":"string","description":"Free text as typed, or as resolved by /places/resolve"},"unit":{"type":"string","description":"Apartment or suite. A number like 2104 lets the floor be inferred."},"place_id":{"type":"string","description":"From /places/resolve, when address autocomplete was used"},"dwelling":{"type":"string","description":"apartment, condo, townhouse, house or storage — free text is normalised"}},"description":"One end of the move, as the customer gives it."}},"additionalProperties":false}},{"name":"create_key","description":"Mint a key. The raw secret is in THIS response only. A key can never mint one broader than itself; a test key mints only test keys; a live secret key may mint the sandbox pair. Scope: keys.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"kind":{"type":"string","enum":["publishable","secret"],"default":"secret"},"mode":{"type":"string","enum":["live","test"],"description":"Default: the calling key's mode."},"scopes":{"type":["array","null"],"items":{"type":"string","enum":["quote","jobs:read","jobs:write","outcomes","keys"]},"description":"null (default) = everything the kind allows"},"label":{"type":"string","description":"Up to 80 chars, e.g. 'CRM sync'"}},"additionalProperties":false}},{"name":"create_upload_url","description":"Presigned upload for the walkthrough video. Requires stored contact email. Body: { content_type, consent, size }. Send the byte size: at or above 16 MB the response carries `multipart` (an upload_id, a part_size and a presigned PUT per part) instead of `upload`, and each part is retried on its own rather than restarting the whole video. Report each part's ETag to /upload-complete. Below the threshold, or if opening a multipart upload fails, the response is a single `upload`. Scope: jobs:write.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"content_type":{"type":"string","description":"A video/* MIME type","example":"video/mp4"},"size":{"type":"integer","description":"Byte size of the file. Decides single vs multipart."},"consent":{"type":"boolean","description":"Must be true: the customer agrees the video will be analysed and shared with the mover."}},"required":["job_id","content_type","consent"],"additionalProperties":false}},{"name":"edit_items","description":"Edit inventory (quantity, exclude, add by item_key). Response carries the re-priced quote. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"items":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","description":"An existing row's id"},"quantity":{"type":"integer","description":"0 allowed"},"excluded":{"type":"boolean","description":"true = staying. Rows are never deleted."},"notes":{"type":"string","description":"Up to 500 chars"}},"required":["id"],"description":"Edit a row"},{"type":"object","properties":{"item_key":{"type":"string","description":"From GET /catalog"},"quantity":{"type":"integer","description":"Default 1"},"room":{"type":"string","description":"Default 'Added by customer'"},"notes":{"type":"string"}},"required":["item_key"],"description":"Add a row (source becomes customer_added)"}]},"description":"Non-empty. Any edit clears the customer's approval and the e-signature."}},"required":["job_id","items"],"additionalProperties":false}},{"name":"get_availability","description":"Which days the mover has marked off, before a job exists. Soft: a marked day can still be requested — the mover confirms and calls first — so steer to an open day when the customer has a choice. Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"from":{"type":"string","format":"date","description":"First day, YYYY-MM-DD. Default tomorrow; earlier dates clamp to tomorrow."},"days":{"type":"integer","minimum":1,"maximum":90,"default":30,"description":"Window length; values above 90 are capped."}},"additionalProperties":false}},{"name":"get_cube_sheet_csv","description":"Itemized cube sheet as CSV (Excel-ready): rooms, volumes, weights, exclusions. Secret key only. Scope: jobs:read.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"}},"required":["job_id"],"additionalProperties":false}},{"name":"get_date_prices","description":"This job's quote priced across a ~2-week window from the mover's date rules. flat=true means every day prices the same. Scope: jobs:read.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"}},"required":["job_id"],"additionalProperties":false}},{"name":"get_job","description":"Full job state: status, inventory, quote, access, terms, move_date. Scope: jobs:read.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job's ULID"}},"required":["job_id"],"additionalProperties":false}},{"name":"get_session","description":"Resolve the key to its mover (name, branding, config). Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"hand_off_video","description":"Server-side handoff: give us a public https URL of the walkthrough instead of uploading it from a browser. Secret key only. We fetch it (up to 500 MB, streamed) and the job runs exactly as an upload would — poll GET /jobs/{id}. Needs the stored contact email and consent, like /upload-url. Replaces /upload-url, /upload-complete and /submit for a caller that already holds the file. A job whose fetch failed (`error`) may be handed a new URL. Counts toward the mover's daily analysis cap (429). Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"url":{"type":"string","description":"Public https URL that serves the video (a signed cloud-storage link is ideal). Private hosts and http are refused."},"content_type":{"type":"string","description":"A video/* MIME type when you know it; otherwise the host's Content-Type must be video/*","example":"video/quicktime"},"consent":{"type":"boolean","description":"Must be true: the customer agrees the video will be analysed and shared with the mover."}},"required":["job_id","url","consent"],"additionalProperties":false}},{"name":"list_home_profiles","description":"Home sizes for the ballpark step (2br_apt, 3br_house, …). Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"list_jobs","description":"List jobs for the tenant, newest first. Secret key only. Paged: pass `limit` (1–100, default 25), optional `status`, and `cursor` from the previous page's `next_cursor` (null on the last page; a bad cursor is a 400). Scope: jobs:read.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":100,"default":25},"status":{"type":"string","enum":["created","uploading","uploaded","queued","processing","complete","quoted","booked_requested","booked","declined","error"],"description":"Funnel order. **created** — The job exists. Nothing uploaded yet. **uploading** — An upload URL was issued; the video is on its way. **uploaded** — A chunked upload was assembled (a single PUT skips this state). **queued** — POST /submit accepted; waiting its turn to be analysed. **processing** — The walkthrough is being analysed. Poll GET /jobs/{id}; typically 1–4 minutes. **complete** — Inventory ready. The firm quote is computed on the first read. **quoted** — A firm, bookable quote exists (set by the first GET after complete). **booked_requested** — The customer asked to book; the mover has not answered yet. **booked** — The mover confirmed the booking. **declined** — The mover turned the request down. `decline_reason` may say why. **error** — Analysis failed. `error` carries a message; upload again or contact the mover."},"cursor":{"type":"string","description":"Opaque; from the previous response's next_cursor."}},"additionalProperties":false}},{"name":"list_keys","description":"List the account's API keys — live and test, active and revoked. Never a raw secret. Secret key with the `keys` scope. Scope: keys.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"list_webhook_deliveries","description":"The delivery log: every webhook POST for 30 days, newest first, with its outcome and the exact body sent. Secret key with the `keys` scope. A key reads the deliveries of its own mode: live keys the live log, test keys the sandbox log. Scope: keys.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"webhook_id":{"type":"string","description":"One endpoint only"},"job_id":{"type":"string","description":"Everything sent about one job"},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25},"before":{"type":"string","format":"date-time","description":"The previous page's next_before"}},"additionalProperties":false}},{"name":"quote_inventory","description":"Direct pricing for agents: items or total_cuft in, firm quote out. Secret key only. Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"total_cuft":{"type":"number","description":"Either this…"},"items":{"type":"array","items":{"type":"object","properties":{"item_key":{"type":"string"},"quantity":{"type":"integer"}}},"description":"…or this, priced from the catalog"},"total_weight_lbs":{"type":"number","description":"Optional with total_cuft; derived from items otherwise"},"distance_miles":{"type":"number"},"move_date":{"type":"string","format":"date","description":"YYYY-MM-DD"},"origin":{"type":"object","properties":{"address":{"type":"string","description":"Free text as typed, or as resolved by /places/resolve"},"unit":{"type":"string","description":"Apartment or suite. A number like 2104 lets the floor be inferred."},"place_id":{"type":"string","description":"From /places/resolve, when address autocomplete was used"},"dwelling":{"type":"string","description":"apartment, condo, townhouse, house or storage — free text is normalised"}},"description":"One end of the move, as the customer gives it."},"destination":{"type":"object","properties":{"address":{"type":"string","description":"Free text as typed, or as resolved by /places/resolve"},"unit":{"type":"string","description":"Apartment or suite. A number like 2104 lets the floor be inferred."},"place_id":{"type":"string","description":"From /places/resolve, when address autocomplete was used"},"dwelling":{"type":"string","description":"apartment, condo, townhouse, house or storage — free text is normalised"}},"description":"One end of the move, as the customer gives it."},"rate_card_id":{"type":"string","description":"A specific card of this mover's; default the active one"}},"additionalProperties":false}},{"name":"replay_webhook_delivery","description":"Re-send one delivery to its endpoint: the same body byte for byte (same envelope id, so your dedupe still works) under a fresh signature, with the usual retries. Returns the replay's own delivery record. Deliveries of the other mode are not found (404). Scope: keys.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"type":"string","description":"A delivery id from the log"}},"required":["id"],"additionalProperties":false}},{"name":"report_outcome","description":"Report actuals (hours, final cents, crew). Secret key only. Scope: outcomes.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"actual_hours":{"type":"number"},"actual_total_cents":{"type":"integer","description":"What was actually billed, in integer cents. Currency travels beside it — never assume USD."},"actual_crew":{"type":"integer"},"notes":{"type":"string","description":"Up to 1000 chars"}},"required":["job_id"],"additionalProperties":false}},{"name":"request_booking","description":"Request the booking. Idempotent per job; requires approve:true (types-name-as-signature approval of the inventory + quote, stored with a quote snapshot) and accept_terms when the mover has terms. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"name":{"type":"string","description":"The submitted name is the signature on the approval."},"email":{"type":"string"},"phone":{"type":"string"},"approve":{"type":"boolean","description":"Must be true: approves the inventory as complete and this quote. Cleared if the inventory is edited afterwards."},"accept_terms":{"type":"boolean","description":"Required (true) when the job's `terms.terms` is non-null"}},"required":["job_id","name","email","approve"],"additionalProperties":false}},{"name":"resolve_address","description":"Resolve a suggestion to a full address (same session_token). Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"place_id":{"type":"string"},"session_token":{"type":"string"}},"additionalProperties":false}},{"name":"revoke_key","description":"Revoke a key immediately. The only live publishable key is refused (409) — rotate it instead. A test key cannot revoke a live key (403 `mode_mismatch`). Scope: keys.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"],"additionalProperties":false}},{"name":"rotate_key","description":"Replace a key with its twin (same kind, mode, scopes, label). The old key keeps working until `replaced.expires_at` so a deploy can swap values without a gap. Needs the `keys` scope even to rotate itself — rotate a scoped key with a full key or from the dashboard. A key is rotated once: rotating it again is a 409 `key_already_rotated`, and during its grace the old key cannot mint, rotate, revoke or read deliveries (403 `key_rotated`). A test key cannot rotate a live key (403 `mode_mismatch`). Scope: keys.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"type":"string","description":"Which key. Default: the key making this call."},"grace_hours":{"type":"integer","minimum":0,"maximum":72,"default":24,"description":"0 revokes the old key immediately."}},"additionalProperties":false}},{"name":"search_catalog","description":"Search the cube-sheet catalog (?q=sofa). Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"q":{"type":"string","minLength":2,"description":"Name, synonym or key fragment"}},"required":["q"],"additionalProperties":false}},{"name":"send_resume_link","description":"Email the customer their resume link. Only on explicit request. Scope: jobs:write.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"email":{"type":"string"},"name":{"type":"string"},"consent":{"type":"boolean","description":"Must be true"}},"required":["job_id","email","consent"],"additionalProperties":false}},{"name":"set_contact","description":"Store customer email + optional name + move date. Sends NOTHING — required before upload-url. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"email":{"type":"string"},"name":{"type":"string"},"consent":{"type":"boolean","description":"Must be true. Express consent to email about this quote."},"move_date":{"type":["string","null"],"format":"date","description":"Null clears; absent leaves unchanged."}},"required":["job_id","email","consent"],"additionalProperties":false}},{"name":"set_move_date","description":"Set or clear the move date; invalidates and recomputes the quote. Refused after a booking is requested. Scope: jobs:write.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"},"date":{"type":["string","null"],"format":"date","description":"YYYY-MM-DD, or null to clear."}},"required":["job_id"],"additionalProperties":false}},{"name":"submit_job","description":"Queue the uploaded video for analysis. Poll GET /jobs/{id} for status. Scope: jobs:write.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"job_id":{"type":"string","description":"The job id (ULID)"}},"required":["job_id"],"additionalProperties":false}},{"name":"suggest_addresses","description":"Address autocomplete (proxied; send session_token). Scope: quote.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"input":{"type":"string","description":"What the customer has typed so far"},"session_token":{"type":"string","description":"Any opaque string, kept for the whole typing session and the resolve call"}},"additionalProperties":false}}],"scan":{"score":67,"grade":"C","scanned_at":"2026-09-20T16:20:01.415Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-20T16:20:01.312Z","components":{"code":{"score":-1,"max":25,"notes":["remote-only server, no package to scan"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 529ms"]},"poisoning":{"score":15,"max":15,"notes":["32 tool descriptions checked"]},"auth":{"score":8,"max":15,"notes":["API key sent as a header"]},"maintenance":{"score":3,"max":15,"notes":["no repository listed"]},"identity":{"score":4,"max":10,"notes":["verified namespace with website, no repo"]}},"findings":[{"id":"maint.no-repo","severity":"low","component":"maintenance","title":"No source repository listed"}],"inputs":{"probes":[{"url":"https://widget.reelquoteai.com/mcp","reachable":true,"authRequired":false,"latencyMs":529,"serverInfo":{"name":"reelquoteai-us","version":"1.1.0"}}],"packages":[],"repo":{"found":false},"icon":{"url":"https://www.reelquoteai.com/favicon.ico","source":"site","width":48,"height":48},"presence":{"stars":null,"forks":null,"downloadsWeek":null,"license":null,"lastPushAt":null,"score":8}}}},"grade_history":[],"reviews":[]}