Skip to content

The agent's tools ​

Accepted direction (owner, 19 October 2026) · steps 1 to 3 and the solver's tools built in the API and the app: the catalog, its read tools, the manager's schedule proposals, the solver's three tools and, since step 3, proposals for the store's people and the store, tested against an in-memory Agentfy and checked against a local Agentfy, not deployed · since 20 October 2026 the solver's tools take people's constraints read from their descriptions, tested against an in-memory Agentfy and checked once against a local Agentfy, not deployed; since the same day they hand the descriptions to the agent themselves when it passes none, tested against an in-memory Agentfy, checked once against a local Agentfy, not deployed; and the store's own rules from its description, tested against an in-memory Agentfy, checked once against a local Agentfy, not deployed · step 4 is a plan · the owner's assistant and its tools (owner, 20 October 2026) built, tested against an in-memory Agentfy and checked once against a local Agentfy, not deployed · creating a store, a store's time zone and status, and several invitations in one card (23 October 2026) built and tested against an in-memory Agentfy, not checked against a local Agentfy, not deployed · since 26 October 2026 the solver's plans and cover may use custom hours it sets itself, marked on the card, tested against an in-memory Agentfy, not checked against a local Agentfy, not deployed · a card mentioned only when a tool made one, and the chat's note when a reply speaks of one it did not make (owner, 28 October 2026), tested against an in-memory Agentfy, checked once against a local Agentfy, not deployed · since 28 October 2026 they cover every opening hour with at least one person by default and say on the card which hours stay with nobody, tested on a store written by the test, not checked against a local Agentfy, not deployed · since 30 October 2026 a person's position comes from the team's list of positions, by name, with its description; tested against an in-memory Agentfy, not checked against a local Agentfy, not deployed · since 30 October 2026 a failed call says why (wrong arguments by field, refusals in their own words, faults logged), tested against an in-memory Agentfy, not checked against a local Agentfy, not deployed · since 30 October 2026 the solver's tools take constraints, empty or not, only with the fingerprint of the descriptions they handed over, tested through the tools on the seeded demo stores and against an in-memory Agentfy, not checked against a local Agentfy, not deployed · since 5 November 2026 solve_week asks for missing descriptions before it plans and the owner's assistant writes a position's description with edit_position, tested over the real /mcp against an in-memory Agentfy, not checked with a live agent, not deployed · since 10 November 2026 the rules read from descriptions stored next to them (save_rules), tested through the tools on a store written by the test and on a copy of the owner's local data, not checked with a live agent, not deployed · since 11 November 2026 the owner's assistant creates a position (create_position), and a store's people answer a colleague's ask (answer_colleague) and confirm their published week (confirm_week), each as a card, tested over the real /mcp against an in-memory Agentfy, not checked with a live agent, not deployed · since 11 November 2026 a swap or a cover named by the colleague's name and the dates, every fitting shift of a colleague in find_cover, weekdays next to dates, and dates far from today refused, tested over the real /mcp against an in-memory Agentfy, not checked with a live agent, not deployed

The store assistant is meant to do, in the end, everything the signed-in manager or employee can do in Shiffty, with that person's rights and through the same rules as the app — except publishing a schedule, which stays a person's action. Deciding a change request comes with the solver: the assistant prepares the decision, the manager confirms it.

One catalog of tools, written for a model: each tool is a task a person would ask for, and each calls the same code the app's screens call.

What the owner decided ​

On 19 October 2026 the owner set four rules for the assistant's tools:

  1. The agent does not approve or decline change requests and does not publish a schedule — for now. Later a solver will be added, and with it the agent will build schedules and decide requests. Until then, tools for those three actions do not exist at all, not even switched off.
  2. No assistant for the owner or for the whole company. There is one agent per store, as before; the owner keeps doing the owner's things in the app. Replaced on 20 October 2026: the owner gets an assistant with the owner's rights over the whole company (below).
  3. Apart from rule 1, nothing is off limits. The agent may do whatever the signed-in person is allowed to do in the app, always with that person's own rights, checked by the same rules as the app. When a manager may change something by hand, the assistant may help them change it; when they may not, the assistant may not either.
  4. Tools are chosen and written by hand, not generated from the API. A tool is the size of a task ("who is short on Saturday?"), not of an endpoint, and its description is written for a model: what it answers, in which units, with which limits.

