tommy
v1.0.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 / offer). 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.
kindstringrequestdropswapofferFor 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.
kindstringrequestdropswapofferargumentFor 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,
"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
}
}){
"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
}
}{
"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",
"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
}
}){
"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
}
}{
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_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
documentobjectrequiredargumentFree-form JSON object (goals, audience, tone, anything the agent should remember).
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": {},
"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
}){
"content": [
{
"type": "text",
"text": "..."
}
]
}tommy_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
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.
Returns
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
documents
Workflow guidance for requesting, approving, and reminding on team documents.
Returns
Returns MCP content array (text, image, or embedded resource).
{
"jsonrpc": "2.0",
"method": "prompts/get",
"params": {
"name": "documents",
"arguments": {}
}
}const result = await client.getPrompt("documents");result = await session.get_prompt("documents"){
"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": "..."
}
]
}