tempo-api-mcp 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,203 +1,128 @@
1
- export const toolDefinitions = [
2
- {
3
- name: 'tempo_get_projects',
1
+ import { z } from 'zod';
2
+ export function register(server, client) {
3
+ server.registerTool('tempo_get_projects', {
4
4
  description: 'Retrieve a paginated list of all Tempo Financial Manager projects.',
5
5
  annotations: { readOnlyHint: true },
6
6
  inputSchema: {
7
- type: 'object',
8
- properties: {
9
- offset: { type: 'integer', description: 'Pagination offset' },
10
- limit: { type: 'integer', description: 'Max results (default 50)' },
11
- },
12
- required: [],
7
+ offset: z.number().int().optional().describe('Pagination offset'),
8
+ limit: z.number().int().optional().describe('Max results (default 50)'),
13
9
  },
14
- },
15
- {
16
- name: 'tempo_get_project',
10
+ }, async ({ offset, limit }) => {
11
+ const data = await client.request('GET', '/4/projects', undefined, { offset, limit });
12
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
13
+ });
14
+ server.registerTool('tempo_get_project', {
17
15
  description: 'Retrieve a single Tempo Financial Manager project by id.',
18
16
  annotations: { readOnlyHint: true },
19
17
  inputSchema: {
20
- type: 'object',
21
- properties: {
22
- id: { type: 'string', description: 'Project id' },
23
- },
24
- required: ['id'],
18
+ id: z.string().describe('Project id'),
25
19
  },
26
- },
27
- {
28
- name: 'tempo_get_timesheet_approval_status',
20
+ }, async ({ id }) => {
21
+ const data = await client.request('GET', `/4/projects/${id}`);
22
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
23
+ });
24
+ server.registerTool('tempo_get_timesheet_approval_status', {
29
25
  description: 'Retrieve the current timesheet approval status for a user in the given period.',
30
26
  annotations: { readOnlyHint: true },
31
27
  inputSchema: {
32
- type: 'object',
33
- properties: {
34
- accountId: { type: 'string', description: 'Atlassian account id of the user' },
35
- from: { type: 'string', description: 'Period start date (YYYY-MM-DD)' },
36
- to: { type: 'string', description: 'Period end date (YYYY-MM-DD)' },
37
- },
38
- required: ['accountId'],
28
+ accountId: z.string().describe('Atlassian account id of the user'),
29
+ from: z.string().optional().describe('Period start date (YYYY-MM-DD)'),
30
+ to: z.string().optional().describe('Period end date (YYYY-MM-DD)'),
39
31
  },
40
- },
41
- {
42
- name: 'tempo_get_timesheet_approvals_waiting',
32
+ }, async ({ accountId, from, to }) => {
33
+ const data = await client.request('GET', `/4/timesheet-approvals/user/${accountId}`, undefined, { from, to });
34
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
35
+ });
36
+ server.registerTool('tempo_get_timesheet_approvals_waiting', {
43
37
  description: 'Retrieve all timesheets that are currently waiting for approval.',
44
38
  annotations: { readOnlyHint: true },
45
39
  inputSchema: {
46
- type: 'object',
47
- properties: {
48
- offset: { type: 'integer', description: 'Pagination offset' },
49
- limit: { type: 'integer', description: 'Max results' },
50
- },
51
- required: [],
40
+ offset: z.number().int().optional().describe('Pagination offset'),
41
+ limit: z.number().int().optional().describe('Max results'),
52
42
  },
53
- },
54
- {
55
- name: 'tempo_search_timesheet_approval_logs',
43
+ }, async ({ offset, limit }) => {
44
+ const data = await client.request('GET', '/4/timesheet-approvals/waiting', undefined, { offset, limit });
45
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
46
+ });
47
+ server.registerTool('tempo_search_timesheet_approval_logs', {
56
48
  description: 'Search timesheet approval audit logs.',
57
49
  annotations: { readOnlyHint: true },
58
50
  inputSchema: {
59
- type: 'object',
60
- properties: {
61
- accountIds: { type: 'array', items: { type: 'string' }, description: 'Filter by Atlassian account ids' },
62
- reviewerIds: { type: 'array', items: { type: 'string' }, description: 'Filter by reviewer account ids' },
63
- from: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
64
- to: { type: 'string', description: 'End date (YYYY-MM-DD)' },
65
- offset: { type: 'integer', description: 'Pagination offset' },
66
- limit: { type: 'integer', description: 'Max results' },
67
- },
68
- required: [],
51
+ accountIds: z.array(z.string()).optional().describe('Filter by Atlassian account ids'),
52
+ reviewerIds: z.array(z.string()).optional().describe('Filter by reviewer account ids'),
53
+ from: z.string().optional().describe('Start date (YYYY-MM-DD)'),
54
+ to: z.string().optional().describe('End date (YYYY-MM-DD)'),
55
+ offset: z.number().int().optional().describe('Pagination offset'),
56
+ limit: z.number().int().optional().describe('Max results'),
69
57
  },
70
- },
71
- {
72
- name: 'tempo_get_periods',
58
+ }, async ({ accountIds, reviewerIds, from, to, offset, limit }) => {
59
+ const qs = {};
60
+ if (offset !== undefined)
61
+ qs.offset = offset;
62
+ if (limit !== undefined)
63
+ qs.limit = limit;
64
+ const body = {};
65
+ if (accountIds)
66
+ body.accountIds = accountIds;
67
+ if (reviewerIds)
68
+ body.reviewerIds = reviewerIds;
69
+ if (from)
70
+ body.from = from;
71
+ if (to)
72
+ body.to = to;
73
+ const data = await client.request('POST', '/4/timesheet-approvals/logs/search', body, qs);
74
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
75
+ });
76
+ server.registerTool('tempo_get_periods', {
73
77
  description: 'Retrieve Tempo period definitions (used for timesheet approval cycles).',
74
78
  annotations: { readOnlyHint: true },
75
79
  inputSchema: {
76
- type: 'object',
77
- properties: {
78
- from: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
79
- to: { type: 'string', description: 'End date (YYYY-MM-DD)' },
80
- },
81
- required: [],
80
+ from: z.string().optional().describe('Start date (YYYY-MM-DD)'),
81
+ to: z.string().optional().describe('End date (YYYY-MM-DD)'),
82
82
  },
83
- },
84
- {
85
- name: 'tempo_get_user_schedule',
83
+ }, async ({ from, to }) => {
84
+ const data = await client.request('GET', '/4/periods', undefined, { from, to });
85
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
86
+ });
87
+ server.registerTool('tempo_get_user_schedule', {
86
88
  description: 'Retrieve the work schedule for a user, including planned working hours per day.',
87
89
  annotations: { readOnlyHint: true },
88
90
  inputSchema: {
89
- type: 'object',
90
- properties: {
91
- accountId: { type: 'string', description: 'Atlassian account id of the user' },
92
- from: { type: 'string', description: 'Start date (YYYY-MM-DD)' },
93
- to: { type: 'string', description: 'End date (YYYY-MM-DD)' },
94
- },
95
- required: ['accountId', 'from', 'to'],
91
+ accountId: z.string().describe('Atlassian account id of the user'),
92
+ from: z.string().describe('Start date (YYYY-MM-DD)'),
93
+ to: z.string().describe('End date (YYYY-MM-DD)'),
96
94
  },
97
- },
98
- {
99
- name: 'tempo_get_global_configuration',
95
+ }, async ({ accountId, from, to }) => {
96
+ const data = await client.request('GET', `/4/user-schedule`, undefined, { accountId, from, to });
97
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
98
+ });
99
+ server.registerTool('tempo_get_global_configuration', {
100
100
  description: 'Retrieve the global Tempo configuration settings.',
101
101
  annotations: { readOnlyHint: true },
102
- inputSchema: {
103
- type: 'object',
104
- properties: {},
105
- required: [],
106
- },
107
- },
108
- {
109
- name: 'tempo_get_work_attributes',
102
+ }, async () => {
103
+ const data = await client.request('GET', '/4/globalconfiguration');
104
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
105
+ });
106
+ server.registerTool('tempo_get_work_attributes', {
110
107
  description: 'Retrieve all Tempo work attributes (custom fields on worklogs).',
111
108
  annotations: { readOnlyHint: true },
112
109
  inputSchema: {
113
- type: 'object',
114
- properties: {
115
- offset: { type: 'integer', description: 'Pagination offset' },
116
- limit: { type: 'integer', description: 'Max results' },
117
- },
118
- required: [],
110
+ offset: z.number().int().optional().describe('Pagination offset'),
111
+ limit: z.number().int().optional().describe('Max results'),
119
112
  },
120
- },
121
- {
122
- name: 'tempo_get_roles',
113
+ }, async ({ offset, limit }) => {
114
+ const data = await client.request('GET', '/4/work-attributes', undefined, { offset, limit });
115
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
116
+ });
117
+ server.registerTool('tempo_get_roles', {
123
118
  description: 'Retrieve all Tempo roles.',
124
119
  annotations: { readOnlyHint: true },
125
120
  inputSchema: {
126
- type: 'object',
127
- properties: {
128
- offset: { type: 'integer', description: 'Pagination offset' },
129
- limit: { type: 'integer', description: 'Max results' },
130
- },
131
- required: [],
121
+ offset: z.number().int().optional().describe('Pagination offset'),
122
+ limit: z.number().int().optional().describe('Max results'),
132
123
  },
133
- },
134
- ];
135
- export async function handleTool(name, args, client) {
136
- switch (name) {
137
- case 'tempo_get_projects': {
138
- const { offset, limit } = args;
139
- const data = await client.request('GET', '/4/projects', undefined, { offset, limit });
140
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
141
- }
142
- case 'tempo_get_project': {
143
- const { id } = args;
144
- const data = await client.request('GET', `/4/projects/${id}`);
145
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
146
- }
147
- case 'tempo_get_timesheet_approval_status': {
148
- const { accountId, from, to } = args;
149
- const data = await client.request('GET', `/4/timesheet-approvals/user/${accountId}`, undefined, { from, to });
150
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
151
- }
152
- case 'tempo_get_timesheet_approvals_waiting': {
153
- const { offset, limit } = args;
154
- const data = await client.request('GET', '/4/timesheet-approvals/waiting', undefined, { offset, limit });
155
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
156
- }
157
- case 'tempo_search_timesheet_approval_logs': {
158
- const { accountIds, reviewerIds, from, to, offset, limit } = args;
159
- const qs = {};
160
- if (offset !== undefined)
161
- qs.offset = offset;
162
- if (limit !== undefined)
163
- qs.limit = limit;
164
- const body = {};
165
- if (accountIds)
166
- body.accountIds = accountIds;
167
- if (reviewerIds)
168
- body.reviewerIds = reviewerIds;
169
- if (from)
170
- body.from = from;
171
- if (to)
172
- body.to = to;
173
- const data = await client.request('POST', '/4/timesheet-approvals/logs/search', body, qs);
174
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
175
- }
176
- case 'tempo_get_periods': {
177
- const { from, to } = args;
178
- const data = await client.request('GET', '/4/periods', undefined, { from, to });
179
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
180
- }
181
- case 'tempo_get_user_schedule': {
182
- const { accountId, from, to } = args;
183
- const data = await client.request('GET', `/4/user-schedule`, undefined, { accountId, from, to });
184
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
185
- }
186
- case 'tempo_get_global_configuration': {
187
- const data = await client.request('GET', '/4/globalconfiguration');
188
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
189
- }
190
- case 'tempo_get_work_attributes': {
191
- const { offset, limit } = args;
192
- const data = await client.request('GET', '/4/work-attributes', undefined, { offset, limit });
193
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
194
- }
195
- case 'tempo_get_roles': {
196
- const { offset, limit } = args;
197
- const data = await client.request('GET', '/4/roles', undefined, { offset, limit });
198
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
199
- }
200
- default:
201
- throw new Error(`Unknown tool: ${name}`);
202
- }
124
+ }, async ({ offset, limit }) => {
125
+ const data = await client.request('GET', '/4/roles', undefined, { offset, limit });
126
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
127
+ });
203
128
  }
@@ -1,176 +1,123 @@
1
- export const toolDefinitions = [
2
- {
3
- name: 'tempo_get_teams',
1
+ import { z } from 'zod';
2
+ function buildTeamBody(args) {
3
+ const body = { name: args.name };
4
+ if (args.summary !== undefined)
5
+ body.summary = args.summary;
6
+ if (args.leadAccountId !== undefined)
7
+ body.leadAccountId = args.leadAccountId;
8
+ if (args.programId !== undefined)
9
+ body.programId = args.programId;
10
+ return body;
11
+ }
12
+ export function register(server, client) {
13
+ server.registerTool('tempo_get_teams', {
4
14
  description: 'Retrieve a list of Tempo teams. Can filter by name, member account ids, or specific team ids.',
5
15
  annotations: { readOnlyHint: true },
6
16
  inputSchema: {
7
- type: 'object',
8
- properties: {
9
- name: { type: 'string', description: 'Filter by team name' },
10
- teamIds: { type: 'array', items: { type: 'integer' }, description: 'Filter by specific team ids' },
11
- teamMembers: { type: 'array', items: { type: 'string' }, description: 'Filter by member Atlassian account ids' },
12
- includeMemberships: { type: 'boolean', description: 'Include team member memberships in response' },
13
- offset: { type: 'integer', description: 'Pagination offset' },
14
- limit: { type: 'integer', description: 'Max results (default 50)' },
15
- },
16
- required: [],
17
+ name: z.string().optional().describe('Filter by team name'),
18
+ teamIds: z.array(z.number().int()).optional().describe('Filter by specific team ids'),
19
+ teamMembers: z.array(z.string()).optional().describe('Filter by member Atlassian account ids'),
20
+ includeMemberships: z.boolean().optional().describe('Include team member memberships in response'),
21
+ offset: z.number().int().optional().describe('Pagination offset'),
22
+ limit: z.number().int().optional().describe('Max results (default 50)'),
17
23
  },
18
- },
19
- {
20
- name: 'tempo_get_team',
24
+ }, async ({ name: teamName, teamIds, teamMembers, includeMemberships, offset, limit }) => {
25
+ const data = await client.request('GET', '/4/teams', undefined, {
26
+ name: teamName, teamIds, teamMembers, includeMemberships, offset, limit,
27
+ });
28
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
29
+ });
30
+ server.registerTool('tempo_get_team', {
21
31
  description: 'Retrieve a single Tempo team by id.',
22
32
  annotations: { readOnlyHint: true },
23
33
  inputSchema: {
24
- type: 'object',
25
- properties: {
26
- id: { type: 'integer', description: 'Team id' },
27
- },
28
- required: ['id'],
34
+ id: z.number().int().describe('Team id'),
29
35
  },
30
- },
31
- {
32
- name: 'tempo_create_team',
36
+ }, async ({ id }) => {
37
+ const data = await client.request('GET', `/4/teams/${id}`);
38
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
39
+ });
40
+ server.registerTool('tempo_create_team', {
33
41
  description: 'Create a new Tempo team.',
34
42
  annotations: { readOnlyHint: false },
35
43
  inputSchema: {
36
- type: 'object',
37
- properties: {
38
- name: { type: 'string', description: 'Team name' },
39
- summary: { type: 'string', description: 'Short description of the team' },
40
- leadAccountId: { type: 'string', description: 'Atlassian account id of the team lead' },
41
- programId: { type: 'integer', description: 'Id of the program this team belongs to' },
42
- },
43
- required: ['name'],
44
+ name: z.string().describe('Team name'),
45
+ summary: z.string().optional().describe('Short description of the team'),
46
+ leadAccountId: z.string().optional().describe('Atlassian account id of the team lead'),
47
+ programId: z.number().int().optional().describe('Id of the program this team belongs to'),
44
48
  },
45
- },
46
- {
47
- name: 'tempo_update_team',
49
+ }, async (args) => {
50
+ const body = buildTeamBody(args);
51
+ const data = await client.request('POST', '/4/teams', body);
52
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
53
+ });
54
+ server.registerTool('tempo_update_team', {
48
55
  description: 'Update an existing Tempo team by id.',
49
56
  annotations: { readOnlyHint: false },
50
57
  inputSchema: {
51
- type: 'object',
52
- properties: {
53
- id: { type: 'integer', description: 'Team id' },
54
- name: { type: 'string', description: 'Team name' },
55
- summary: { type: 'string', description: 'Short description of the team' },
56
- leadAccountId: { type: 'string', description: 'Atlassian account id of the team lead' },
57
- programId: { type: 'integer', description: 'Id of the program this team belongs to' },
58
- },
59
- required: ['id', 'name'],
58
+ id: z.number().int().describe('Team id'),
59
+ name: z.string().describe('Team name'),
60
+ summary: z.string().optional().describe('Short description of the team'),
61
+ leadAccountId: z.string().optional().describe('Atlassian account id of the team lead'),
62
+ programId: z.number().int().optional().describe('Id of the program this team belongs to'),
60
63
  },
61
- },
62
- {
63
- name: 'tempo_delete_team',
64
+ }, async ({ id, ...rest }) => {
65
+ const body = buildTeamBody(rest);
66
+ const data = await client.request('PUT', `/4/teams/${id}`, body);
67
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
68
+ });
69
+ server.registerTool('tempo_delete_team', {
64
70
  description: 'Delete a Tempo team by id.',
65
71
  annotations: { readOnlyHint: false },
66
72
  inputSchema: {
67
- type: 'object',
68
- properties: {
69
- id: { type: 'integer', description: 'Team id' },
70
- },
71
- required: ['id'],
73
+ id: z.number().int().describe('Team id'),
72
74
  },
73
- },
74
- {
75
- name: 'tempo_get_team_memberships',
75
+ }, async ({ id }) => {
76
+ await client.request('DELETE', `/4/teams/${id}`);
77
+ return { content: [{ type: 'text', text: `Team ${id} deleted successfully` }] };
78
+ });
79
+ server.registerTool('tempo_get_team_memberships', {
76
80
  description: 'Retrieve team memberships, optionally filtered by account id or team id.',
77
81
  annotations: { readOnlyHint: true },
78
82
  inputSchema: {
79
- type: 'object',
80
- properties: {
81
- accountIds: { type: 'array', items: { type: 'string' }, description: 'Filter by Atlassian account ids' },
82
- teamIds: { type: 'array', items: { type: 'integer' }, description: 'Filter by team ids' },
83
- offset: { type: 'integer', description: 'Pagination offset' },
84
- limit: { type: 'integer', description: 'Max results (default 50)' },
85
- },
86
- required: [],
83
+ accountIds: z.array(z.string()).optional().describe('Filter by Atlassian account ids'),
84
+ teamIds: z.array(z.number().int()).optional().describe('Filter by team ids'),
85
+ offset: z.number().int().optional().describe('Pagination offset'),
86
+ limit: z.number().int().optional().describe('Max results (default 50)'),
87
87
  },
88
- },
89
- {
90
- name: 'tempo_search_team_memberships',
88
+ }, async ({ accountIds, teamIds, offset, limit }) => {
89
+ const data = await client.request('GET', '/4/team-memberships', undefined, {
90
+ accountIds, teamIds, offset, limit,
91
+ });
92
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
93
+ });
94
+ server.registerTool('tempo_search_team_memberships', {
91
95
  description: 'Search Tempo team memberships with advanced filters via POST.',
92
96
  annotations: { readOnlyHint: true },
93
97
  inputSchema: {
94
- type: 'object',
95
- properties: {
96
- teamIds: { type: 'array', items: { type: 'integer' }, description: 'Filter by team ids' },
97
- accountIds: { type: 'array', items: { type: 'string' }, description: 'Filter by Atlassian account ids' },
98
- from: { type: 'string', description: 'Membership active from date (YYYY-MM-DD)' },
99
- to: { type: 'string', description: 'Membership active to date (YYYY-MM-DD)' },
100
- offset: { type: 'integer', description: 'Pagination offset' },
101
- limit: { type: 'integer', description: 'Max results' },
102
- },
103
- required: [],
98
+ teamIds: z.array(z.number().int()).optional().describe('Filter by team ids'),
99
+ accountIds: z.array(z.string()).optional().describe('Filter by Atlassian account ids'),
100
+ from: z.string().optional().describe('Membership active from date (YYYY-MM-DD)'),
101
+ to: z.string().optional().describe('Membership active to date (YYYY-MM-DD)'),
102
+ offset: z.number().int().optional().describe('Pagination offset'),
103
+ limit: z.number().int().optional().describe('Max results'),
104
104
  },
105
- },
106
- ];
107
- function buildTeamBody(args) {
108
- const body = { name: args.name };
109
- if (args.summary !== undefined)
110
- body.summary = args.summary;
111
- if (args.leadAccountId !== undefined)
112
- body.leadAccountId = args.leadAccountId;
113
- if (args.programId !== undefined)
114
- body.programId = args.programId;
115
- return body;
116
- }
117
- export async function handleTool(name, args, client) {
118
- switch (name) {
119
- case 'tempo_get_teams': {
120
- const { name: teamName, teamIds, teamMembers, includeMemberships, offset, limit } = args;
121
- const data = await client.request('GET', '/4/teams', undefined, {
122
- name: teamName, teamIds, teamMembers, includeMemberships, offset, limit,
123
- });
124
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
125
- }
126
- case 'tempo_get_team': {
127
- const { id } = args;
128
- const data = await client.request('GET', `/4/teams/${id}`);
129
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
130
- }
131
- case 'tempo_create_team': {
132
- const body = buildTeamBody(args);
133
- const data = await client.request('POST', '/4/teams', body);
134
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
135
- }
136
- case 'tempo_update_team': {
137
- const { id, ...rest } = args;
138
- const body = buildTeamBody(rest);
139
- const data = await client.request('PUT', `/4/teams/${id}`, body);
140
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
141
- }
142
- case 'tempo_delete_team': {
143
- const { id } = args;
144
- await client.request('DELETE', `/4/teams/${id}`);
145
- return { content: [{ type: 'text', text: `Team ${id} deleted successfully` }] };
146
- }
147
- case 'tempo_get_team_memberships': {
148
- const { accountIds, teamIds, offset, limit } = args;
149
- const data = await client.request('GET', '/4/team-memberships', undefined, {
150
- accountIds, teamIds, offset, limit,
151
- });
152
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
153
- }
154
- case 'tempo_search_team_memberships': {
155
- const { teamIds, accountIds, from, to, offset, limit } = args;
156
- const query = {};
157
- if (offset !== undefined)
158
- query.offset = offset;
159
- if (limit !== undefined)
160
- query.limit = limit;
161
- const body = {};
162
- if (teamIds)
163
- body.teamIds = teamIds;
164
- if (accountIds)
165
- body.accountIds = accountIds;
166
- if (from)
167
- body.from = from;
168
- if (to)
169
- body.to = to;
170
- const data = await client.request('POST', '/4/team-memberships/search', body, query);
171
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
172
- }
173
- default:
174
- throw new Error(`Unknown tool: ${name}`);
175
- }
105
+ }, async ({ teamIds, accountIds, from, to, offset, limit }) => {
106
+ const query = {};
107
+ if (offset !== undefined)
108
+ query.offset = offset;
109
+ if (limit !== undefined)
110
+ query.limit = limit;
111
+ const body = {};
112
+ if (teamIds)
113
+ body.teamIds = teamIds;
114
+ if (accountIds)
115
+ body.accountIds = accountIds;
116
+ if (from)
117
+ body.from = from;
118
+ if (to)
119
+ body.to = to;
120
+ const data = await client.request('POST', '/4/team-memberships/search', body, query);
121
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
122
+ });
176
123
  }