Later the same day the owner added the solver (19 October 2026): with it the agent builds a week and weighs and decides change requests. That lifts rule 1 for approving and declining — as propose tools only: the manager confirms each decision in the app, and the confirmation runs the ordinary approve or decline with the manager's rights. Publishing a week stays a person's action: there is no tool for it. Undoing a decision is not a tool either. See the solver's tools.

On 20 October 2026 the owner replaced rule 2: the owner gets an assistant of their own, one per company, with everything the owner may do in the app — every store, managers included. Every change stays a card the owner confirms; the API checks the rules again on confirmation. Publishing a week becomes possible for the owner only, as a card the owner confirms — the owner still publishes by confirming; a manager's assistant still cannot publish. Rights come only from the conversation, never from the model. See the owner's tools.

The decisions are also listed in Open questions.

How a tool is built ​

Each part of the API declares its own tools next to its screens' routes — the schedule's, the store's, the people's and the requests' — and one registry collects them for the agent. Every tool has:

  • a name that never changes once agents use it;
  • a description for the model;
  • a strict list of arguments: an argument the tool does not know is refused, and no argument may name a person, a role or a permission — who is asking always comes from the conversation's grant (how a call is authorised). One exception since 20 October 2026: storeId names which store a tool works on, a target checked against the asker's rights — the owner names any store of the company, a manager or an employee only their own, and anything else is not found;
  • who may use it: employees, managers, the owner (since 20 October 2026), or several of them;
  • a level: read, propose or direct (below);
  • the capability the conversation's grant has to hold.

The registry refuses to start when a tool breaks one of these rules, when a tool or an action would publish unless it is the owner's propose tool, or when a tool that approves, declines or decides a request is anything but propose. Every call is journaled by tool name and outcome, never by its arguments. Since 30 October 2026 a call that fails says why: arguments that do not fit the tool come back as invalid_arguments, naming each wrong field and why, so the model can fix its call; a refusal the rules mean — a missing or expired conversation permission, a tool not for the asker's role — comes back with its own words; and a fault in Shiffty is journaled as tool_failed and written to the server log with its stack and ids only, while the model gets only that the call failed (until then all three came back as the same bare refusal and nothing was logged).

Three levels ​

LevelWhat happensExample
readRuns at once and changes nothing.The week grid, a day with its coverage
proposePrepares a change and shows it in the chat as a card. Nothing changes until the person confirms the card in the app (for a change request the button is Send request); the confirmation checks the rules again as they are at that moment and then makes the change.Check a day off: the card "Send this request?"
directChanges something at once — only the person's own, low-risk answers, after they said yes in the conversation. Since 10 November 2026 also the rules the assistant read from descriptions the person already confirmed (save_rules), which the app shows under each description.Send my confirmed request; save the rules read from the descriptions

The cards are the same ones the chat has shown since SHIF-20. Since step 2 a card can carry any proposed action: a change request, a new week, a change to a week, the shift templates, the hourly load. Each card shows a title, what will change in plain words, one line per change, and the warnings of the checks.

A card only when a tool made one ​

Owner's decision of 28 October 2026; built in the API and the app, tested against an in-memory Agentfy and checked once against a local Agentfy, not deployed. That day the owner's assistant wrote "the changes are ready, confirm the card on the Schedules page" in replies that had called no tool, so there was no card — and cards are in the chat, not on the Schedules page. Confirming stays the card's button; typing "I confirm" confirms nothing.

  • What the assistant is told. It mentions a card, or says a change is ready, only when a tool in the same reply returned one. A request to change something goes to its tool in that reply, never a promise. When the person types "I confirm", it says that the button on the card does that, points to an open card from earlier when it is the change meant, and makes a new card when the request has changed. It never says anything was applied unless a tool or a confirmed card says so.
  • What the chat does when it says so anyway. Under a reply that speaks of a card it did not make, a quiet line says "No card was created in this reply — ask again to get one", or, when an earlier card is still open, points to that card. A typed confirmation highlights the open card and scrolls to it. A card from an earlier reply stays in the conversation and can still be confirmed.
  • What is not solved. The assistant can still word things wrongly — once it said a card "should appear below" when the card was from an earlier reply. And when one of a reply's tool calls fails, the whole reply ends in an error even if the assistant recovered; a card made in that reply shows only after the conversation is reloaded.

