Boulevard MCP by usefulapi

Look up appointments, clients, services, staff and orders, and update clients in Boulevard.

Should I use this

Quality & Safety

A
Description quality
97%
Schema completeness
93%
Naming quality
80%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~4,203Tokens (tool definitions)
~1.5 KBTypical response size
Significant attention impact (3.28% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "boulevard": {
      "url": "https://boulevard.usefulapi.io/mcp"
    }
  }
}

Remote endpoints

https://boulevard.usefulapi.io/mcpstreamable-http

What it can do

Tool inventory

Tools (21)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢boulevard_get_business

Fetch the Boulevard business the credentials act for — name, timezone, address, phone, website. A cheap way to confirm the setup works. GraphQL: business.

Input Schema

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_locations(first, after)

List the business's locations with id, name, timezone and address. Most other tools need a location id from here. GraphQL: locations.

Input Schema

{
  "type": "object",
  "properties": {
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_appointments(location_id, client_id, query, first, after)

List appointments at one location, optionally for one client and filtered by a query such as a date range or staff member. Each appointment includes its client, services, staff, state and cancellation. GraphQL: appointments.

Input Schema

{
  "type": "object",
  "properties": {
    "location_id": {
      "type": "string",
      "minLength": 1,
      "description": "Location id, e.g. urn:blvd:Location:<uuid> (from boulevard_list_locations)."
    },
    "client_id": {
      "description": "Only this client's appointments (urn:blvd:Client:<uuid>).",
      "type": "string"
    },
    "query": {
      "description": "Boulevard filter expression (QueryString) over: id, startAt, createdAt, cancelled, staffId. Comparisons joined with AND/OR, strings in single quotes, ISO 8601 datetimes, e.g. \"startAt >= '2026-10-01T00:00:00Z' AND cancelled = false\". Field names are case sensitive.",
      "type": "string"
    },
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "required": [
    "location_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_get_appointment(appointment_id)

Fetch one appointment by id — time, state, notes, client, each booked service with its staff and price (in cents), cancellation details and tags. GraphQL: appointment.

Input Schema

{
  "type": "object",
  "properties": {
    "appointment_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Appointment id, e.g. urn:blvd:Appointment:<uuid>."
    }
  },
  "required": [
    "appointment_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_clients(query, emails, client_ids, first, after)

List the business's clients, or find them by email, id list, or a query (e.g. name = 'Jane Doe', mobilePhone = '+15551234567'). GraphQL: clients.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "description": "Boulevard filter expression (QueryString) over: id, email, name, mobilePhone, active, externalId, primaryLocation, createdAt, updatedAt. Comparisons joined with AND/OR, strings in single quotes, ISO 8601 datetimes, e.g. \"startAt >= '2026-10-01T00:00:00Z' AND cancelled = false\". Field names are case sensitive.",
      "type": "string"
    },
    "emails": {
      "description": "Only clients with these email addresses.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "client_ids": {
      "description": "Only these client ids.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_get_client(client_id)

Fetch one client by id, including contact details, appointment count, account balance (cents), scheduling alert, tags and notes. GraphQL: client.

Input Schema

{
  "type": "object",
  "properties": {
    "client_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Client id, e.g. urn:blvd:Client:<uuid>."
    }
  },
  "required": [
    "client_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_services(first, after)

List the service menu — name, category, default duration (minutes) and default price (cents), and whether it is an add-on. GraphQL: services.

Input Schema

{
  "type": "object",
  "properties": {
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_staff(query, first, after)

List staff members with their role, locations, contact details and whether they are bookable online, optionally filtered by a query. GraphQL: staff.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "description": "Boulevard filter expression (QueryString) over: id, email, name, mobilePhone, active. Comparisons joined with AND/OR, strings in single quotes, ISO 8601 datetimes, e.g. \"startAt >= '2026-10-01T00:00:00Z' AND cancelled = false\". Field names are case sensitive.",
      "type": "string"
    },
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_shifts(location_id, start_date, end_date, staff_ids)

List staff working shifts at one location for a date range — clock-in/out times, weekday, availability and recurrence. GraphQL: shifts.

Input Schema

{
  "type": "object",
  "properties": {
    "location_id": {
      "type": "string",
      "minLength": 1,
      "description": "Location id, e.g. urn:blvd:Location:<uuid> (from boulevard_list_locations)."
    },
    "start_date": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "First date, YYYY-MM-DD."
    },
    "end_date": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Last date, YYYY-MM-DD."
    },
    "staff_ids": {
      "description": "Only these staff ids.",
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "location_id",
    "start_date",
    "end_date"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_timeblocks(location_id, query, first, after)

List blocked time on staff calendars at one location (breaks, meetings, personal time). GraphQL: timeblocks.

Input Schema

{
  "type": "object",
  "properties": {
    "location_id": {
      "type": "string",
      "minLength": 1,
      "description": "Location id, e.g. urn:blvd:Location:<uuid> (from boulevard_list_locations)."
    },
    "query": {
      "description": "Boulevard filter expression (QueryString) over: staffId, startAt, cancelled. Comparisons joined with AND/OR, strings in single quotes, ISO 8601 datetimes, e.g. \"startAt >= '2026-10-01T00:00:00Z' AND cancelled = false\". Field names are case sensitive.",
      "type": "string"
    },
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "required": [
    "location_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_orders(location_id, query, first, after)

List checkout orders at one location with totals (cents: subtotal, discount, tax, gratuity, total, refunds), optionally filtered e.g. by closedAt range or clientId. GraphQL: orders.

Input Schema

{
  "type": "object",
  "properties": {
    "location_id": {
      "type": "string",
      "minLength": 1,
      "description": "Location id, e.g. urn:blvd:Location:<uuid> (from boulevard_list_locations)."
    },
    "query": {
      "description": "Boulevard filter expression (QueryString) over: id, clientId, closedAt, updatedAt, createdAt. Comparisons joined with AND/OR, strings in single quotes, ISO 8601 datetimes, e.g. \"startAt >= '2026-10-01T00:00:00Z' AND cancelled = false\". Field names are case sensitive.",
      "type": "string"
    },
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "required": [
    "location_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_get_order(order_id)

Fetch one order by id with its totals and line items (services, products, gratuity, gift cards), amounts in cents. GraphQL: order.

Input Schema

{
  "type": "object",
  "properties": {
    "order_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Order id, e.g. urn:blvd:Order:<uuid>."
    }
  },
  "required": [
    "order_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_products(query, include_inactive, first, after)

List retail products — brand, SKU, barcode, unit price and cost (cents), category. Set include_inactive to include retired products. GraphQL: products.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "description": "Boulevard filter expression (QueryString) over: id, categoryId, externalId. Comparisons joined with AND/OR, strings in single quotes, ISO 8601 datetimes, e.g. \"startAt >= '2026-10-01T00:00:00Z' AND cancelled = false\". Field names are case sensitive.",
      "type": "string"
    },
    "include_inactive": {
      "description": "Also return inactive products.",
      "type": "boolean"
    },
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_memberships(first, after)

List client memberships sold by the business — status (ACTIVE, PAUSED, PAST_DUE, CANCELLED), client, price (cents), interval, term and next charge date. GraphQL: memberships.

Input Schema

{
  "type": "object",
  "properties": {
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢boulevard_list_tags(first, after)

List the tags defined for the business (ids to use with boulevard_add_tag). GraphQL: tags.

Input Schema

{
  "type": "object",
  "properties": {
    "first": {
      "description": "Page size, 1-100 (default 25).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "after": {
      "description": "Cursor: pageInfo.endCursor from the previous page. Omit for the first page.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴boulevard_create_client(first_name, last_name, email, mobile_phone, dob, ...)

Create a new client profile. Check boulevard_list_clients by email or phone first to avoid a duplicate. GraphQL: createClient.

Input Schema

{
  "type": "object",
  "properties": {
    "first_name": {
      "description": "First name.",
      "type": "string"
    },
    "last_name": {
      "description": "Last name.",
      "type": "string"
    },
    "email": {
      "description": "Email address.",
      "type": "string",
      "format": "email",
      "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "mobile_phone": {
      "description": "Mobile phone in E.164 form, e.g. +15551234567.",
      "type": "string"
    },
    "dob": {
      "description": "Date of birth, YYYY-MM-DD.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "pronoun": {
      "description": "Pronoun, e.g. she/her.",
      "type": "string"
    },
    "external_id": {
      "description": "Your own id for this client.",
      "type": "string"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴boulevard_update_client(client_id, first_name, last_name, email, mobile_phone, ...)

Change a client's name, email, mobile phone, date of birth, pronoun or external id. Only the fields you pass change. GraphQL: updateClient.

Input Schema

{
  "type": "object",
  "properties": {
    "client_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Client id, e.g. urn:blvd:Client:<uuid>."
    },
    "first_name": {
      "description": "First name.",
      "type": "string"
    },
    "last_name": {
      "description": "Last name.",
      "type": "string"
    },
    "email": {
      "description": "Email address.",
      "type": "string",
      "format": "email",
      "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    },
    "mobile_phone": {
      "description": "Mobile phone in E.164 form, e.g. +15551234567.",
      "type": "string"
    },
    "dob": {
      "description": "Date of birth, YYYY-MM-DD.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "pronoun": {
      "description": "Pronoun, e.g. she/her.",
      "type": "string"
    },
    "external_id": {
      "description": "Your own id for this client.",
      "type": "string"
    }
  },
  "required": [
    "client_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴boulevard_create_client_note(client_id, text)

Add an internal note to a client's profile (visible to staff, e.g. formulas, preferences, allergies). GraphQL: createClientNote.

Input Schema

{
  "type": "object",
  "properties": {
    "client_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Client id, e.g. urn:blvd:Client:<uuid>."
    },
    "text": {
      "type": "string",
      "minLength": 1,
      "description": "The note text."
    }
  },
  "required": [
    "client_id",
    "text"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴boulevard_update_appointment(appointment_id, notes, state)

Replace an appointment's internal notes and/or move its state to BOOKED, CONFIRMED, ARRIVED or ACTIVE (e.g. confirm, or check the client in). Does not cancel or reschedule. GraphQL: updateAppointment.

Input Schema

{
  "type": "object",
  "properties": {
    "appointment_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Appointment id, e.g. urn:blvd:Appointment:<uuid>."
    },
    "notes": {
      "description": "New internal notes (replaces the existing notes).",
      "type": "string"
    },
    "state": {
      "description": "New appointment state.",
      "type": "string",
      "enum": [
        "BOOKED",
        "CONFIRMED",
        "ARRIVED",
        "ACTIVE"
      ]
    }
  },
  "required": [
    "appointment_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴boulevard_create_timeblock(location_id, staff_id, start_time, duration, title, ...)

Block time on one staff member's calendar at a location (a break, meeting or personal time) so it cannot be booked. One-off only. GraphQL: createTimeblock.

Input Schema

{
  "type": "object",
  "properties": {
    "location_id": {
      "type": "string",
      "minLength": 1,
      "description": "Location id, e.g. urn:blvd:Location:<uuid> (from boulevard_list_locations)."
    },
    "staff_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Staff id, e.g. urn:blvd:Staff:<uuid>."
    },
    "start_time": {
      "type": "string",
      "minLength": 1,
      "description": "Start, ISO 8601 datetime with offset, e.g. 2026-10-02T13:00:00-07:00."
    },
    "duration": {
      "type": "integer",
      "minimum": 1,
      "maximum": 1440,
      "description": "Length in minutes."
    },
    "title": {
      "description": "Title shown on the calendar.",
      "type": "string"
    },
    "reason": {
      "description": "Why the time is blocked.",
      "type": "string",
      "enum": [
        "BUSINESS",
        "PERSONAL"
      ]
    }
  },
  "required": [
    "location_id",
    "staff_id",
    "start_time",
    "duration"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴boulevard_add_tag(entity_id, tag_id)

Apply an existing tag (from boulevard_list_tags) to a taggable record such as a client or appointment. GraphQL: addTag.

Input Schema

{
  "type": "object",
  "properties": {
    "entity_id": {
      "type": "string",
      "minLength": 1,
      "description": "Global id of the record to tag, e.g. urn:blvd:Client:<uuid>."
    },
    "tag_id": {
      "type": "string",
      "minLength": 1,
      "description": "The Tag id, e.g. urn:blvd:Tag:<uuid>."
    }
  },
  "required": [
    "entity_id",
    "tag_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded21 tools
verifiedversion not recorded21 tools