Home

tommy

v1.0.0
Base URL
https://api.mytommy.com/mcp

Workforce, scheduling, documents, and chat for service teams.

Connect

Add to your MCP client configuration:

{ "mcpServers": { "tommy": { "url": "https://api.mytommy.com/mcp" } } }
Protocol MCP 2025-11-25Transport streamable-httpCapabilities tools, resources, prompts

Tools

tommy_get_status

read-onlyidempotent
TOOLtommy_get_status

Get current account/team readiness, recent activity counts, and recommended next actions.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_get_status
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_get_status",
    "arguments": {}
  }
}
const result = await client.callTool("tommy_get_status", {});
result = await session.call_tool("tommy_get_status", arguments={})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_query

read-onlyidempotent
TOOLtommy_query

Read-only paginated lookup across approved Tommy entity types: shifts, availabilities, documents, clients, contacts, team_members. Pagination via page/per.

Parameters

entitystringshiftsavailabilitiesdocumentsclientscontactsteam_membersrequiredargument

The entity type to list.

pageinteger1argument
perinteger[1, 100]25argument
idinteger | stringargument

Optional single-record lookup by id.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_query
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_query",
    "arguments": {
        "entity": "shifts",
        "page": 1,
        "per": 25,
        "id": 0
      }
  }
}
const result = await client.callTool("tommy_query", {
  "entity": "shifts",
  "page": 1,
  "per": 25,
  "id": 0
});
result = await session.call_tool("tommy_query", arguments={
  "entity": "shifts",
  "page": 1,
  "per": 25,
  "id": 0
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_search_people

read-onlyidempotent
TOOLtommy_search_people

Search across team_members, clients, or contacts by name/email. Pass kind to narrow; q is the case-insensitive search term.

Parameters

qstringrequiredargument

Search text (matches name, email, phone).

kindstringteam_membersclientscontactsargument

Optional. Defaults to all kinds.

perinteger[1, 100]25argument

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_search_people
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_search_people",
    "arguments": {
        "q": "string",
        "kind": "team_members",
        "per": 25
      }
  }
}
const result = await client.callTool("tommy_search_people", {
  "q": "string",
  "kind": "team_members",
  "per": 25
});
result = await session.call_tool("tommy_search_people", arguments={
  "q": "string",
  "kind": "team_members",
  "per": 25
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_get_insights

read-onlyidempotent
TOOLtommy_get_insights

Read-only summaries and metrics for the active team. Pass metric to narrow: overview, attendance, shifts, documents.

Parameters

metricstringoverviewattendanceshiftsdocumentsoverviewargument
windowstring24h7d30d90d7dargument

Lookback window for time-series metrics.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_get_insights
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_get_insights",
    "arguments": {
        "metric": "overview",
        "window": "7d"
      }
  }
}
const result = await client.callTool("tommy_get_insights", {
  "metric": "overview",
  "window": "7d"
});
result = await session.call_tool("tommy_get_insights", arguments={
  "metric": "overview",
  "window": "7d"
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_manage_shift

destructive
TOOLtommy_manage_shift

Create, update, cancel, drop, or swap a workforce shift. Pass dry_run: true to preview. Cancel/drop/swap require attributes.confirm: true.

Body

application/json
operationstringcreateupdatecanceldropswaprequired

What to do.

shift_idinteger | string

For update/cancel/drop/swap.

dry_runbooleanfalse

Preview without applying.

idempotency_keystring

Dedupe retries.

attributesobject

Shift fields to set or update.

Show child attributes
start_atstring<date-time>

When the shift starts.

end_atstring<date-time>

When the shift ends.

assignee_idinteger | string

Team member to work the shift.

role_namestring

Optional role label for the shift.

replacement_team_member_idinteger | string

For swap: the team member to swap to.

confirmbooleanfalse

Required for cancel, drop, or swap.

Parameters

operationstringcreateupdatecanceldropswaprequiredargument

What to do.

shift_idinteger | stringargument

For update/cancel/drop/swap.

dry_runbooleanfalseargument

Preview without applying.

idempotency_keystringargument

Dedupe retries.

attributesobjectargument

Shift fields to set or update.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_manage_shift
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_manage_shift",
    "arguments": {
        "operation": "create",
        "shift_id": 0,
        "dry_run": false,
        "idempotency_key": "string",
        "attributes": {
          "start_at": "2024-01-15T09:30:00Z",
          "end_at": "2024-01-15T09:30:00Z",
          "assignee_id": 0,
          "role_name": "string",
          "replacement_team_member_id": 0,
          "confirm": false
        }
      }
  }
}
const result = await client.callTool("tommy_manage_shift", {
  "operation": "create",
  "shift_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "assignee_id": 0,
    "role_name": "string",
    "replacement_team_member_id": 0,
    "confirm": false
  }
});
result = await session.call_tool("tommy_manage_shift", arguments={
  "operation": "create",
  "shift_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "assignee_id": 0,
    "role_name": "string",
    "replacement_team_member_id": 0,
    "confirm": false
  }
})
Request Body
{
  "operation": "create",
  "shift_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "assignee_id": 0,
    "role_name": "string",
    "replacement_team_member_id": 0,
    "confirm": false
  }
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_manage_shift_requirements