What is built: step 1 ​

Built 19 October 2026, not deployed. The seven tools agents were first provisioned with keep their names and their answers; nine read tools are new. All times are wall-clock times in the store's time zone, and hours are net of breaks.

ToolFor whomLevelWhat it answers
my_shiftsEmployee, managerreadThe person's published shifts this or next week
team_weekManagerreadThe store's week as one grid, with totals, duty gaps and coverage
check_changeEmployee, managerproposeWhether a day off, cover, swap or new hours passes the rules; a card when it does
find_coverEmployee, managerreadWho could cover or swap a shift
explain_refusalEmployee, managerreadWhy a change does not pass and what would fix it
submit_change_requestEmployee, managerdirectSends the person's own confirmed request; it still waits for a decision
request_statusEmployee, managerreadThe person's own requests and where each stands
day_viewManagerreadOne day: who works when, and per hour the usual receipts, tills needed, people on checkout and where it is short
month_sheetManagerreadThe month sheet: everyone's shifts, hours, days off and contract hours
duty_gapsManagerreadThe hours of a week without a manager on duty
person_weekManagerreadOne person's week, against their contract hours
store_infoEmployee, managerreadThe store: hours, time zone, description, the assistant's status; for a manager also the hourly load, receipts per cashier and shift templates
store_peopleManagerreadThe store's people: position (its name, the owner's description of it, and whether it is archived), role, manager, contract hours, status, and the description where the manager may read it; and the team's active positions, the ones a person can be given
requests_to_decideManagerreadThe requests that are the manager's to decide, waiting or decided — read only
request_detailEmployee, managerreadOne request in full: the person's own, or one the manager decides
waiting_for_meEmployee, managerread"Waiting for you": a colleague asking for cover or a swap, a week to confirm, and the counts

An employee's conversation cannot reach a manager's tool, and a manager's never reaches another store: every answer is the actor's own store, through the same checks as the screens.

What is built: step 2 ​

Built 19 October 2026, not deployed. A manager can now change the schedule through the assistant, always as a proposal: the tool tries the change through the same code as the app's editor, writes nothing, and shows a card; the manager confirms the card in the app. An employee has none of these tools.

ToolFor whomLevelWhat it proposes
create_weekManagerproposeA new draft week, empty or a copy of the week before it, as New week in Schedules: how many shifts are copied and how many are left out
change_weekManagerproposeAny number of shift changes in one week as one card: add, edit and delete, with times, break, break start and area, or from a shift template by name
manage_templatesManagerproposeAdd, edit, delete and reorder the store's shift templates
set_hourly_loadManagerproposeThe store's usual receipts per weekday and hour, each slot before → after
set_receipts_per_cashierManagerproposeHow many receipts one cashier handles in an hour

How a proposal works:

  • The same rules as the editor. change_week runs every change through the schedule editor: the store's opening hours, at most three shifts a person a day that do not overlap, past weeks read only, a shift with an open request locked, and the managers' own rows are the owner's. The tool runs the whole change in the database and then undoes it, so the card's warnings are what the editor itself says: rest under 11 hours, hours over the contract, hours without a manager on duty, and hours where fewer people are on checkout than tills needed.
  • All or nothing. A change that breaks a rule is not proposed: the tool's answer says which change it stopped at and why, and the assistant tells the manager.
  • Confirming checks again. Confirming the card runs the change again with the rights of the person confirming, at that moment. If someone has changed the same shifts, the week to copy, the templates or the hourly load since the card was made, the card is refused as out of date and nothing changes; the assistant can propose it again. A card is done once: a lost answer is recovered from the card, never done twice.
  • No publishing. A new week stays a draft; publishing stays with the manager in Schedules (decision 1).

Every call is journaled by tool name and outcome, as in step 1; a proposal the rules refuse is journaled as refused.

What is built: the solver's tools ​

