deputy-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@deputy-mcpshow my next shift"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
deputy-mcp
Ask Claude "what's my next shift?" or "who's clocked in right now?" and get the answer straight from your Deputy roster — no app, no dashboard.
deputy-mcp connects Deputy — the workforce scheduling and timesheet platform — to Claude and any other MCP client. If your work life runs through Deputy, this lets you ask about your own shifts, timesheets, and who's on right now in plain language, instead of opening the app. It runs on your machine and only ever talks to your own Deputy install.
Example
"When do I work next?" Fri 18 Jul, 09:00–17:00 · Cloud Nine Cafe
"Am I clocked in right now?" Yes — since 20:27, still in progress.
"Who else is on with me tonight?" Sam O'Brien, rostered until 23:27.
(Fictional example data — Cloud Nine Cafe and its staff aren't real; see
examples/mock_deputy.py.)
Related MCP server: SmartSuite MCP Server
Installation
Needs uv (or anything that can run uvx).
Get a token. In Deputy: Business settings → Integrations → API access → New OAuth Client → Get an Access Token (shown once — copy it). This needs an admin access level in Deputy. No admin access? Skip to No token? Use your calendar feed below.
Get your base URL. The address you see in the browser when logged in to Deputy,
e.g. https://your-company.eu.deputy.com.
Claude Code
claude mcp add deputy \
-e DEPUTY_API_TOKEN=your-deputy-token \
-e DEPUTY_BASE_URL=https://your-company.eu.deputy.com \
-- uvx --from git+https://github.com/augbastos/deputy-mcp deputy-mcpAdd -e DEPUTY_ALLOW_WRITES=true to also enable the write tools (off by default).
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"deputy": {
"command": "uvx",
"args": ["--from", "git+https://github.com/augbastos/deputy-mcp", "deputy-mcp"],
"env": {
"DEPUTY_API_TOKEN": "your-deputy-token",
"DEPUTY_BASE_URL": "https://your-company.eu.deputy.com"
}
}
}
}Any other MCP client
deputy-mcp speaks MCP over stdio. Point your client at
uvx --from git+https://github.com/augbastos/deputy-mcp deputy-mcp and set the same
DEPUTY_* environment variables (full list in Configuration).
No token? Use your calendar feed
Not a Deputy admin? Every employee has a personal iCal feed of their own roster, and
that's enough to run deputy-mcp with no API token. In Deputy, open My Schedule →
Subscribe / Export to calendar and copy the link. Set it as DEPUTY_CALENDAR_URL
instead of DEPUTY_API_TOKEN / DEPUTY_BASE_URL.
This mode is read-only and roster-only — deputy_get_my_roster, deputy_next_shift,
deputy_whoami, deputy_get_my_calendar_url. The feed link is a secret (it carries
your personal token); never commit it.
Tools
Every tool accepts response_format — "markdown" (default) or "json". ? marks
an optional argument.
Read — always on
Self-service tools work on any employee token. Team/manager tools need an elevated access level — on a plain employee token they fail with a clear "needs manager/admin access" message rather than a cryptic error.
Tool | Arguments | Returns |
| — | Who the token authenticates as, your location and timezone, whether you're clocked in, and your calendar feed URL. Run this first. |
|
| Your scheduled shifts in a date range (default: today → +7 days). |
|
| Your next upcoming shift. Naming someone else needs manager/admin. |
|
| Your worked timesheets, with a total (default: last 7 days). |
| — | Your personal iCal feed — add it once to Google/Apple/Outlook Calendar. |
| — | Areas (work locations) you work, with ids. |
|
| People you work with, grouped by location — names only, never contact details. |
|
| Every scheduled shift in a range, optionally scoped to one area. |
|
| Snapshot at an instant (default now): who's clocked in vs rostered. |
|
| Profile(s) matching a name or id. |
|
| Shifts filtered by person, area, date, open status — paginated. |
Write — opt-in, off by default
This is a deliberate security default, not a limitation: write tools only get
registered when you set DEPUTY_ALLOW_WRITES=true. Until then, a model can't see
them, let alone call them. Every write acts as the signed-in token holder; none of
them delete anything.
Tool | Arguments | Returns |
|
| Assigns you to an open shift. |
|
| Offers one of your shifts for swap, pending manager approval. |
|
| Records an unavailability window (one-off or recurring). |
|
| Starts a live timesheet. |
|
| Ends your in-progress timesheet. |
How it works
flowchart LR
A["Claude / any MCP client"] -->|"MCP, stdio"| B["deputy-mcp<br/>(runs on your machine)"]
T1["DEPUTY_API_TOKEN"] --> B
T2["DEPUTY_CALENDAR_URL<br/>(no token)"] --> B
B --> R["Read tools<br/>always on"]
B -.->|"DEPUTY_ALLOW_WRITES=true"| W["Write tools<br/>off by default"]
R --> API["Your Deputy install"]
W -.-> APIReads are always registered. Writes only exist as callable tools once you opt in — otherwise the model can't see them at all.
Privacy & security
Runs locally as a stdio process — no hosted backend, no telemetry. Its only network traffic is HTTPS to your own Deputy install (or your personal iCal feed); nothing passes through a third party. deputy-mcp does exactly what your Deputy token can do, no more — the token is held in memory, redacted from logs, and never printed.
Configuration
All settings are DEPUTY_* environment variables. Provide one credential set:
DEPUTY_API_TOKEN + DEPUTY_BASE_URL for the full API, or DEPUTY_CALENDAR_URL
alone for iCal mode. Copy .env.example to .env and fill it in
(never commit .env).
Variable | Required | Default | Description |
| API mode | — | Deputy permanent or OAuth access token (stored redacted). |
| API mode | — | Your install origin, e.g. |
| iCal mode | — | Your personal iCal feed URL (token-free, roster-only, stored redacted). |
| No |
| Enable the write tools. |
| No |
| Allow a base URL host outside |
| No |
| In-memory read-cache lifetime, seconds. |
| No |
| Per-request HTTP timeout, seconds. |
| No |
| Automatic retries on |
| No | — | Path to a dotenv file to load |
CLI (bonus)
The same client ships as a small standalone CLI, for a quick check without an MCP client:
deputy-mcp whoami # who you're authenticated as
deputy-mcp roster # your roster (--team for everyone, --area ID to scope)
deputy-mcp who # who's working right now
deputy-mcp next # your next shiftAdd --json for raw output. With no subcommand, deputy-mcp starts the MCP server.
Development
See CONTRIBUTING.md for setup, project layout, and the PR checklist. Short version:
uv sync
uv run pytest # full suite, mocked, no live calls
uv run ruff check .
uv run mypyThe Deputy client has no MCP dependency and works standalone:
import asyncio
from deputy_mcp.client import DeputyClient
async def main() -> None:
async with DeputyClient.from_env() as deputy:
print(await deputy.next_shift())
asyncio.run(main())Planned work lives in ROADMAP.md.
License
MIT © Augusto Bastos.
Available Tools
4 toolsdeputy_get_my_calendar_urlARead-only
Return the signed-in user's personal Deputy calendar (iCal) subscription URL.
Deputy publishes a per-user, read-only iCal feed of your roster (the CalendarURL on /api/v1/me). Add the returned link to any calendar app (Google Calendar, Apple Calendar, Outlook) to see your shifts there; it stays in sync as your roster changes. Works at any access level — it reads only your own /me record.
When NOT to use: to read the shifts themselves here (use deputy_get_my_roster or deputy_next_shift) — this only returns the subscription link.
Returns markdown (the subscription link, or a note that this install exposes none)
or, with response_format="json", an object {"calendar_url"} whose value is a
string or null. In iCal mode the feed URL is the configured secret and is never
printed; the tool confirms it is configured without revealing it.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: 'markdown' (human-readable, default) or 'json' (raw records). | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already declare readOnlyHint=true, the description adds substantial behavioral context: it reads only the caller's own /me record, works at any access level, stays in sync with roster changes, returns markdown or a JSON object, and never prints the secret iCal feed URL. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, and every subsequent sentence adds distinct operational, security, or output-format context. There is no filler or redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers tool selection, read-only behavior, access-level guarantees, output format variants, null handling, and the security nuance around the secret iCal URL. An agent has everything needed to call this tool correctly and avoid misuse.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully documents response_format with enum values and a default description, so the baseline is 3. The description goes beyond by specifying the exact JSON shape ({'calendar_url'}), the null possibility, and the markdown-mode behavior, which adds meaningful semantic value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: return the signed-in user's personal Deputy calendar (iCal) subscription URL. It also explicitly distinguishes this from sibling tools like deputy_get_my_roster and deputy_next_shift, which read shifts rather than return a subscription link.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description contains an explicit 'When NOT to use' section that names the alternative tools for reading shifts and clarifies that this tool only returns the subscription link. This gives the agent clear selection criteria with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deputy_get_my_rosterARead-only
List the signed-in user's own upcoming shifts in a date range.
Defaults to today through the next 7 days, computed in UTC; dates are ISO YYYY-MM-DD.
When NOT to use: for other people's shifts (use deputy_get_team_roster) or for worked time (use deputy_get_my_timesheets) — this returns your scheduled shifts.
Returns markdown (a shift list, times in the install timezone) or, with response_format="json", a list of Roster records. The output is identical whether the roster came from the Deputy API or, in iCal mode, from your calendar feed.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | End date (ISO). | |
| start_date | No | Start date (ISO). | |
| response_format | No | Output format: 'markdown' (human-readable, default) or 'json' (raw records). | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the default date range, UTC computation, ISO date format, output format behavior, timezone rendering, and the source-agnostic nature of the output (Deputy API or iCal feed). It does not contradict the readOnlyHint/openWorldHint annotations and actually enriches them with meaningful runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized with clear sections: what it does, defaults/format, when not to use, and return behavior. Every sentence carries useful information, and the most critical purpose statement is front-loaded. It is detailed without being bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, read-only, all-optional-parameter tool with a full output schema, this description covers everything an agent needs: the resource, the scope, default behavior, alternatives, output format selection, timezone handling, and data source nuance. No critical context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all 3 parameters with 100% coverage, so the description does not need to re-document them. It adds value by explaining the default range when start_date/end_date are omitted, and by describing what response_format changes about the returned output. Baseline is 3; the added context justifies 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List the signed-in user's own upcoming shifts in a date range.' It clearly distinguishes the tool from alternatives by naming deputy_get_team_roster and deputy_get_my_timesheets, and states what it does NOT return. This is unambiguous and immediately actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'When NOT to use' guidance names the sibling tools and the exact conditions that route elsewhere: other people's shifts go to deputy_get_team_roster, worked time goes to deputy_get_my_timesheets. It also specifies default behavior when date parameters are omitted, leaving no ambiguity about invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deputy_next_shiftARead-only
Return the single next upcoming shift for an employee (name or id).
Omit 'employee' to get your own next shift. A name must resolve to exactly one active person; otherwise the matches are listed for you to retry by id.
When NOT to use: for a full range of upcoming shifts (use deputy_get_my_roster or deputy_search_shifts) — this returns only the earliest one.
Returns markdown (one shift, or a 'none scheduled' note) or, with response_format="json", a single Roster record or null. In iCal mode only your own next shift is available (naming another employee needs an API token).
| Name | Required | Description | Default |
|---|---|---|---|
| employee | No | Employee name or id. | |
| response_format | No | Output format: 'markdown' (human-readable, default) or 'json' (raw records). | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already covering safety, the description adds valuable behavioral context: ambiguous-name handling, markdown vs. json return semantics, the 'none scheduled' note, and the iCal-mode auth limitation. No contradiction with annotations is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then uses clear sections for usage and exclusions. Each sentence delivers distinct information—scope, edge cases, alternatives, and output behavior—with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has only two optional parameters and a read-only annotation. The description covers the essential usage scenarios, output formats, failure modes, and auth caveats. An output schema exists, so return value structure is already handled, making this complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining that a name must resolve to exactly one active person, that matches are listed for retry by id, and that json returns a single Roster record or null. This justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Return the single next upcoming shift for an employee (name or id).' It clearly distinguishes itself from sibling tools by noting it returns only the earliest one, contrasting with deputy_get_my_roster and deputy_search_shifts for full ranges.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is an explicit 'When NOT to use' section naming alternatives (deputy_get_my_roster, deputy_search_shifts) and the condition that selects this tool. It also gives guidance on omitting 'employee' for your own shift and handling ambiguous names, leaving no inference burden on the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deputy_whoamiARead-only
Verify the Deputy connection and confirm which identity the token uses.
Returns who the API token authenticates as, the company/location and its timezone, whether that user is clocked in right now (from their in-progress timesheet), and their personal iCal calendar subscription URL when the install exposes one. Run this first to confirm setup before other tools.
When NOT to use: to read schedules or people (use deputy_get_my_roster or deputy_get_employee_info) — this only checks the connection and identity.
Returns markdown (a connection summary: signed-in name, company, timezone, whether
clocked in, and the calendar feed) or, with response_format="json", an object
{"whoami", "company", "timezone", "company_name", "clocked_in", "calendar_url"}
where clocked_in is a bool and calendar_url is a string or null. In iCal
mode there is no API identity, so this reports mode=iCal and that only your roster
is available.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: 'markdown' (human-readable, default) or 'json' (raw records). | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal read-only and open-world behavior, so the bar is lower. The description adds useful context: markdown vs JSON output, the exact JSON fields, clocked_in being a bool, calendar_url being nullable, and the special iCal mode with no API identity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well organized with clear paragraphs for purpose, usage, and return behavior. Some redundancy exists between the opening summary and the later markdown/JSON explanation, but each section adds detail and the purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, one-optional-parameter read-only tool, this description covers the key aspects: what it returns, when to run it, when not to use it, alternatives, and a non-obvious iCal limitation. The output schema also exists to carry return-type details, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single response_format parameter, so the baseline is 3. The description adds value by explaining what json mode returns, including the object shape and field types, which is not fully captured by the schema's 'raw records' phrasing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Verify the Deputy connection and confirm which identity the token uses.' It also distinguishes itself from sibling schedule/people-reading tools by stating 'this only checks the connection and identity.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is given: 'Run this first to confirm setup before other tools.' The description also states when not to use it and names alternatives: 'to read schedules or people (use deputy_get_my_roster or deputy_get_employee_info).'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
deputy_get_my_calendar_url - First observed
deputy_get_my_roster - First observed
deputy_next_shift - First observed
deputy_whoami
TDQS
Scored across 4 tools
Each tool has a clear primary purpose, and the explicit 'When NOT to use' notes help separate roster listing from next-shift lookup. There is minor overlap where whoami also returns the calendar URL and next_shift is a single-item subset of the roster, but these are not likely to cause serious misselection.
All tools share the deputy_ prefix and use snake_case, and three of the four follow a get_my_* pattern. deputy_whoami and deputy_next_shift break the verb-first convention, but the naming remains predictable and readable.
Four tools is a reasonable, compact set for a personal roster/identity assistant. It feels slightly thin for a general Deputy integration, especially since several missing tools are referenced in descriptions, but the count itself is not excessive.
The self-service schedule workflow is covered, but the descriptions reference four tools that do not exist in this server: deputy_get_employee_info, deputy_get_team_roster, deputy_get_my_timesheets, and deputy_search_shifts. There are also no leave, timesheet, or shift-management tools, so common Deputy queries will hit dead ends.
Maintenance
Related MCP Connectors
The MCP server for Azure DevOps, bringing the power of Azure DevOps directly to your agents.
MCP server providing attendance data queries via the CloudTime API.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
- mcp-serverOAuthio.klokin
MCP server exposing klokin time-tracking operations (employees, time entries, stores) to AI clients.
Related MCP Servers
- FlicenseAqualityDmaintenanceAn MCP server that wraps the TimePRO API, enabling AI assistants to automatically create, view, and manage timesheets for authenticated users. It provides tools for searching clients and projects, retrieving configuration defaults, and performing full CRUD operations on timesheet entries.10-
- AlicenseAqualityBmaintenanceA locally-hosted MCP server enabling AI agents to securely interact with SmartSuite data, with configurable access modes and audit logging.8610MIT
- FlicenseNot gradedqualityBmaintenanceMCP server for integrating with the RHiD (ControlID) API, providing time tracking, employee management, and reporting tools for use in Claude products.-
- AlicenseAqualityBmaintenanceAn unofficial MCP server that exposes the Timetastic API to enable querying and managing absence & leave data.39MIT