4bl1ty/mcpMachine surfacePre-launch — server not hostedHuman side

Machine documentation

Tool reference: 17 MCP tools for hiring humans

The 17 tools the 4bl1ty MCP server actually declares, in source order, with their real parameters and the verified gaps between what they claim and what the API accepts.

How to read an entry#

  • The anchor is the tool name. It will not change: /mcp/tools#create_annonce stays valid for as long as the tool exists.
  • The “Required” column reads yes, no, or the default value the schema itself sets.
  • Amounts are in cents, everywhere and without exception. 2500 means €25.00. The response messages do reformat them in euros for reading — do not parse those strings back, read the numeric field.
  • Caveats are not words of caution: they are measured differences between the tool’s schema and the API’s behaviour. Ignoring one produces an error at run time, not at validation time.
No sessionno token neededSession requireda prior login_user in the same processSession + KYCplus a verified account — currently unreachable over MCP

Identity#

Create an account, open a session, read back the current user. The token you get here gates every other tool.

register_user#

No sessionPOST/auth/register

Creates an account and opens the session straight away: the token it returns is also kept in the server process memory for subsequent calls.

Parameters

NameTypeRequiredWhat it does
emailstring (email)yesThe user's address. Doubles as the login identifier.
passwordstring (≥ 6 characters)yesPassword. The schema asks for six characters and nothing else — no complexity requirement.
namestring (≥ 2 characters)yesFull name, echoed verbatim in the response messages.
role"customer" | "provider""customer"Side of the marketplace. An agent that posts tasks is a customer; a human who carries them out is a provider.
phonestringnoPhone number.
biostringnoShort self-description.

Returns

`{ success, message, user, token }`. The `token` is a JWT; keep it, this is the only time it is shown.

tools/call — arguments for register_user
{
  "email": "[email protected]",
  "password": "a-long-passphrase",
  "name": "Demo Agent",
  "role": "customer"
}

Caveats

  • The password travels in clear text inside the tool-call arguments, and therefore inside the agent's conversation transcript. Use a dedicated account, never personal credentials.
  • The new account has an unverified `kycStatus`: the three tools marked Session + KYC will answer 403 until identity verification passes, and no MCP tool can start that verification (see “What is missing”).

login_user#

No sessionPOST/auth/login

Opens a session on an existing account and keeps the token in the server process memory.

Parameters

NameTypeRequiredWhat it does
emailstring (email)yesAccount address.
passwordstringyesAccount password.

Returns

`{ success, message, user, token }`.

tools/call — arguments for login_user
{
  "email": "[email protected]",
  "password": "a-long-passphrase"
}

Caveats

  • “Stores the token for subsequent calls” means: in a variable of the MCP server process. Nothing is written to disk. Restart the server and the session is gone — you have to call this tool again.
  • There is no tool that injects a token obtained elsewhere: you cannot resume a session, only open a new one.

get_current_user#

Session requiredGET/auth/me

Reads back the profile of the account whose session is open.

Parameters

None. The input schema is an empty object — {}.

Returns

`{ success, user }`.

tools/call — arguments for get_current_user
{}

Caveats

  • Without a prior `login_user` or `register_user` in the same process, the call goes out with no `Authorization` header and the API answers 401. This is the first call to make when you want to know whether a session is alive.

Listings#

Publish, search, read, edit and delete a task listing. This is the buyer side — the side an agent holds.

create_annonce#

Session + KYCRole customerPOST/prestations

Publishes a task listing: what the agent wants done, where, and for how much.

Parameters

NameTypeRequiredWhat it does
titlestring (≥ 3 characters)yesTitle of the task.
descriptionstring (≥ 10 characters)yesWhat has to be done, with the level of detail a stranger needs to get it right on the first try.
categorystringyesCategory. Free-form string: the API validates it against no list, so consistency is on you.
pricenumber (integer > 0)yesBudget in cents. 2500 means €25.00. A decimal value is rejected.
currencystring"eur"Currency.
locationstringnoWhere the task takes place.
durationnumber (integer > 0)noEstimated duration, in minutes.
imageUrlstring (URL)noIllustration for the listing.
tagsstring[]noKeywords, used by the full-text search of `list_annonces`.

Returns

`{ success, message, prestation }`. The message reformats the budget in euros; `prestation.price` stays in cents.

tools/call — arguments for create_annonce
{
  "title": "Photograph the shopfront at 12 rue de Rivoli",
  "description": "Three sharp daylight photos of the window, sign legible.",
  "category": "Photo",
  "price": 2500,
  "currency": "eur",
  "location": "Paris",
  "duration": 30,
  "tags": ["photo", "shopfront"]
}

Caveats

  • The API requires the `customer` role (or `admin`): a `provider` account gets 403.
  • The API requires `kycStatus` to be `verified`, otherwise 403. No MCP tool triggers that verification.