Built 19 October 2026, tested over the real /mcp against an in-memory Agentfy and on the seeded demo stores, not deployed. They use the same proposal cards as step 2. What the solver does, and its limits, is on Agent and solver.

ToolFor whomLevelWhat it does
solve_weekManagerproposeThe solver's plan for a week of the store's team: one card line per shift added or removed — a shift whose hours the solver set itself, where no template fits, ends "Custom hours: …" with why (since 26 October 2026, custom hours) — and as warnings the hours still short on the tills, without a manager on duty or — since 28 October 2026, when every opening hour needs at least one person by default (every opening hour covered) — with nobody on shift ("Fri 17:00–18:00: nobody on shift — …"), each with why, and overtime. For a draft week, or one not created yet, confirming writes the shifts into the draft; it never publishes. A published week gets the plan as advice and no card
evaluate_requestManagerreadThe solver's view of a request the manager decides: the week with the change against the week as it is, the cover it would need (a cover with custom hours says so; an opening hour the change leaves with nobody on shift needs cover too, since 28 October 2026), and a recommendation — approve or decline — with reasons
decide_requestManagerproposeThe manager's approve or decline (a decline needs the reason the requester will see); the card warns when the solver recommends the other way; confirming runs the ordinary approve or decline
save_rulesManagerdirectSince 10 November 2026: stores the rules the assistant read from descriptions, up to 20 a call, each checked as solve_week checks constraints, with the rights of editing those descriptions; no card — the rules are shown under each description in the app and on the week's card (Agent and solver)

Confirming checks again: a plan whose week has changed since it was made is refused as out of date, and a request decided meanwhile is refused; nothing is done twice.

