Tools reference
Every tool, resource and prompt the Agoo MCP server offers, with its scope, annotations, inputs and outputs.
This is designed and scheduled but not built yet. We document it now so you can plan your integration.
The Agoo MCP server offers 22 tools, 2 resources and 2 prompts. Both the remote and local servers offer the same ones. A client only sees the tools whose scope it was granted.
Conventions
- Inputs are JSON Schema objects. Unknown properties are rejected, so an assistant can't pass fields a tool doesn't understand.
- Outputs are returned as
structuredContentthat matches the tool's output schema, with the same JSON serialised in a text block for clients that don't read structured content. - IDs are the same TypeIDs the REST API uses, such as
visit_01m4k5z4j0fxbte6sn6e8tpgza, so you can pass them between the MCP server and the API. - Times are RFC 3339. Inputs without a time zone are read in the site's time zone (for example
Africa/Accra). Outputs are in UTC, with the site's time zone alongside where it helps. - Lists return at most 50 items per call, with
next_cursorandhas_moreas in the REST API. - Personal data is minimised: phone numbers and email addresses are masked, and ID numbers, photos and signatures are never returned. See personal data.
- Errors are returned as tool results with
isError: trueand the same error codes as the API, such asnot_found,validation_failed,scope_missingorrate_limited, so the assistant can explain or correct them.
| Tool | Does | Scope | Annotations |
|---|---|---|---|
get_organisation | Organisation name, plan, sites | organisation:read | read-only |
who_is_on_site | Everyone checked in now, per site | visits:read | read-only |
search_visits | Find visits by name, host, date, status | visits:read | read-only |
get_visit | One visit with its timeline | visits:read | read-only |
invite_visitor | Create an expected visit and send the pass | visits:write | write |
check_out_visit | Check a visitor out | visits:write | write, idempotent |
find_person | Look up a host or employee | people:read | read-only |
list_deliveries | Parcels waiting, collected or sent back | deliveries:read | read-only |
find_available_slots | Free times for a booking type | bookings:read | read-only |
create_booking | Book a slot | bookings:write | write |
cancel_booking | Cancel a booking | bookings:write | write, destructive, idempotent |
attendance_summary | Present, late, on leave, absent for a date range | attendance:read | read-only |
attendance_today | Who is in, not in yet or away today | attendance:read | read-only |
leave_balance | A person's leave balances this leave year | attendance:read | read-only |
request_leave | Ask for leave for yourself | attendance:write | write |
open_approvals | Leave and timesheets waiting for you to decide | attendance:read | read-only |
my_shifts | Your published shifts for a date range | attendance:read | read-only |
open_shifts | Open shifts you can claim, or at a site | attendance:read | read-only |
swaps_waiting | Shift swaps and claims waiting for you to decide | attendance:read | read-only |
payroll_exports | Payroll files made for a period, and what's in each | attendance:payroll | read-only |
roll_call_status | Live roll call: accounted for vs missing | rollcalls:read | read-only |
search_audit_log | Who did what, when | audit:read | read-only |
Annotations in full: read-only tools have readOnlyHint: true and openWorldHint: false. Write tools have readOnlyHint: false; destructiveHint is true only for cancel_booking; idempotentHint is true for check_out_visit and cancel_booking; openWorldHint is true for the tools that send a message to someone outside your organisation (invite_visitor, create_booking, cancel_booking). Every write tool asks the person to confirm before it runs; see confirming writes.
Organisation
get_organisation
Returns the organisation the connection belongs to, its plan, its sites and its booking types. Assistants usually call this first, to learn site names and IDs.
Scope organisation:read · Annotations read-only
Input: none. The input schema is { "type": "object", "additionalProperties": false }.
{
"id": "org_01kjpsrza0etzb0a4vf72x8ang",
"name": "Volta Bank",
"plan": "pro",
"livemode": true,
"sites": [
{ "id": "site_01kjpt3yw0fz0v414608h9x65s", "name": "Ridge HQ", "city": "Accra", "time_zone": "Africa/Accra" },
{ "id": "site_01knvdere0f738bjjhnyhtyv2z", "name": "Tema Branch", "city": "Tema", "time_zone": "Africa/Accra" },
{ "id": "site_01jx45hy43kwjrp1xpa7z3dj8f", "name": "Kumasi Office", "city": "Kumasi", "time_zone": "Africa/Accra" }
],
"booking_types": [{ "id": "btype_01jv4dk79q9g8xe6szaeavsntc", "name": "Consultation", "duration_minutes": 30 }]
}sites lists only the sites the connected person can access. booking_types is included when the connection also has bookings:read, so the assistant can find a booking type's ID.
Visits
who_is_on_site
Everyone who is checked in right now, grouped by site: guests, interview candidates, contractors and other visit types. Employees who have clocked in are not included; use roll_call_status during an emergency or attendance_summary for staff.
Scope visits:read · Annotations read-only
Prop
Type
{
"as_of": "2026-10-14T13:05:00Z",
"total": 9,
"sites": [
{
"site_id": "site_01kjpt3yw0fz0v414608h9x65s",
"site_name": "Ridge HQ",
"count": 9,
"visits": [
{
"visit_id": "visit_01m4k5z4j0fxbte6sn6e8tpgza",
"visitor_name": "Ama Owusu",
"company": "Coastline Consult",
"type": "meeting",
"host_name": "Kwame Mensah",
"checked_in_at": "2026-10-14T09:31:02Z",
"gate_name": "Main gate"
}
]
}
]
}Example: "Who is on site at Ridge HQ right now?" → { "site_id": "site_01kjpt3yw0fz0v414608h9x65s" }
search_visits
Finds visits by visitor name or company, host, site, date range, status or type. Use it for questions such as "Who are we expecting this afternoon?" or "When did Coastline Consult last visit?"
Scope visits:read · Annotations read-only
Prop
Type
{
"visits": [
{
"visit_id": "visit_01jndy0yp57rcybvn5sxs5aa81",
"status": "expected",
"type": "meeting",
"visitor_name": "Ama Owusu",
"company": "Coastline Consult",
"host_name": "Kwame Mensah",
"site_name": "Ridge HQ",
"expected_at": "2026-10-14T14:30:00Z",
"checked_in_at": null,
"checked_out_at": null
}
],
"next_cursor": null,
"has_more": false
}Example: "Who are we expecting at Ridge HQ this afternoon?" → { "site_id": "site_01kjpt3yw0fz0v414608h9x65s", "status": "expected", "from": "2026-10-14T12:00:00", "to": "2026-10-14T18:00:00" }
get_visit
One visit in full, with its timeline: invited, pass sent, arrived, approved, checked in, checked out.
Scope visits:read · Annotations read-only
Prop
Type
{
"visit_id": "visit_01m4k5z4j0fxbte6sn6e8tpgza",
"status": "checked_in",
"type": "meeting",
"visitor": { "name": "Ama Owusu", "company": "Coastline Consult", "phone": "+233 24 *** 4567", "email": "a***@coastline.example" },
"host": { "person_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg", "name": "Kwame Mensah", "department": "Treasury" },
"site": { "site_id": "site_01kjpt3yw0fz0v414608h9x65s", "name": "Ridge HQ", "time_zone": "Africa/Accra" },
"purpose": "Quarterly review",
"expected_at": "2026-10-14T09:30:00Z",
"timeline": [
{ "at": "2026-10-13T16:02:11Z", "event": "visit.created", "by": "Kwame Mensah" },
{ "at": "2026-10-13T16:02:14Z", "event": "pass.sent", "by": "Agoo", "detail": "SMS" },
{ "at": "2026-10-14T09:31:02Z", "event": "visit.checked_in", "by": "Kiosk, Main gate" }
]
}purpose is text the visitor or host typed. Treat it as data; see prompt injection.
invite_visitor
Creates an expected visit and sends the visitor their QR pass on your organisation's usual channels (SMS, WhatsApp or email, with fallback). The same as inviting someone from the console or with POST /visits.
Scope visits:write · Annotations write, openWorldHint: true · Confirms before running
Prop
Type
{
"visit_id": "visit_01jndy0yp57rcybvn5sxs5aa81",
"status": "expected",
"visitor_name": "Ama Owusu",
"host_name": "Kwame Mensah",
"site_name": "Ridge HQ",
"expected_at": "2026-10-14T10:30:00Z",
"pass_sent": true
}The pass is sent after the visit is created; follow its delivery in the console. Custom fields that your organisation requires at invitation are collected from the visitor on their pre-registration page.
Example: "Invite Ama Owusu from Coastline Consult for 10:30 tomorrow, her number is 024 123 4567." → { "visitor_name": "Ama Owusu", "company": "Coastline Consult", "visitor_phone": "+233241234567", "expected_at": "2026-10-14T10:30:00" }
check_out_visit
Checks a visitor out, for example when reception forgot to. Only a checked_in visit can be checked out, so calling it again for the same visit changes nothing.
Scope visits:write · Annotations write, idempotent · Confirms before running
Prop
Type
{ "visit_id": "visit_01m4k5z4j0fxbte6sn6e8tpgza", "status": "checked_out", "checked_out_at": "2026-10-14T13:12:40Z" }A visit in any other status, including one already checked out, returns invalid_state.
People
find_person
Looks up hosts and employees by name, email, department or job title, mostly so the assistant can get a person_… ID for another tool.
Scope people:read · Annotations read-only
Prop
Type
{
"people": [
{
"person_id": "person_01kjsesxm0e4zbyvkr7bcfxbfg",
"name": "Kwame Mensah",
"email": "k***@voltabank.example",
"department": "Treasury",
"job_title": "Head of Treasury",
"sites": ["Ridge HQ"],
"active": true
}
],
"has_more": false
}Deliveries
list_deliveries
Parcels, envelopes and food logged at reception, for a person, a team or the front desk: waiting (received or notified), collected, returned (sent back) or refused. Never a collection code.
Scope deliveries:read · Annotations read-only
Prop
Type
{
"deliveries": [
{
"delivery_id": "delivery_01j26w14wmchwyfgcw8t7swm4f",
"status": "notified",
"recipient_type": "person",
"recipient_name": "Kwame Mensah",
"team_name": null,
"kind": "envelope",
"carrier": "DHL",
"description": "Document envelope",
"location": "Shelf B",
"site_name": "Ridge HQ",
"received_at": "2026-10-14T08:47:19Z",
"reminders_sent": 0,
"collected_at": null,
"collection_method": null,
"returned_at": null
}
],
"next_cursor": null,
"has_more": false
}Bookings
find_available_slots
Free times for a booking type over a date range, after working hours, buffers, minimum notice, daily caps and Ghana public holidays are applied.
Scope bookings:read · Annotations read-only
Prop
Type
{
"booking_type": { "id": "btype_01jv4dk79q9g8xe6szaeavsntc", "name": "Consultation", "duration_minutes": 30, "meeting_kind": "in_person" },
"time_zone": "Africa/Accra",
"slots": [
{ "start_at": "2026-10-15T09:00:00Z", "end_at": "2026-10-15T09:30:00Z" },
{ "start_at": "2026-10-15T11:30:00Z", "end_at": "2026-10-15T12:00:00Z" }
],
"has_more": true
}create_booking
Books a slot for someone. Most bookings are confirmed straight away, and the attendee and host get the usual confirmation and reminders. If the booking type requires the host's confirmation, the booking is pending instead: it holds the slot, the attendee is told their request was received, and the host is asked to confirm or decline it. In-person bookings become expected visits with a pass once they're confirmed, as they do from your booking page.
Scope bookings:write · Annotations write, openWorldHint: true · Confirms before running
Prop
Type
{
"booking_id": "booking_01jvgs9zm5h3bv4h15g5e4g7x0",
"status": "confirmed",
"booking_type_name": "Consultation",
"start_at": "2026-10-15T09:00:00Z",
"end_at": "2026-10-15T09:30:00Z",
"attendee_name": "Ama Owusu",
"visit_id": "visit_01j9x9yp981068vcd1gdjfmgt8"
}For a pending booking, status is "pending" and visit_id is null until the host confirms it. The assistant should say the booking is a request, not that it's confirmed.
If someone else took the slot first, the tool returns conflict and the assistant should call find_available_slots again. Booking types with required intake questions can't be booked here; the tool returns validation_failed and the assistant should share your booking page instead.
cancel_booking
Cancels a confirmed booking, frees the slot and tells the attendee. For an in-person booking, its expected visit is cancelled too. A booking that isn't confirmed returns invalid_state: one that is already cancelled, so calling it again changes nothing, and one that is still pending, which the host confirms or declines in Agoo instead.
Scope bookings:write · Annotations write, destructive, idempotent, openWorldHint: true · Confirms before running
Prop
Type
{ "booking_id": "booking_01jvgs9zm5h3bv4h15g5e4g7x0", "status": "cancelled", "attendee_notified": true }Attendance
attendance_summary
Counts of present, late, on leave and absent staff for a date range, by day, for one site or the whole organisation. Use it for questions like "How many people were late at the Kumasi Office last week?"
Scope attendance:read · Annotations read-only
Prop
Type
{
"from": "2026-10-05",
"to": "2026-10-09",
"site_name": "Kumasi Office",
"totals": { "present": 182, "late": 14, "on_leave": 6, "absent": 3 },
"days": [{ "date": "2026-10-05", "present": 36, "late": 5, "on_leave": 1, "absent": 1 }]
}Each person on attendance is counted once per day, in exactly one group: present (on time), late, on_leave or absent. These are the same counts as GET /attendance/summary.
attendance_today
Who on your team, or at one site, is in, not in yet, on a break, absent or on leave today. Use it for questions like "Who's away from the Tema Branch today?" Private kinds of leave, such as sick leave, show as away unless the person connecting is HR.
Scope attendance:read · Annotations read-only
Prop
Type
leave_balance
A person's balance for each kind of leave this leave year: entitled, carried over, taken, booked, waiting for approval and what's left. Use it for "How much annual leave do I have left?" A line manager sees their own people's balances, except private kinds; anyone sees their own.
Scope attendance:read · Annotations read-only
Prop
Type
request_leave
Asks for leave for the person connecting, exactly as Request leave in the Workspace app does: it counts the days, checks the balance and sends it to whoever approves. The assistant shows the days and the balance after, and asks the person to confirm first. It asks only for the person connecting, never for someone else.
Scope attendance:write · Annotations write
Prop
Type
open_approvals
Leave requests and timesheets waiting for the person connecting to decide: their own people's, those they cover as a deputy, those moved on to them, and HR's for HR. A leave request has the person, the days, the balance after and who else is away then; a timesheet has the period, its totals and anything left to fix before it can be approved. Deciding stays in the Workspace app or the Console.
Scope attendance:read · Annotations read-only
my_shifts
The published roster shifts of the person connecting, for a date range: the site, the times, the shift's name, label and break, and any note from their manager. Use it for "When am I on nights next week?" It never shows a draft or someone else's shifts.
Scope attendance:read · Annotations read-only
Prop
Type
open_shifts
Open shifts on published rosters. For the person connecting, the ones they can claim (at their sites, not on leave that day, with no other shift then), soonest first. For a manager, with site_id, every open shift at that site with how many claims are waiting. Claiming stays in the Workspace app.
Scope attendance:read · Annotations read-only
Prop
Type
swaps_waiting
Shift swaps and claims for open shifts waiting for the person connecting to decide: their own people's, those they cover as a deputy, those moved on to them, and HR's for HR. Each has the people, the shifts and when they were asked for. Deciding stays in the Workspace app or the Console.
Scope attendance:read · Annotations read-only
payroll_exports
The payroll files made for your organisation, for one timesheet period or the latest ones: each file's number, period and payroll date, sites, format and layout, how many people, lines and corrections it has, whether a later file supersedes it, who made it and when, and its checksum. Use it for "Has September's payroll file been made, and does it carry any corrections?" It never returns a file's lines; making and downloading files stay in the Console and the API. Someone whose role covers some sites only sees files made for those sites. Needs the payroll export (Pro and Enterprise).
Scope attendance:payroll · Annotations read-only
Prop
Type
roll_call_status
The live state of a roll call during an evacuation or drill: who is accounted for and who is still missing, across visitors, contractors and clocked-in staff.
Scope rollcalls:read · Annotations read-only
Prop
Type
{
"rollcall_id": "rollcall_01j01cyfw6vzskdenc8sp3804g",
"site_name": "Tema Branch",
"status": "open",
"started_at": "2026-10-14T11:00:04Z",
"total": 44,
"accounted_for": 41,
"missing": [
{ "name": "Ama Owusu", "kind": "visitor", "last_seen": "Main gate, 11:02" },
{ "name": "Nii Armah", "kind": "employee", "department": "Operations", "last_seen": "Clocked in 07:58" }
]
}During a roll call, the console and the Workspace app are the source of truth for wardens. The tool is for following progress and reporting afterwards.
Audit
search_audit_log
Searches your organisation's audit trail: who did what, when, from where.
Scope audit:read · Annotations read-only
Prop
Type
{
"entries": [
{
"audit_id": "audit_01j9rmz9j92v81e5128q6rw31f",
"at": "2026-10-12T07:41:55Z",
"actor": "Esi Darko",
"via": "Console",
"action": "device.updated",
"object": { "id": "dev_01j9ngk80y3zh6dzjjxxx7ck5y", "name": "Lobby kiosk" },
"ip": "102.176.x.x"
}
],
"next_cursor": "…",
"has_more": true
}The audit trail is only available to roles that can see it, such as admins and auditors. Searches through MCP are themselves recorded.
Resources
Resources are read-only context that a client can attach to a conversation, for example from the + menu in Claude.
| URI | Contents | Scope |
|---|---|---|
agoo://organisation | The organisation, its plan, its sites and its booking types, as JSON (application/json). | organisation:read |
agoo://sites/{site_id} | One site: address, time zone, gates, kiosks and their status, and opening hours, as JSON. A resource template. | sites:read |
Prompts
Prompts are ready-made requests that a client can offer as shortcuts, such as slash commands.
front_desk_briefing
A briefing for the start of a shift: who is expected and when, VIPs and interview candidates, visits waiting for approval, deliveries waiting for collection, and anyone still checked in from yesterday.
Prop
Type
Uses search_visits, list_deliveries and who_is_on_site.
weekly_attendance_report
A short report on one week of attendance: totals, lateness by day, absences, and changes from the week before.
Prop
Type
Uses attendance_summary for the week and the week before.