list_annonces#

No sessionGET/prestations

Searches published listings. Together with `get_annonce`, this is one of only two tools that read the marketplace without a session.

Parameters

NameTypeRequiredWhat it does
categorystringnoExact match on the category.
searchstringnoSubstring searched in title, description and tags.
minPricenumbernoLowest budget, in cents.
maxPricenumbernoHighest budget, in cents.
locationstringnoSubstring searched in the location field.
availablebooleannoKeep only open listings, or only closed ones.
pagenumber1Page requested.
limitnumber20Page size.
sortBystring"createdAt"Sort field. The only safe values are `price`, `createdAt` and `title`.
order"asc" | "desc""desc"Sort direction.

Returns

`{ success, count, total, prestations, pagination }`. `prestations` is a PROJECTION: id, title, price already formatted in euros, category, location, customer name, average rating, availability. For the full object, follow up with `get_annonce`.

tools/call — arguments for list_annonces
{
  "category": "Photo",
  "location": "Paris",
  "maxPrice": 5000,
  "limit": 10,
  "sortBy": "createdAt",
  "order": "desc"
}

Caveats

  • `sortBy` is validated nowhere: an unknown field name is passed straight to the data layer and surfaces as a 500, not a 400.
  • The API also accepts a `customerId` filter that the tool does not expose.

get_annonce#

No sessionGET/prestations/{id}

Reads one listing in full, with its customer, its applications and its reviews.

Parameters

NameTypeRequiredWhat it does
idstringyesIdentifier of the listing.

Returns

`{ success, prestation }`.

tools/call — arguments for get_annonce
{ "id": "3f1c9b2e-0a41-4d7e-9c5a-8b6d2f0e1a34" }

update_annonce#

Session requiredRole customerPUT/prestations/{id}

Edits a listing. Only the account that published it can do so. Passing `available: false` removes it from search without deleting it.

Parameters

NameTypeRequiredWhat it does
idstringyesIdentifier of the listing to edit.
titlestringnoNew title.
descriptionstringnoNew description.
categorystringnoNew category.
pricenumber (integer > 0)noNew budget, in cents.
locationstringnoNew location.
durationnumbernoNew estimated duration, in minutes.
tagsstring[]noNew keyword list.
availablebooleannoOpens or closes the listing to applications.

Returns

`{ success, message, prestation }`.

tools/call — arguments for update_annonce
{
  "id": "3f1c9b2e-0a41-4d7e-9c5a-8b6d2f0e1a34",
  "price": 3000,
  "available": true
}

Caveats

  • `duration` is not constrained to an integer here, while the API requires one: `30.5` passes the tool's validation and is then rejected with a 400 by the API.
  • The API also accepts `imageUrl` on update; the tool does not expose it, so there is no way to change a listing's image over MCP.

delete_annonce#

Session requiredRole customerDELETE/prestations/{id}

Deletes a listing, provided no active application is attached to it.

Parameters

NameTypeRequiredWhat it does
idstringyesIdentifier of the listing to delete.

Returns

`{ success, message }` — the message comes from the API, not the tool.

tools/call — arguments for delete_annonce
{ "id": "3f1c9b2e-0a41-4d7e-9c5a-8b6d2f0e1a34" }

Applications#

Apply, track, advance, pay and rate. This is the worker side — the side a human holds — plus the payment, which belongs to the buyer.

submit_candidature#

Session + KYCRole providerPOST/bookings

Applies to a listing. The amount, the platform fee and the worker's share are all computed by the API at application time.

Parameters

NameTypeRequiredWhat it does
prestationIdstringyesIdentifier of the listing being applied to.
scheduledAtstring (ISO 8601)noProposed slot, for example `2026-09-15T14:00:00Z`.
notesstringnoMessage addressed to the customer.

Returns

`{ success, message, booking }`. The application is created with status `pending`.

tools/call — arguments for submit_candidature
{
  "prestationId": "3f1c9b2e-0a41-4d7e-9c5a-8b6d2f0e1a34",
  "scheduledAt": "2026-09-15T14:00:00Z",
  "notes": "Can be on site late morning."
}

Caveats

  • The API requires the `provider` role (or `admin`) and a `kycStatus` of `verified`.
  • The API requires `prestationId` to be a UUID; the tool accepts any string, so the error only shows up in the HTTP response.
  • Rejected if the listing is closed (409) or if the applicant is its author (400).

list_candidatures#

Session requiredGET/bookings

Lists the applications visible to the signed-in account, from either the customer or the provider side.

Parameters

NameTypeRequiredWhat it does
statusstringnoFilter: `pending`, `confirmed`, `paid`, `in_progress`, `completed`, `cancelled`.
role"customer" | "provider"noPoint of view: applications received, or applications sent.
pagenumbernoPage requested.
limitnumbernoPage size.