Constraints from descriptions (since 20 October 2026, owner's decision that day). All three tools take an optional list of constraints: before solve_week the agent reads store_people (and store_info) and passes what a person's description clearly says about when or where they work — days off, one area, hours, hours a day, or a wish — each with source, the words it came from. The agent is told never to invent one, to propose the hourly load or a template for a store-level hint instead, and to tell the manager which were applied and which were ignored. The card shows them under "Read from the descriptions · correct them if wrong", one line each with its source, and the ignored ones with why. Since 5 November 2026 one the solver cannot use stops the call instead: nothing is planned, and the answer (needsConstraints, reason rejected) names each with why, to be fixed and sent again in the same turn; what no kind expresses the agent passes as ignored, and only that is shown as ignored (Agent and solver). Until then one wrong constraint was ignored with a reason. Since the same day (owner's decision) every description the tools hand over — the store's, each position's, each person's — has to be accounted for: cited by a constraint, listed in ignored (a person's), or named in a new list, noConstraints, when it states nothing a kind expresses; otherwise nothing is planned and the answer is needsConstraints with reason incomplete, naming what was left out. And the solver gives a person one shift a day unless a description allows split shifts (splitShifts) (Agent and solver; tested through the tools on a store written by the test and on a copy of the owner's local data, not checked against a local Agentfy, not deployed). What each kind does is on Agent and solver.

The descriptions are considered without being asked (since 20 October 2026, owner's decision that day; tested over the real /mcp against an in-memory Agentfy, checked once against a local Agentfy, not deployed). A call to any of the three without constraints does not solve when the people it would plan have descriptions: it answers — an ordinary answer, not an error — with those descriptions (for a manager the store's employees', never a manager's or their own; for the owner everyone's), the store's, and a short fingerprint, and the agent calls again with the constraints it read, or an empty list together with that fingerprint when nothing in them limits when or where anyone works (a list without it is answered with the descriptions again — an empty one since 20 October, any list since 30 October 2026, owner's decision that day: in a later message the agent had retyped constraints from memory; tested through the tools on the seeded demo stores, not checked against a local Agentfy, not deployed). Every time a week is built or built again the agent starts from the descriptions, never from constraints of an earlier message. The agent no longer needs store_people first and is told never to ask whether to consider the descriptions. The card then lists the constraints and whose descriptions gave none, or says "Descriptions read: nothing in them limits when or where people work, or how many the store needs".

The store's own rules (since 20 October 2026, owner's decision that day; tested over the real /mcp against an in-memory Agentfy, checked once against a local Agentfy, not deployed). The same constraints list takes rules read from the store's description, without a person: minStaff (people on checkout, on the sales floor or anywhere, in given hours), maxTills (the store's tills) and extraStaff (people on top of what is otherwise needed). The store's description alone makes the tools hand the descriptions over. The solver weighs these rules as the tills and reports what stays short with why (staffShort); the card lists them first, apart from the people's. What is already the store's data — opening hours, a busy time without a number of people, a shift's shape — the agent proposes through edit_store, set_hourly_load or manage_templates instead. What each kind does is on Agent and solver.

Positions (since 30 October 2026, the owner's request; tested over the real /mcp against an in-memory Agentfy, not checked against a local Agentfy, not deployed). A person's free-text title is gone: the tools give each person's position from the team's own list, and edit_person, invite_employee, invite_manager and invite_people take a position by its name, matched whatever the case. A name that is not one of the team's active positions is refused with the names it could have been, and an archived one is refused too; the list is the owner's, kept in the app, and no tool adds to it. Without constraints the solver's three tools also hand over the descriptions of the planned people's positions — each position once, with who holds it — and what one states outright is true of each of them. The tools' descriptions come from the MCP server, so the agents' profiles did not change.

Descriptions first (since 5 November 2026, the owner's request that day; tested over the real /mcp against an in-memory Agentfy, not checked with a live agent, not deployed). A week is built from the descriptions, so solve_week first checks that they are there: the store's, the position of everyone it would plan, and each of those people's own. While one is missing it plans nothing and makes no card; it answers with what is missing — the store, the positions with who holds them, the people by name — and the descriptions that are there. The assistant is told to say so plainly ("the store has no description", "no description for: Viktor, Sergey"), to ask in one message for what a week needs — how many people on the checkout and on the sales floor and when; a position's usual shifts and working days; a person's days off, earliest start and latest end — and to ask the same about a description that is there but leaves that out. The answer is written down before the week is built: a card for the store (edit_store), for a person (edit_person) or, for the owner, for a position (edit_position), the person's words added to the text that was there, never replacing it; a store manager cannot change a position, so the assistant says the owner adds it under People → Positions. Once the cards are confirmed it builds the week from the start. The way out: only when the person says outright to build without the information does the assistant call again with withoutDescriptions, the fingerprint of the list it was just given — a call without it, or with one for a list that has changed since, gets the question again — and then the result and the card's first warning name what was missing ("Built without descriptions, as you asked — missing: …"). Shiffty cannot hear what the person said, so the flag proves only that the assistant saw the list; that it asked is the profile's rule. Whether a description that is there says enough is the assistant's judgement: the tool checks only that a description exists. create_week does not plan, so it does not ask; evaluate_request and decide_request do not ask either, so a request is never held up by a missing description. Both profiles moved to a new revision (the stores' 15, the owner's 11).

Rules stored next to the descriptions (since 10 November 2026, the owner's request that day; tested through the tools on a store written by the test and on a copy of the owner's local data with a script in place of the assistant, not checked with a live agent, not deployed). The solver's three tools are called without constraints: they plan with the rules stored for the descriptions. While some description has none fresh — never read, or changed since — they answer needsRules with only those, at most 20, each with its text and fingerprint; the assistant reads them and saves their rules with save_rules, in batches of up to 20, and calls again. Rules are never retyped, a changed description is read again, and the app shows the rules under each description. The hand-passed constraints stay as an override for one call. Both profiles moved to a new revision (the stores' 19, the owner's 15). What is stored and why is on Agent and solver.

What is built: step 3 ​

Built 19 October 2026, not deployed, on the rights the owner gave managers that day: within their own store and only for employees — never another manager, never themselves — a manager deactivates and reactivates people, gives them another manager of the store, invites employees and withdraws those invitations, and changes the store's description and opening hours. Each is a proposal, as in step 2: the tool tries the change through the same code as the app, writes nothing, and shows a card the manager confirms.

ToolFor whomLevelWhat it proposes
deactivate_personManagerproposeAn employee of the store made inactive; the card lists the shifts after today that go with it. Refused while a change request is open on one of them
reactivate_personManagerproposeAn inactive employee of the store made active again
change_managerManagerproposeAnother manager of the same store for an employee
edit_personManagerproposeThe position — an active one of the team's list, by name — and contract hours of the manager's own people, the description of any employee of the store
invite_employeeManagerproposeA new employee of the store, by name and email, reporting to the manager unless another manager of the store is named
withdraw_invitationManagerproposeThe open invitation of an invited employee; a manager's invitation stays the owner's
edit_storeManagerproposeThe store's opening hours and description; hours that would leave shifts outside are refused before the card
invite_peopleManagerproposeSeveral new employees of the store in one card (up to 50), each by name and email; one refused person refuses the whole card, naming them. Since 23 October 2026
  • The invitation link is shown once. Nothing is sent and nobody is created until the manager confirms. Then the person gets the email, and the card shows the link once, with Copy link, to hand over if the email does not arrive. Shiffty keeps only a fingerprint of the link, as for an invitation made in the app; the card keeps no copy, so a reload shows the card as sent without the link. The assistant never sees the link.
  • Out of date, refused. Confirming checks again with the rules as they are at that moment; if the person or the store changed since the card was made, the card is refused and nothing changes.
  • Who did it. Every confirmed change is recorded with the manager's name and "through the assistant", like a change made by hand in the app records "in the app".

What is built: the owner's tools ​

Built 20 October 2026 (the owner's decision that day), tested over the real /mcp against an in-memory Agentfy and checked once against a local Agentfy, not deployed. The owner's assistant has the manager's tools with the owner's rights, for any store of the company, and a few of its own. A store tool takes storeId; when the company has more than one store and it is left out, the answer lists the stores. A store's agent never sees storeId or these tools: it discovers exactly what it did before.

ToolLevelWhat it does for the owner
list_storesreadThe company's stores: hours, time zone, status, managers, the store assistant's status, this week's hours
company_overviewreadEvery active store, this and next week: draft or published, shifts and hours, till-hours short on checkout, stretches without a manager on duty, change requests open on the week and those waiting for the owner
store_weekreadOne store's week as the grid — the owner's team_week, which stays the manager's unchanged
day_view, month_sheet, duty_gaps, person_week, store_info, store_peoplereadAs for a manager, for any store; the people with everyone's description
requests_to_decide, request_detail, evaluate_requestreadThe requests the owner decides (a manager's own); evaluate_request takes the same constraints from descriptions as solve_week, so the cover it names keeps to them
create_week, change_week, manage_templates, set_hourly_load, set_receipts_per_cashierproposeAs for a manager, for any store; change_week may change the managers' rows too
edit_storeproposeAlso the store's name and address, and since 23 October 2026 its time zone (shifts keep their wall-clock times) and its status: deactivating a store retires its assistant, and making it active again does not bring the assistant back
create_storeproposeSince 23 October 2026: a new store in one card — name, address, opening hours, time zone (left out: the zone of the company's other stores), description, receipts per cashier-hour, and optionally the hourly load and shift templates. The card lists every value, so what the assistant chose is visible before confirming. Confirming creates the store through the same rules as the app (another store's name is refused, in the app too) and then connects its assistant; the next tool calls find the store in list_stores and work on it at once
solve_weekproposeThe solver plans every row with the owner's rights, the managers' too, and takes people's constraints read from their descriptions (Agent and solver) — a manager's too, since the owner plans their rows; a manager's own plan ignores a constraint on a manager's row, with the reason
decide_requestproposeThe owner's approve or decline of a manager's request
save_rulesdirectSince 10 November 2026: the rules read from any description of the company, a position's too (a manager cannot save those)
deactivate_person, reactivate_person, change_manager, edit_person, invite_employee, withdraw_invitationproposeFor anyone of the company — managers too, and a manager's invitation
edit_positionproposeSince 5 November 2026: a position's description, the same in every store, as a card; the card warns when the new text drops what was there, and a description changed in the app since the card is refused as out of date. Renaming and archiving stay in People → Positions
create_positionproposeSince 11 November 2026: a new position of the company's catalogue — its name and, optionally, a description — as a card, so a new company with no positions can be set up in the chat. A name the company already has is refused (an archived one too: it is restored in People → Positions); confirming creates it through the same rules as the app, and a name taken since the card is refused. Once confirmed, invite_people, invite_employee, invite_manager and edit_person give it by its name in the same conversation
invite_managerproposeA new manager for a store, by name and email; the link is shown once in the app
invite_peopleproposeSince 23 October 2026: several people for one store in one card, managers and employees; an employee may report to a manager invited in the same card. The emails go out only once the card is confirmed, the links are shown once. The assistant asks for real names and emails and never makes an address up; made-up demo people only when the owner asks for them
publish_weekproposePublishes a draft week once the owner confirms the card; the card lists what goes out and warns about tills short, hours without a manager on duty and open requests. A week changed after the card was made is refused as out of date
  • The domain decides, as in the app. A manager who still has people reporting to them cannot be deactivated until those people have another manager; the tool says so and makes no card.
  • What the owner can do in the app and the assistant still cannot (23 October 2026; creating a store and a store's time zone and status were on this list until that day): undo a decision; reorder the stores; rename or archive a position; the company itself, its members, API keys and ownership transfer; connecting or retiring the assistants (deactivating a store through edit_store retires its assistant). Asked for one of these, the assistant says it cannot do it and where in Shiffty it is done.
  • The assistant names the product Shiffty (23 October 2026), never the platform it runs on.

Answers and positions through the chat ​

Built 11 November 2026, tested over the real /mcp against an in-memory Agentfy, not checked with a live agent, not deployed. Until then the assistant read "Waiting for you" and said to answer in the app, and the owner's assistant sent a new company with no positions to People → Positions.

ToolFor whomLevelWhat it proposes
answer_colleagueEmployee, managerproposeYes or no to a colleague's ask to cover or swap a shift, one item of "Waiting for you" by its id; the card shows the ask as the app does, with an overtime warning when agreeing would cause one. There is no note: the app's answer is yes or no too
confirm_weekEmployee, managerproposeConfirming the person's own shifts of a published week, or marking the week as wrong; the card lists the shifts
  • Only the person's own items. Another person's item is not found, and the owner, who has no "Waiting for you", has neither tool.
  • The same answer as the app's buttons. Confirming runs what the app's Agree, No and Confirm do, with the same checks then: an item answered in the app meanwhile, or a request the colleague withdrew or that was decided, refuses the card and changes nothing. A week card is refused too when the person's shifts that week changed after it was made.
  • Positions are the owner's create_position and edit_position, above.

A swap with a named colleague, and dates ​

Built 11 November 2026, tested over the real /mcp against an in-memory Agentfy, not checked with a live agent, not deployed. That day a demo of an employee asking to swap a Saturday with a named colleague failed twice: the assistant offered only the colleague's first fitting shift, got a weekday wrong, lost the shift's id by the next message, tried a manager's tool and asked the person for an "employment ID". The same day a manager's assistant asked for "Friday, 20 November" with the year 2024, got an empty day and said the week was not published.

  • find_cover lists every shift of a colleague that fits, not only the first one, and leaves out a shift another open request is already about. Each date comes with its weekday (day, e.g. "Mon 16 Nov"). So do the dates in my_shifts, check_change, request_status, request_detail and waiting_for_me; the app's own answers are unchanged.
  • A change can be named the way the person says it. check_change, explain_refusal and submit_change_request take the person's shift by its date, the colleague by name and, for a swap, the colleague's shift by its date. The API finds the shifts and the person; when a name or a date fits nobody or more than one, it refuses and lists the choices, so the assistant asks the person. The card stores the shifts it found, and confirming it checks the rules again, as before.
  • An employee is told what to use instead of a manager's tool. Before, store_people answered an employee's assistant that "the conversation permission is missing", and the assistant passed that on as a permission problem.
  • A date about six months or more from today is refused by every tool of both assistants. The refusal gives today's date in the store's time zone and the same day and month in the nearest year ("did you mean 2026-11-20?"), so the assistant asks again instead of answering from an empty day. The assistant cannot be handed today's date directly: the chat passes it nothing but the person's permission. The owner's assistant, which has no store, is given today's date in UTC.
  • The store assistant's instructions say all of this (profile revision 21). The owner's assistant's instructions are unchanged.

The plan: step 4 ​

A plan, not built. It keeps the rules above, and adds its tools through the same proposal cards.

  • Step 4 — the rest of a person's own actions. Withdraw my request; the kinds of request a shift allows. Withdrawing is the person's own answer, so direct, after a yes in the conversation. Answering a colleague's ask and confirming my week were on this list; since 11 November 2026 they are built, as cards rather than direct (the owner's request that day: every change in the chat is a card the person confirms) — see Answers through the chat.

Approving and declining came with the solver's tools, above. Undoing a decision and publishing a week stay people's actions.

Every action in the app, and its tool ​

What the API lets a person do, and how the assistant reaches it. "Not for the agent yet" names the reason.

In the appToolWhen
See my shiftsmy_shiftsBuilt (step 1)
See a store's weeks, a week, the current weekteam_week, person_week, duty_gapsBuilt (step 1)
See a day with its coverageday_viewBuilt (step 1)
See the month sheetmonth_sheetBuilt (step 1)
Create a week, empty or copiedcreate_weekBuilt (step 2)
Add, change, delete a shift; check a shiftchange_week, with a list of operations; the check runs inside itBuilt (step 2)
Build a week with the solversolve_week → card, writes into a draftBuilt (solver)
Publish a weekThe owner's only: publish_week → card, the owner publishes by confirming (owner, 20 October 2026); never a manager's assistantBuilt (owner)
See the store, its hourly load, its templatesstore_infoBuilt (step 1)
Change the hourly load and receipts per cashierset_hourly_load, set_receipts_per_cashierBuilt (step 2)
Add, change, reorder, delete shift templatesmanage_templatesBuilt (step 2)
Change the store's hours and descriptiona propose tool (edit_store); a manager may since 19 October 2026Built (step 3)
Change the store's name and addressThe owner's: edit_storeBuilt (owner)
Change the store's zone or statusThe owner's: edit_storeBuilt (owner, 23 October 2026)
List all stores, see the company at a glancelist_stores, company_overview (the owner)Built (owner)
Create a storeThe owner's: create_store, with its hours, zone, description, load and templates in one cardBuilt (owner, 23 October 2026)
Connect a store's assistantNot for the agent: it cannot connect itself—
See the store's people, one personstore_people, person_weekBuilt (step 1)
Change a person's position, contract hours, descriptiona propose tool (edit_person), within the manager's rightsBuilt (step 3)
Deactivate or reactivate an employee, change their managerpropose tools (deactivate_person, reactivate_person, change_manager); a manager may since 19 October 2026, for the store's employeesBuilt (step 3)
Invite an employee, withdraw that invitationpropose tools (invite_employee, withdraw_invitation); a manager may since 19 October 2026Built (step 3)
Invite a manager, withdraw a manager's invitationinvite_manager, withdraw_invitation (the owner)Built (owner)
Invite several people at onceinvite_people (the owner; a manager for the store's employees)Built (23 October 2026)
Create a position, change its descriptionThe owner's: create_position, edit_position → cardBuilt (5 and 11 November 2026)
Check a change, find cover, explain a refusalcheck_change, find_cover, explain_refusalBuilt
Make a requestcheck_change → card, or submit_change_request after a yesBuilt
The kinds of request a shift allowsPartly: check_change and find_cover answer one change at a time; a tool listing the optionsStep 4
See my requestsrequest_status, request_detailBuilt (step 1)
Withdraw my requesta direct toolStep 4
See requests to decide, one of themrequests_to_decide, request_detailBuilt (step 1)
Weigh a requestevaluate_requestBuilt (solver)
Approve, declinedecide_request → card; the confirmation decidesBuilt (solver)
Undo a decisionNot for the agent: it stays a person's action—
See "Waiting for you" and the countswaiting_for_meBuilt (step 1)
Answer a colleague, confirm my weekanswer_colleague, confirm_week → card; the confirmation answersBuilt (11 November 2026)
Sign in, sign out, reset a password, see who I amNot for the agent: the person signs in; the conversation already knows who they are—
The company, its members, API keys, ownership transferNot for the agent yet: the owner does it in the app—
Settings (platform administrators)Not for the agent—
The chat, its history, confirming or keeping a cardThe chat itself, not a tool—

Where to go next ​