destructive
TOOLtommy_manage_shift_requirements

Create, update, cancel, approve, or reject a shift request (request / drop / swap / offer). approve_request, reject_request, and cancel_request require attributes.confirm: true.

Body

application/json
operationstringcreate_requestupdate_requestcancel_requestapprove_requestreject_requestrequired

What to do.

request_idinteger | string

For update/cancel/approve/reject.

shift_idinteger | string

For create_request.

kindstringrequestdropswapoffer

For create_request: what kind of request.

dry_runbooleanfalse
idempotency_keystring
attributesobject

Optional fields for create/update.

Show child attributes
swap_shift_idinteger | string

For swap requests, the shift to swap into.

messagestring

Optional note.

confirmbooleanfalse

Required before cancelling, approving, or rejecting.

Parameters

operationstringcreate_requestupdate_requestcancel_requestapprove_requestreject_requestrequiredargument

What to do.

request_idinteger | stringargument

For update/cancel/approve/reject.

shift_idinteger | stringargument

For create_request.

kindstringrequestdropswapofferargument

For create_request: what kind of request.

dry_runbooleanfalseargument
idempotency_keystringargument
attributesobjectargument

Optional fields for create/update.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_manage_shift_requirements
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_manage_shift_requirements",
    "arguments": {
        "operation": "create_request",
        "request_id": 0,
        "shift_id": 0,
        "kind": "request",
        "dry_run": false,
        "idempotency_key": "string",
        "attributes": {
          "swap_shift_id": 0,
          "message": "string",
          "confirm": false
        }
      }
  }
}
const result = await client.callTool("tommy_manage_shift_requirements", {
  "operation": "create_request",
  "request_id": 0,
  "shift_id": 0,
  "kind": "request",
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "swap_shift_id": 0,
    "message": "string",
    "confirm": false
  }
});
result = await session.call_tool("tommy_manage_shift_requirements", arguments={
  "operation": "create_request",
  "request_id": 0,
  "shift_id": 0,
  "kind": "request",
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "swap_shift_id": 0,
    "message": "string",
    "confirm": false
  }
})
Request Body
{
  "operation": "create_request",
  "request_id": 0,
  "shift_id": 0,
  "kind": "request",
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "swap_shift_id": 0,
    "message": "string",
    "confirm": false
  }
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_manage_availability

TOOLtommy_manage_availability

Update an availability record or record a clock-in/out attendance.

Body

application/json
operationstringupdateclock_inclock_outrequired

What to do.

availability_idinteger | string

For update.

attendance_idinteger | string

For clock_out.

team_member_idinteger | string

For clock_in/clock_out: who is clocking in or out.

dry_runbooleanfalse
idempotency_keystring
attributesobject

Availability or attendance fields.

Show child attributes
start_atstring<date-time>

Start of the availability window.

end_atstring<date-time>

End of the availability window.

statusstringunavailableneutralavailablepreferred

Availability status for the requested time range.

datestring<date>

Availability date.

periodsArray<string>ampmnd

Which availability windows to update.

availabilitystringunavailableneutralavailablepreferred

Availability value to apply to the selected periods.

Parameters

operationstringupdateclock_inclock_outrequiredargument

What to do.

availability_idinteger | stringargument

For update.

attendance_idinteger | stringargument

For clock_out.

team_member_idinteger | stringargument

For clock_in/clock_out: who is clocking in or out.

dry_runbooleanfalseargument
idempotency_keystringargument
attributesobjectargument