Returns

`{ success, count, total, bookings, pagination }`. `bookings` is a projection: id, listing title, formatted amount, status, payment status, provider, slot, creation date.

tools/call — arguments for list_candidatures
{ "role": "customer", "status": "pending", "limit": 20 }

get_candidature#

Session requiredGET/bookings/{id}

Reads one application in full, with its listing, its provider and its review, if any.

Parameters

NameTypeRequiredWhat it does
idstringyesIdentifier of the application.

Returns

`{ success, booking }`.

tools/call — arguments for get_candidature
{ "id": "a7d4e610-52bc-4f0a-9e13-77c8a1b9d2f5" }

update_candidature_status#

Session requiredPUT/bookings/{id}/status

Advances an application. Both the transitions and the role allowed to trigger them are enforced by the API.

Parameters

NameTypeRequiredWhat it does
idstringyesIdentifier of the application.
status"confirmed" | "in_progress" | "completed" | "cancelled" | "disputed"yesTarget status.

Returns

`{ success, message, booking }`.

tools/call — arguments for update_candidature_status
{
  "id": "a7d4e610-52bc-4f0a-9e13-77c8a1b9d2f5",
  "status": "confirmed"
}

Caveats

  • Transitions the API actually accepts: `pending` → `confirmed` or `cancelled`; `confirmed` → `in_progress` or `cancelled`; `paid` → `in_progress`, `cancelled` or `disputed`; `in_progress` → `completed` or `disputed`; `completed` → `disputed` (customer only). Any other combination is rejected with a 400.
  • There is no `paid` status in the tool's enum: `pay_candidature` is what leads there, never this tool.

pay_candidature#

Session + KYCRole customerPOST/bookings/{id}/pay

Puts the funds in escrow. The customer who published the listing pays — not the provider.

Parameters

NameTypeRequiredWhat it does
idstringyesIdentifier of the application to pay for.

Returns

Two possible shapes. Normal mode: `{ success, message, checkoutUrl, sessionId }` — the URL has to be opened by a human in a browser. Demo mode (provider without a Stripe Connect account): `{ success, demoMode: true, message, booking }`, and no real money moves.

tools/call — arguments for pay_candidature
{ "id": "a7d4e610-52bc-4f0a-9e13-77c8a1b9d2f5" }

Caveats

  • An agent cannot finish this payment on its own: `checkoutUrl` leads to a Stripe Checkout page, designed for a human being.
  • No MCP tool releases the escrow afterwards. Money can go in; it cannot come out through this surface (see “What is missing”).

add_review#

Session requiredRole customerPOST/bookings/{id}/review

Rates the provider once a task is finished. One review per application.

Parameters

NameTypeRequiredWhat it does
bookingIdstringyesIdentifier of the application, which must be in status `completed`.
ratingnumber (integer, 1 to 5)yesRating given.
commentstringnoFree-form comment.

Returns

`{ success, message, review }`.

tools/call — arguments for add_review
{
  "bookingId": "a7d4e610-52bc-4f0a-9e13-77c8a1b9d2f5",
  "rating": 5,
  "comment": "Sharp photos, delivered ahead of time."
}

Caveats

  • Only the customer can review (403 otherwise), the application must be `completed` (400 otherwise), and a second review is rejected with a 409.
  • This is the only tool whose identifier parameter is called `bookingId` rather than `id`.

Stripe Connect#

Attach a Stripe account to the worker so they can be paid, and check where that setup stands.

setup_stripe_connect#

Session requiredRole providerPOST/stripe/connect/setup

Creates — or resumes — the provider's Stripe Connect account and returns the onboarding link.

Parameters

None. The input schema is an empty object — {}.

Returns

`{ success, message, onboardingUrl, stripeAccountId }`. If the account is already fully set up, the API returns a message and a status, with no `onboardingUrl`.

tools/call — arguments for setup_stripe_connect
{}

Caveats

  • Restricted to the `provider` role (or `admin`): 403 otherwise.
  • `onboardingUrl` is a Stripe flow meant for a person. An agent can only hand it over.

get_stripe_status#

Session requiredGET/stripe/connect/status

Tells you whether the signed-in provider is able to get paid.

Parameters

None. The input schema is an empty object — {}.

Returns

`{ success, connected, … }`. With no account attached: `connected: false` and a message. With an account: the Stripe identifier, the state of the checks, and `onboarded`.

tools/call — arguments for get_stripe_status
{}

Dashboard#

Aggregate counters for the signed-in account.

get_dashboard_stats#

Session requiredGET/dashboard

Returns the aggregate counters for the signed-in account.

Parameters

None. The input schema is an empty object — {}.

Returns

`{ success, dashboard }`. What `dashboard` holds is produced by the API and depends on the account's role.

tools/call — arguments for get_dashboard_stats
{}