tommy
v1.1.0https://api.mytommy.com/mcpWorkforce, scheduling, documents, and chat for service teams.
Add to your MCP client configuration:
Tools
tommy_get_status
read-onlyidempotentGet current account/team readiness, recent activity counts, and recommended next actions.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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={}){
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_query
read-onlyidempotentRead-only paginated lookup across approved Tommy entity types: shifts, availabilities, documents, clients, contacts, team_members. Pagination via page/per.
Parameters
entitystringshiftsavailabilitiesdocumentsclientscontactsteam_membersrequiredargumentThe entity type to list.
pageinteger1argumentperinteger[1, 100]25argumentidinteger | stringargumentOptional single-record lookup by id.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_search_people
read-onlyidempotentSearch across team_members, clients, or contacts by name/email. Pass kind to narrow; q is the case-insensitive search term.
Parameters
qstringrequiredargumentSearch text (matches name, email, phone).
kindstringteam_membersclientscontactsargumentOptional. Defaults to all kinds.
perinteger[1, 100]25argumentReturns
Returns MCP content array (text, image, or embedded resource).
{
"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
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_get_insights
read-onlyidempotentRead-only summaries and metrics for the active team. Pass metric to narrow: overview, attendance, shifts, documents.
Parameters
metricstringoverviewattendanceshiftsdocumentsoverviewargumentwindowstring24h7d30d90d7dargumentLookback window for time-series metrics.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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"
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_manage_shift
destructiveCreate, update, cancel, drop, or swap a workforce shift. Pass dry_run: true to preview. Cancel/drop/swap require attributes.confirm: true.
Body
operationstringcreateupdatecanceldropswaprequiredWhat to do.
shift_idinteger | stringFor update/cancel/drop/swap.
dry_runbooleanfalsePreview without applying.
idempotency_keystringDedupe retries.
attributesobjectShift fields to set or update.
Parameters
operationstringcreateupdatecanceldropswaprequiredargumentWhat to do.
shift_idinteger | stringargumentFor update/cancel/drop/swap.
dry_runbooleanfalseargumentPreview without applying.
idempotency_keystringargumentDedupe retries.
attributesobjectargumentShift fields to set or update.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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
}
}){
"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
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_manage_shift_requirements
destructiveCreate, update, cancel, approve, or reject a shift request (request / drop / swap). approve_request, reject_request, and cancel_request require attributes.confirm: true.
Body
operationstringcreate_requestupdate_requestcancel_requestapprove_requestreject_requestrequiredWhat to do.
request_idinteger | stringFor update/cancel/approve/reject.
shift_idinteger | stringFor create_request.
kindstringrequestdropswapFor create_request: what kind of request.
dry_runbooleanfalseidempotency_keystringattributesobjectOptional fields for create/update.
Parameters
operationstringcreate_requestupdate_requestcancel_requestapprove_requestreject_requestrequiredargumentWhat to do.
request_idinteger | stringargumentFor update/cancel/approve/reject.
shift_idinteger | stringargumentFor create_request.
kindstringrequestdropswapargumentFor create_request: what kind of request.
dry_runbooleanfalseargumentidempotency_keystringargumentattributesobjectargumentOptional fields for create/update.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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,
"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,
"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,
"confirm": false
}
}){
"operation": "create_request",
"request_id": 0,
"shift_id": 0,
"kind": "request",
"dry_run": false,
"idempotency_key": "string",
"attributes": {
"swap_shift_id": 0,
"confirm": false
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_manage_availability
Update an availability record or record a clock-in/out attendance.
Body
operationstringupdateclock_inclock_outrequiredWhat to do.
availability_idinteger | stringFor update.
attendance_idinteger | stringFor clock_out.
team_member_idinteger | stringFor clock_in/clock_out: who is clocking in or out.
dry_runbooleanfalseidempotency_keystringattributesobjectAvailability or attendance fields.
Parameters
operationstringupdateclock_inclock_outrequiredargumentWhat to do.
availability_idinteger | stringargumentFor update.
attendance_idinteger | stringargumentFor clock_out.
team_member_idinteger | stringargumentFor clock_in/clock_out: who is clocking in or out.
dry_runbooleanfalseargumentidempotency_keystringargumentattributesobjectargumentAvailability or attendance fields.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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"
}
}){
"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"
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_manage_documents
destructiveCreate, update, cancel, approve, or reject a leave request. Approve/reject/cancel require attributes.confirm: true.
Body
operationstringcreate_leaveupdate_leavecancel_leaveapprove_leavereject_leaverequiredWhat to do.
leave_idinteger | stringFor update/cancel/approve/reject.
dry_runbooleanfalsePreview without applying.
idempotency_keystringattributesobjectLeave request fields.
Parameters
operationstringcreate_leaveupdate_leavecancel_leaveapprove_leavereject_leaverequiredargumentWhat to do.
leave_idinteger | stringargumentFor update/cancel/approve/reject.
dry_runbooleanfalseargumentPreview without applying.
idempotency_keystringargumentattributesobjectargumentLeave request fields.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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",
"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",
"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",
"confirm": false
}
}){
"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",
"confirm": false
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_manage_dashboards
Add tabs or panels to team dashboards, set tab visibility, or reorder tabs. Requires the manage_dashboards permission. Use dry_run to preview and an idempotency_key to safely retry a write.
Body
operationstringadd_tabadd_panelset_visibilityreorderrequiredWhat to do.
dry_runbooleanfalsePreview the mutation without writing.
idempotency_keystringDedupe retries of the same write.
attributesobjectFields for the chosen operation.
Parameters
operationstringadd_tabadd_panelset_visibilityreorderrequiredargumentWhat to do.
dry_runbooleanfalseargumentPreview the mutation without writing.
idempotency_keystringargumentDedupe retries of the same write.
attributesobjectargumentFields for the chosen operation.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "tommy_manage_dashboards",
"arguments": {
"operation": "add_tab",
"dry_run": false,
"idempotency_key": "string",
"attributes": {
"surface": "dashboard",
"title": "string",
"slug": "string",
"icon": "string",
"tab": "string",
"mp_id": "string",
"panel_id": "string",
"x": 0,
"y": 0,
"w": 0,
"h": 0,
"params": {},
"config": {},
"visibility": {},
"ordered": [
"string"
]
}
}
}
}const result = await client.callTool("tommy_manage_dashboards", {
"operation": "add_tab",
"dry_run": false,
"idempotency_key": "string",
"attributes": {
"surface": "dashboard",
"title": "string",
"slug": "string",
"icon": "string",
"tab": "string",
"mp_id": "string",
"panel_id": "string",
"x": 0,
"y": 0,
"w": 0,
"h": 0,
"params": {},
"config": {},
"visibility": {},
"ordered": [
"string"
]
}
});result = await session.call_tool("tommy_manage_dashboards", arguments={
"operation": "add_tab",
"dry_run": false,
"idempotency_key": "string",
"attributes": {
"surface": "dashboard",
"title": "string",
"slug": "string",
"icon": "string",
"tab": "string",
"mp_id": "string",
"panel_id": "string",
"x": 0,
"y": 0,
"w": 0,
"h": 0,
"params": {},
"config": {},
"visibility": {},
"ordered": [
"string"
]
}
}){
"operation": "add_tab",
"dry_run": false,
"idempotency_key": "string",
"attributes": {
"surface": "dashboard",
"title": "string",
"slug": "string",
"icon": "string",
"tab": "string",
"mp_id": "string",
"panel_id": "string",
"x": 0,
"y": 0,
"w": 0,
"h": 0,
"params": {},
"config": {},
"visibility": {},
"ordered": [
"string"
]
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_set_memory
idempotentUpdate 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
documentobjectrequiredargumentFree-form JSON object (goals, audience, tone, anything the agent should remember).
idempotency_keystringargumentDedupe retries.
mergebooleantrueargumentMerge document into existing memory (default).
replacebooleanfalseargumentReplace memory entirely instead of merging.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "tommy_set_memory",
"arguments": {
"document": {},
"idempotency_key": "string",
"merge": true,
"replace": false
}
}
}const result = await client.callTool("tommy_set_memory", {
"document": {},
"idempotency_key": "string",
"merge": true,
"replace": false
});result = await session.call_tool("tommy_set_memory", arguments={
"document": {},
"idempotency_key": "string",
"merge": true,
"replace": false
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_request_support
Record a durable support request and queue it for delivery to the Tommy support inbox.
Body
idempotency_keystringattributesobjectSupport ticket fields.
Parameters
idempotency_keystringargumentattributesobjectargumentSupport ticket fields.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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"
}
}){
"idempotency_key": "string",
"attributes": {
"summary": "string",
"details": "string",
"category": "bug",
"urgency": "low"
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}Resources
guide
Read first. Tommy vocabulary, recommended workflow, and tool conventions.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "tommy://guide"
}
}const result = await client.readResource("tommy://guide");result = await session.read_resource("tommy://guide"){
"content": [
{
"type": "text",
"text": "..."
}
]
}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).
{
"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"){
"content": [
{
"type": "text",
"text": "..."
}
]
}features
Feature flags and addon slugs enabled for the active team.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "tommy://features"
}
}const result = await client.readResource("tommy://features");result = await session.read_resource("tommy://features"){
"content": [
{
"type": "text",
"text": "..."
}
]
}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).
{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "tommy://memory"
}
}const result = await client.readResource("tommy://memory");result = await session.read_resource("tommy://memory"){
"content": [
{
"type": "text",
"text": "..."
}
]
}prompt
Rendered prompt template by name. Available names listed in the prompt registry.
Parameters
namestringrequiredpathReturns
Returns MCP content array (text, image, or embedded resource).
{
"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}"){
"content": [
{
"type": "text",
"text": "..."
}
]
}Prompts
leave
Workflow guidance for requesting, approving, rejecting, and cancelling leave.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"jsonrpc": "2.0",
"method": "prompts/get",
"params": {
"name": "leave",
"arguments": {}
}
}const result = await client.getPrompt("leave");result = await session.get_prompt("leave"){
"content": [
{
"type": "text",
"text": "..."
}
]
}shift-management
Workflow guidance for creating, updating, or cancelling shifts.
Parameters
shift_idstringargumentOptional shift identifier when working with an existing shift.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"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>",
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}workforce-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).
{
"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"){
"content": [
{
"type": "text",
"text": "..."
}
]
}