Availability or attendance fields.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_manage_availability
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_manage_availability",
    "arguments": {
        "operation": "update",
        "availability_id": 0,
        "attendance_id": 0,
        "team_member_id": 0,
        "dry_run": false,
        "idempotency_key": "string",
        "attributes": {
          "start_at": "2024-01-15T09:30:00Z",
          "end_at": "2024-01-15T09:30:00Z",
          "status": "unavailable",
          "date": "2024-01-15",
          "periods": [
            "am"
          ],
          "availability": "unavailable"
        }
      }
  }
}
const result = await client.callTool("tommy_manage_availability", {
  "operation": "update",
  "availability_id": 0,
  "attendance_id": 0,
  "team_member_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "status": "unavailable",
    "date": "2024-01-15",
    "periods": [
      "am"
    ],
    "availability": "unavailable"
  }
});
result = await session.call_tool("tommy_manage_availability", arguments={
  "operation": "update",
  "availability_id": 0,
  "attendance_id": 0,
  "team_member_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "status": "unavailable",
    "date": "2024-01-15",
    "periods": [
      "am"
    ],
    "availability": "unavailable"
  }
})
Request Body
{
  "operation": "update",
  "availability_id": 0,
  "attendance_id": 0,
  "team_member_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "status": "unavailable",
    "date": "2024-01-15",
    "periods": [
      "am"
    ],
    "availability": "unavailable"
  }
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_manage_documents

destructive
TOOLtommy_manage_documents

Create, update, cancel, approve, or reject a leave request. Approve/reject/cancel require attributes.confirm: true.

Body

application/json
operationstringcreate_leaveupdate_leavecancel_leaveapprove_leavereject_leaverequired

What to do.

leave_idinteger | string

For update/cancel/approve/reject.

dry_runbooleanfalse

Preview without applying.

idempotency_keystring
attributesobject

Leave request fields.

Show child attributes
start_atstring<date-time>

When the leave starts.

end_atstring<date-time>

When the leave ends.

leave_kindstringannualsickpersonallong_serviceunpaidother

Type of leave.

messagestring

Optional note.

confirmbooleanfalse

Required before approving, rejecting, or cancelling.

Parameters

operationstringcreate_leaveupdate_leavecancel_leaveapprove_leavereject_leaverequiredargument

What to do.

leave_idinteger | stringargument

For update/cancel/approve/reject.

dry_runbooleanfalseargument

Preview without applying.

idempotency_keystringargument
attributesobjectargument

Leave request fields.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_manage_documents
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_manage_documents",
    "arguments": {
        "operation": "create_leave",
        "leave_id": 0,
        "dry_run": false,
        "idempotency_key": "string",
        "attributes": {
          "start_at": "2024-01-15T09:30:00Z",
          "end_at": "2024-01-15T09:30:00Z",
          "leave_kind": "annual",
          "message": "string",
          "confirm": false
        }
      }
  }
}
const result = await client.callTool("tommy_manage_documents", {
  "operation": "create_leave",
  "leave_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "leave_kind": "annual",
    "message": "string",
    "confirm": false
  }
});
result = await session.call_tool("tommy_manage_documents", arguments={
  "operation": "create_leave",
  "leave_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "leave_kind": "annual",
    "message": "string",
    "confirm": false
  }
})
Request Body
{
  "operation": "create_leave",
  "leave_id": 0,
  "dry_run": false,
  "idempotency_key": "string",
  "attributes": {
    "start_at": "2024-01-15T09:30:00Z",
    "end_at": "2024-01-15T09:30:00Z",
    "leave_kind": "annual",
    "message": "string",
    "confirm": false
  }
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_set_memory

TOOLtommy_set_memory

Update the operator's persistent AI memory document for this team. Call with merge: true to merge keys, or replace: true to overwrite. The document is read back via tommy://memory.

Parameters

documentobjectrequiredargument

Free-form JSON object (goals, audience, tone, anything the agent should remember).

mergebooleantrueargument

Merge document into existing memory (default).

replacebooleanfalseargument

Replace memory entirely instead of merging.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_set_memory
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_set_memory",
    "arguments": {
        "document": {},
        "merge": true,
        "replace": false
      }
  }
}
const result = await client.callTool("tommy_set_memory", {
  "document": {},
  "merge": true,
  "replace": false
});
result = await session.call_tool("tommy_set_memory", arguments={
  "document": {},
  "merge": true,
  "replace": false
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

tommy_request_support

TOOLtommy_request_support

Record a support request from the team. The request is logged and instrumented; a real ticket is created downstream by the support pipeline. Use this instead of exposing arbitrary contact channels.

Body

application/json
idempotency_keystring
attributesobject

Support ticket fields.

Show child attributes
summarystring

One-line summary.

detailsstring

Free-form detail.

categorystringbugbillingdataintegrationsonboardingother

What kind of issue?

urgencystringlownormalhighurgent

How urgent?

Parameters

idempotency_keystringargument
attributesobjectargument

Support ticket fields.

Returns

Returns MCP content array (text, image, or embedded resource).

tommy_request_support
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "tommy_request_support",
    "arguments": {
        "idempotency_key": "string",
        "attributes": {
          "summary": "string",
          "details": "string",
          "category": "bug",
          "urgency": "low"
        }
      }
  }
}
const result = await client.callTool("tommy_request_support", {
  "idempotency_key": "string",
  "attributes": {
    "summary": "string",
    "details": "string",
    "category": "bug",
    "urgency": "low"
  }
});
result = await session.call_tool("tommy_request_support", arguments={
  "idempotency_key": "string",
  "attributes": {
    "summary": "string",
    "details": "string",
    "category": "bug",
    "urgency": "low"
  }
})
Request Body
{
  "idempotency_key": "string",
  "attributes": {
    "summary": "string",
    "details": "string",
    "category": "bug",
    "urgency": "low"
  }
}
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Resources

guide

RESOURCEtommy://guide

Read first. Tommy vocabulary, recommended workflow, and tool conventions.

Returns

Returns MCP content array (text, image, or embedded resource).

guide
{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": {
    "uri": "tommy://guide"
  }
}
const result = await client.readResource("tommy://guide");
result = await session.read_resource("tommy://guide")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

team-current

RESOURCEtommy://team/current

Live snapshot of the active team: name, owner, counts (members, clients, shifts, availabilities, documents), and installed addons.

Returns

Returns MCP content array (text, image, or embedded resource).

team-current
{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": {
    "uri": "tommy://team/current"
  }
}
const result = await client.readResource("tommy://team/current");
result = await session.read_resource("tommy://team/current")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

features

RESOURCEtommy://features

Feature flags and addon slugs enabled for the active team.

Returns

Returns MCP content array (text, image, or embedded resource).

features
{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": {
    "uri": "tommy://features"
  }
}
const result = await client.readResource("tommy://features");
result = await session.read_resource("tommy://features")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

memory

RESOURCEtommy://memory

Operator memory document for this team. Free-form JSON the agent has saved (goals, audience, tone, anything worth remembering). Managed via tommy_set_memory.

Returns

Returns MCP content array (text, image, or embedded resource).

memory
{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": {
    "uri": "tommy://memory"
  }
}
const result = await client.readResource("tommy://memory");
result = await session.read_resource("tommy://memory")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

prompt

RESOURCEtommy://prompts/{name}

Rendered prompt template by name. Available names listed in the prompt registry.

Returns

Returns MCP content array (text, image, or embedded resource).

prompt
{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": {
    "uri": "tommy://prompts/{name}"
  }
}
const result = await client.readResource("tommy://prompts/{name}");
result = await session.read_resource("tommy://prompts/{name}")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

Prompts

documents

PROMPTdocuments

Workflow guidance for requesting, approving, and reminding on team documents.

Returns

Returns MCP content array (text, image, or embedded resource).

documents
{
  "jsonrpc": "2.0",
  "method": "prompts/get",
  "params": {
    "name": "documents",
    "arguments": {}
  }
}
const result = await client.getPrompt("documents");
result = await session.get_prompt("documents")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

shift-management

PROMPTshift-management

Workflow guidance for creating, updating, or cancelling shifts.

Parameters

shift_idstringargument

Optional shift identifier when working with an existing shift.

Returns

Returns MCP content array (text, image, or embedded resource).

shift-management
{
  "jsonrpc": "2.0",
  "method": "prompts/get",
  "params": {
    "name": "shift-management",
    "arguments": {
        "shift_id": "<shift_id>"
      }
  }
}
const result = await client.getPrompt("shift-management", {
  shift_id: "<shift_id>",
});
result = await session.get_prompt("shift-management", arguments={
    "shift_id": "<shift_id>",
})
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}

workforce-assistant

PROMPTworkforce-assistant

System prompt for the in-app workforce assistant. Covers tone, scope, and tool-use guidance.

Returns

Returns MCP content array (text, image, or embedded resource).

workforce-assistant
{
  "jsonrpc": "2.0",
  "method": "prompts/get",
  "params": {
    "name": "workforce-assistant",
    "arguments": {}
  }
}
const result = await client.getPrompt("workforce-assistant");
result = await session.get_prompt("workforce-assistant")
Response
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ]
}