freeagent-mcp-server 1.0.0

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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +359 -0
  3. package/build/client.d.ts +18 -0
  4. package/build/client.js +93 -0
  5. package/build/client.js.map +1 -0
  6. package/build/index.d.ts +2 -0
  7. package/build/index.js +53 -0
  8. package/build/index.js.map +1 -0
  9. package/build/tools/accounting.d.ts +3 -0
  10. package/build/tools/accounting.js +81 -0
  11. package/build/tools/accounting.js.map +1 -0
  12. package/build/tools/banking.d.ts +3 -0
  13. package/build/tools/banking.js +151 -0
  14. package/build/tools/banking.js.map +1 -0
  15. package/build/tools/bills.d.ts +3 -0
  16. package/build/tools/bills.js +127 -0
  17. package/build/tools/bills.js.map +1 -0
  18. package/build/tools/categories.d.ts +3 -0
  19. package/build/tools/categories.js +33 -0
  20. package/build/tools/categories.js.map +1 -0
  21. package/build/tools/company.d.ts +3 -0
  22. package/build/tools/company.js +46 -0
  23. package/build/tools/company.js.map +1 -0
  24. package/build/tools/contacts.d.ts +3 -0
  25. package/build/tools/contacts.js +171 -0
  26. package/build/tools/contacts.js.map +1 -0
  27. package/build/tools/credit-notes.d.ts +3 -0
  28. package/build/tools/credit-notes.js +139 -0
  29. package/build/tools/credit-notes.js.map +1 -0
  30. package/build/tools/estimates.d.ts +3 -0
  31. package/build/tools/estimates.js +150 -0
  32. package/build/tools/estimates.js.map +1 -0
  33. package/build/tools/expenses.d.ts +3 -0
  34. package/build/tools/expenses.js +155 -0
  35. package/build/tools/expenses.js.map +1 -0
  36. package/build/tools/invoices.d.ts +3 -0
  37. package/build/tools/invoices.js +166 -0
  38. package/build/tools/invoices.js.map +1 -0
  39. package/build/tools/projects.d.ts +3 -0
  40. package/build/tools/projects.js +107 -0
  41. package/build/tools/projects.js.map +1 -0
  42. package/build/tools/tasks.d.ts +3 -0
  43. package/build/tools/tasks.js +159 -0
  44. package/build/tools/tasks.js.map +1 -0
  45. package/build/tools/timeslips.d.ts +3 -0
  46. package/build/tools/timeslips.js +194 -0
  47. package/build/tools/timeslips.js.map +1 -0
  48. package/build/tools/users.d.ts +3 -0
  49. package/build/tools/users.js +136 -0
  50. package/build/tools/users.js.map +1 -0
  51. package/build/utils.d.ts +18 -0
  52. package/build/utils.js +37 -0
  53. package/build/utils.js.map +1 -0
  54. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sam
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,359 @@
1
+ # freeagent-mcp
2
+
3
+ [![npm version](https://img.shields.io/npm/v/freeagent-mcp.svg)](https://www.npmjs.com/package/freeagent-mcp)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ MCP server for the [FreeAgent](https://www.freeagent.com/) accounting API. Provides 76 tools covering invoices, expenses, contacts, projects, timeslips, banking, bills, estimates, credit notes, accounting reports, and more.
7
+
8
+ ## Features
9
+
10
+ - **Company** - Company info, business categories, tax timeline
11
+ - **Users** - List, get, create, update, and delete users
12
+ - **Contacts** - Full CRUD for clients and suppliers
13
+ - **Projects** - Create and manage projects
14
+ - **Tasks** - Manage project tasks with billing rates
15
+ - **Timeslips** - Track time with start/stop timer support
16
+ - **Invoices** - Create, send, and manage invoices with status transitions
17
+ - **Estimates** - Quotes, estimates, and proposals with approval workflows
18
+ - **Bills** - Manage supplier bills
19
+ - **Credit Notes** - Issue and manage credit notes
20
+ - **Expenses** - Track and categorize expenses
21
+ - **Banking** - Bank accounts and transaction management
22
+ - **Categories** - Browse accounting categories
23
+ - **Accounting Reports** - Profit & loss, balance sheet, trial balance
24
+
25
+ ## Prerequisites
26
+
27
+ You need a FreeAgent account and OAuth2 access token. To get one:
28
+
29
+ 1. Sign up for a [FreeAgent Developer](https://dev.freeagent.com/) account
30
+ 2. Create a sandbox account for testing
31
+ 3. Register an application to get OAuth credentials
32
+ 4. Complete the OAuth2 authorization flow to obtain an access token
33
+
34
+ See the [FreeAgent API Quick Start](https://dev.freeagent.com/docs/quick_start) for detailed instructions.
35
+
36
+ ## Installation
37
+
38
+ ### Using npx (recommended)
39
+
40
+ ```bash
41
+ npx freeagent-mcp-server
42
+ ```
43
+
44
+ ### Global install
45
+
46
+ ```bash
47
+ npm install -g freeagent-mcp-server
48
+ freeagent-mcp
49
+ ```
50
+
51
+ ### Build from source
52
+
53
+ ```bash
54
+ git clone https://github.com/samaxbytez/freeagent-mcp.git
55
+ cd freeagent-mcp
56
+ npm install
57
+ npm run build
58
+ npm start
59
+ ```
60
+
61
+ ## Configuration
62
+
63
+ ### Environment Variables
64
+
65
+ | Variable | Required | Description |
66
+ |----------|----------|-------------|
67
+ | `FREEAGENT_ACCESS_TOKEN` | Yes | Your FreeAgent OAuth2 access token |
68
+ | `FREEAGENT_BASE_URL` | No | API base URL (defaults to `https://api.sandbox.freeagent.com/v2`) |
69
+
70
+ For production, set:
71
+ ```
72
+ FREEAGENT_BASE_URL=https://api.freeagent.com/v2
73
+ ```
74
+
75
+ ### Claude Desktop
76
+
77
+ Add to your `claude_desktop_config.json`:
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "freeagent": {
83
+ "command": "npx",
84
+ "args": ["-y", "freeagent-mcp-server"],
85
+ "env": {
86
+ "FREEAGENT_ACCESS_TOKEN": "your_access_token_here"
87
+ }
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### Claude Code
94
+
95
+ Add to your `.mcp.json`:
96
+
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "freeagent": {
101
+ "command": "npx",
102
+ "args": ["-y", "freeagent-mcp-server"],
103
+ "env": {
104
+ "FREEAGENT_ACCESS_TOKEN": "your_access_token_here"
105
+ }
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Architecture
112
+
113
+ ```
114
+ freeagent-mcp/
115
+ ├── src/
116
+ │ ├── index.ts # Entry point, server setup
117
+ │ ├── client.ts # FreeAgent API HTTP client
118
+ │ ├── utils.ts # Shared utilities (responses, logging)
119
+ │ ├── client.test.ts # Client tests
120
+ │ ├── utils.test.ts # Utils tests
121
+ │ └── tools/
122
+ │ ├── company.ts # Company info tools (3)
123
+ │ ├── users.ts # User management tools (6)
124
+ │ ├── contacts.ts # Contact CRUD tools (5)
125
+ │ ├── projects.ts # Project management tools (5)
126
+ │ ├── tasks.ts # Task management tools (5)
127
+ │ ├── timeslips.ts # Time tracking tools (7)
128
+ │ ├── invoices.ts # Invoice tools (9)
129
+ │ ├── estimates.ts # Estimate tools (7)
130
+ │ ├── bills.ts # Bill management tools (5)
131
+ │ ├── credit-notes.ts # Credit note tools (5)
132
+ │ ├── expenses.ts # Expense tracking tools (5)
133
+ │ ├── banking.ts # Banking tools (7)
134
+ │ ├── categories.ts # Category tools (2)
135
+ │ ├── accounting.ts # Accounting report tools (5)
136
+ │ └── tools.test.ts # Tool handler tests
137
+ ├── package.json
138
+ ├── tsconfig.json
139
+ └── smithery.yaml
140
+ ```
141
+
142
+ ## Tools Reference
143
+
144
+ ### Company (3 tools)
145
+
146
+ | Tool | Description | API Endpoint |
147
+ |------|-------------|-------------|
148
+ | `freeagent_get_company` | Get company information | `GET /company` |
149
+ | `freeagent_list_business_categories` | List business categories | `GET /company/business_categories` |
150
+ | `freeagent_get_tax_timeline` | Get tax timeline | `GET /company/tax_timeline` |
151
+
152
+ ### Users (6 tools)
153
+
154
+ | Tool | Description | API Endpoint |
155
+ |------|-------------|-------------|
156
+ | `freeagent_list_users` | List users with optional view filter | `GET /users` |
157
+ | `freeagent_get_user` | Get a specific user | `GET /users/:id` |
158
+ | `freeagent_get_current_user` | Get the authenticated user | `GET /users/me` |
159
+ | `freeagent_create_user` | Create a new user | `POST /users` |
160
+ | `freeagent_update_user` | Update a user | `PUT /users/:id` |
161
+ | `freeagent_delete_user` | Delete a user | `DELETE /users/:id` |
162
+
163
+ ### Contacts (5 tools)
164
+
165
+ | Tool | Description | API Endpoint |
166
+ |------|-------------|-------------|
167
+ | `freeagent_list_contacts` | List contacts with filtering and sorting | `GET /contacts` |
168
+ | `freeagent_get_contact` | Get a specific contact | `GET /contacts/:id` |
169
+ | `freeagent_create_contact` | Create a new contact | `POST /contacts` |
170
+ | `freeagent_update_contact` | Update a contact | `PUT /contacts/:id` |
171
+ | `freeagent_delete_contact` | Delete a contact | `DELETE /contacts/:id` |
172
+
173
+ ### Projects (5 tools)
174
+
175
+ | Tool | Description | API Endpoint |
176
+ |------|-------------|-------------|
177
+ | `freeagent_list_projects` | List projects with optional view filter | `GET /projects` |
178
+ | `freeagent_get_project` | Get a specific project | `GET /projects/:id` |
179
+ | `freeagent_create_project` | Create a new project | `POST /projects` |
180
+ | `freeagent_update_project` | Update a project | `PUT /projects/:id` |
181
+ | `freeagent_delete_project` | Delete a project | `DELETE /projects/:id` |
182
+
183
+ ### Tasks (5 tools)
184
+
185
+ | Tool | Description | API Endpoint |
186
+ |------|-------------|-------------|
187
+ | `freeagent_list_tasks` | List tasks with optional filtering | `GET /tasks` |
188
+ | `freeagent_get_task` | Get a specific task | `GET /tasks/:id` |
189
+ | `freeagent_create_task` | Create a new task for a project | `POST /tasks` |
190
+ | `freeagent_update_task` | Update a task | `PUT /tasks/:id` |
191
+ | `freeagent_delete_task` | Delete a task | `DELETE /tasks/:id` |
192
+
193
+ ### Timeslips (7 tools)
194
+
195
+ | Tool | Description | API Endpoint |
196
+ |------|-------------|-------------|
197
+ | `freeagent_list_timeslips` | List timeslips with date and status filters | `GET /timeslips` |
198
+ | `freeagent_get_timeslip` | Get a specific timeslip | `GET /timeslips/:id` |
199
+ | `freeagent_create_timeslip` | Create a new timeslip | `POST /timeslips` |
200
+ | `freeagent_update_timeslip` | Update a timeslip | `PUT /timeslips/:id` |
201
+ | `freeagent_delete_timeslip` | Delete a timeslip | `DELETE /timeslips/:id` |
202
+ | `freeagent_start_timer` | Start a timer on a timeslip | `POST /timeslips/:id/timer` |
203
+ | `freeagent_stop_timer` | Stop a timer on a timeslip | `DELETE /timeslips/:id/timer` |
204
+
205
+ ### Invoices (9 tools)
206
+
207
+ | Tool | Description | API Endpoint |
208
+ |------|-------------|-------------|
209
+ | `freeagent_list_invoices` | List invoices with view and contact filters | `GET /invoices` |
210
+ | `freeagent_get_invoice` | Get a specific invoice | `GET /invoices/:id` |
211
+ | `freeagent_create_invoice` | Create a new invoice | `POST /invoices` |
212
+ | `freeagent_update_invoice` | Update an invoice | `PUT /invoices/:id` |
213
+ | `freeagent_delete_invoice` | Delete an invoice | `DELETE /invoices/:id` |
214
+ | `freeagent_mark_invoice_as_sent` | Mark invoice as sent | `PUT /invoices/:id/transitions/mark_as_sent` |
215
+ | `freeagent_mark_invoice_as_draft` | Mark invoice as draft | `PUT /invoices/:id/transitions/mark_as_draft` |
216
+ | `freeagent_mark_invoice_as_cancelled` | Cancel an invoice | `PUT /invoices/:id/transitions/mark_as_cancelled` |
217
+ | `freeagent_send_invoice_email` | Email an invoice | `POST /invoices/:id/send_email` |
218
+
219
+ ### Estimates (7 tools)
220
+
221
+ | Tool | Description | API Endpoint |
222
+ |------|-------------|-------------|
223
+ | `freeagent_list_estimates` | List estimates with filters | `GET /estimates` |
224
+ | `freeagent_get_estimate` | Get a specific estimate | `GET /estimates/:id` |
225
+ | `freeagent_create_estimate` | Create a new estimate | `POST /estimates` |
226
+ | `freeagent_update_estimate` | Update an estimate | `PUT /estimates/:id` |
227
+ | `freeagent_delete_estimate` | Delete an estimate | `DELETE /estimates/:id` |
228
+ | `freeagent_mark_estimate_as_sent` | Mark estimate as sent | `PUT /estimates/:id/transitions/mark_as_sent` |
229
+ | `freeagent_mark_estimate_as_approved` | Mark estimate as approved | `PUT /estimates/:id/transitions/mark_as_approved` |
230
+
231
+ ### Bills (5 tools)
232
+
233
+ | Tool | Description | API Endpoint |
234
+ |------|-------------|-------------|
235
+ | `freeagent_list_bills` | List bills with view and date filters | `GET /bills` |
236
+ | `freeagent_get_bill` | Get a specific bill | `GET /bills/:id` |
237
+ | `freeagent_create_bill` | Create a new bill | `POST /bills` |
238
+ | `freeagent_update_bill` | Update a bill | `PUT /bills/:id` |
239
+ | `freeagent_delete_bill` | Delete a bill | `DELETE /bills/:id` |
240
+
241
+ ### Credit Notes (5 tools)
242
+
243
+ | Tool | Description | API Endpoint |
244
+ |------|-------------|-------------|
245
+ | `freeagent_list_credit_notes` | List credit notes with filters | `GET /credit_notes` |
246
+ | `freeagent_get_credit_note` | Get a specific credit note | `GET /credit_notes/:id` |
247
+ | `freeagent_create_credit_note` | Create a new credit note | `POST /credit_notes` |
248
+ | `freeagent_update_credit_note` | Update a credit note | `PUT /credit_notes/:id` |
249
+ | `freeagent_delete_credit_note` | Delete a credit note | `DELETE /credit_notes/:id` |
250
+
251
+ ### Expenses (5 tools)
252
+
253
+ | Tool | Description | API Endpoint |
254
+ |------|-------------|-------------|
255
+ | `freeagent_list_expenses` | List expenses with date and project filters | `GET /expenses` |
256
+ | `freeagent_get_expense` | Get a specific expense | `GET /expenses/:id` |
257
+ | `freeagent_create_expense` | Create a new expense | `POST /expenses` |
258
+ | `freeagent_update_expense` | Update an expense | `PUT /expenses/:id` |
259
+ | `freeagent_delete_expense` | Delete an expense | `DELETE /expenses/:id` |
260
+
261
+ ### Banking (7 tools)
262
+
263
+ | Tool | Description | API Endpoint |
264
+ |------|-------------|-------------|
265
+ | `freeagent_list_bank_accounts` | List bank accounts | `GET /bank_accounts` |
266
+ | `freeagent_get_bank_account` | Get a specific bank account | `GET /bank_accounts/:id` |
267
+ | `freeagent_create_bank_account` | Create a new bank account | `POST /bank_accounts` |
268
+ | `freeagent_update_bank_account` | Update a bank account | `PUT /bank_accounts/:id` |
269
+ | `freeagent_delete_bank_account` | Delete a bank account | `DELETE /bank_accounts/:id` |
270
+ | `freeagent_list_bank_transactions` | List transactions for a bank account | `GET /bank_transactions` |
271
+ | `freeagent_get_bank_transaction` | Get a specific bank transaction | `GET /bank_transactions/:id` |
272
+
273
+ ### Categories (2 tools)
274
+
275
+ | Tool | Description | API Endpoint |
276
+ |------|-------------|-------------|
277
+ | `freeagent_list_categories` | List all accounting categories | `GET /categories` |
278
+ | `freeagent_get_category` | Get a specific category by nominal code | `GET /categories/:nominal_code` |
279
+
280
+ ### Accounting Reports (5 tools)
281
+
282
+ | Tool | Description | API Endpoint |
283
+ |------|-------------|-------------|
284
+ | `freeagent_get_profit_and_loss` | Get profit and loss summary | `GET /accounting/profit_and_loss/summary` |
285
+ | `freeagent_get_balance_sheet` | Get balance sheet | `GET /accounting/balance_sheet` |
286
+ | `freeagent_get_opening_balances` | Get opening balances | `GET /accounting/balance_sheet/opening_balances` |
287
+ | `freeagent_get_trial_balance` | Get trial balance summary | `GET /accounting/trial_balance/summary` |
288
+ | `freeagent_get_trial_balance_opening` | Get trial balance opening balances | `GET /accounting/trial_balance/summary/opening_balances` |
289
+
290
+ ## Example Prompts
291
+
292
+ - "Show me the company information from FreeAgent"
293
+ - "List all active contacts"
294
+ - "Create a new invoice for contact 12345 dated today with 30 day payment terms"
295
+ - "How much time did I log this week?"
296
+ - "Start a timer on timeslip 67890"
297
+ - "Show my profit and loss for the current year"
298
+ - "List all overdue invoices"
299
+ - "Create an expense for lunch at $25 under the entertainment category"
300
+ - "What's my current balance sheet?"
301
+ - "List all open bills from suppliers"
302
+
303
+ ## Development
304
+
305
+ ```bash
306
+ # Install dependencies
307
+ npm install
308
+
309
+ # Type check
310
+ npm run type-check
311
+
312
+ # Run tests
313
+ npm test
314
+
315
+ # Run tests in watch mode
316
+ npm run test:watch
317
+
318
+ # Build
319
+ npm run build
320
+
321
+ # Lint
322
+ npm run lint
323
+
324
+ # Format
325
+ npm run format
326
+ ```
327
+
328
+ ### Adding New Tools
329
+
330
+ 1. Create a new file in `src/tools/` (or add to an existing one)
331
+ 2. Follow the pattern: export a `registerXxxTools(server, client)` function
332
+ 3. Register each tool with `server.tool()` or `server.registerTool()`
333
+ 4. Always use `logToolCall()`, `jsonResponse()`, and `errorResponse()`
334
+ 5. Import and call the register function in `src/index.ts`
335
+ 6. Add tests in `src/tools/tools.test.ts`
336
+
337
+ ## Troubleshooting
338
+
339
+ **"Missing required environment variable: FREEAGENT_ACCESS_TOKEN"**
340
+ Set the `FREEAGENT_ACCESS_TOKEN` environment variable with a valid OAuth2 access token.
341
+
342
+ **401 Unauthorized errors**
343
+ Your access token may have expired. FreeAgent OAuth tokens expire - you'll need to refresh your token using the OAuth2 refresh flow.
344
+
345
+ **"FreeAgent API error (403)"**
346
+ Your token may not have the required permission level. Check that your FreeAgent app has the appropriate access scopes.
347
+
348
+ **Sandbox vs Production**
349
+ By default the server connects to the FreeAgent sandbox. Set `FREEAGENT_BASE_URL=https://api.freeagent.com/v2` for production.
350
+
351
+ **Tool not found**
352
+ Ensure you're using the correct tool name with the `freeagent_` prefix (e.g., `freeagent_list_invoices`, not `list_invoices`).
353
+
354
+ **Empty responses**
355
+ Some endpoints return empty responses for successful DELETE operations. This is expected behavior.
356
+
357
+ ## License
358
+
359
+ MIT
@@ -0,0 +1,18 @@
1
+ export declare class FreeAgentApiError extends Error {
2
+ readonly status: number;
3
+ readonly errorCode: string;
4
+ constructor(status: number, errorCode: string, message: string);
5
+ }
6
+ export declare class FreeAgentClient {
7
+ private accessToken;
8
+ private baseUrl;
9
+ constructor(accessToken: string, baseUrl?: string);
10
+ get<T = unknown>(path: string, params?: Record<string, string>): Promise<T>;
11
+ postForm<T = unknown>(path: string, body?: Record<string, string>): Promise<T>;
12
+ postJson<T = unknown>(path: string, body: unknown): Promise<T>;
13
+ putForm<T = unknown>(path: string, body?: Record<string, string>): Promise<T>;
14
+ putJson<T = unknown>(path: string, body: unknown): Promise<T>;
15
+ patchJson<T = unknown>(path: string, body: unknown): Promise<T>;
16
+ deleteReq<T = unknown>(path: string, params?: Record<string, string>): Promise<T>;
17
+ private request;
18
+ }
@@ -0,0 +1,93 @@
1
+ const DEFAULT_BASE_URL = "https://api.sandbox.freeagent.com/v2";
2
+ export class FreeAgentApiError extends Error {
3
+ status;
4
+ errorCode;
5
+ constructor(status, errorCode, message) {
6
+ super(`FreeAgent API error (${status}): ${errorCode} - ${message}`);
7
+ this.name = "FreeAgentApiError";
8
+ this.status = status;
9
+ this.errorCode = errorCode;
10
+ }
11
+ }
12
+ function parseApiError(status, body) {
13
+ try {
14
+ const parsed = JSON.parse(body);
15
+ const code = parsed?.error ?? parsed?.code ?? "unknown";
16
+ const message = parsed?.message ??
17
+ parsed?.error_description ??
18
+ parsed?.errors?.error?.message ??
19
+ `HTTP ${status}`;
20
+ return new FreeAgentApiError(status, code, message);
21
+ }
22
+ catch {
23
+ return new FreeAgentApiError(status, "unknown", `HTTP ${status} error`);
24
+ }
25
+ }
26
+ function encodeFormBody(data) {
27
+ return new URLSearchParams(data).toString();
28
+ }
29
+ export class FreeAgentClient {
30
+ accessToken;
31
+ baseUrl;
32
+ constructor(accessToken, baseUrl) {
33
+ this.accessToken = accessToken;
34
+ this.baseUrl = baseUrl || DEFAULT_BASE_URL;
35
+ }
36
+ async get(path, params) {
37
+ return this.request("GET", path, undefined, undefined, params);
38
+ }
39
+ async postForm(path, body) {
40
+ return this.request("POST", path, body, "form");
41
+ }
42
+ async postJson(path, body) {
43
+ return this.request("POST", path, body, "json");
44
+ }
45
+ async putForm(path, body) {
46
+ return this.request("PUT", path, body, "form");
47
+ }
48
+ async putJson(path, body) {
49
+ return this.request("PUT", path, body, "json");
50
+ }
51
+ async patchJson(path, body) {
52
+ return this.request("PATCH", path, body, "json");
53
+ }
54
+ async deleteReq(path, params) {
55
+ return this.request("DELETE", path, undefined, undefined, params);
56
+ }
57
+ async request(method, path, body, bodyType, params) {
58
+ const url = new URL(path, this.baseUrl);
59
+ if (params) {
60
+ for (const [k, v] of Object.entries(params)) {
61
+ url.searchParams.set(k, v);
62
+ }
63
+ }
64
+ const headers = {
65
+ Authorization: `Bearer ${this.accessToken}`,
66
+ Accept: "application/json",
67
+ "User-Agent": "freeagent-mcp/1.0.0",
68
+ };
69
+ let encodedBody;
70
+ if (body && bodyType === "json") {
71
+ headers["Content-Type"] = "application/json";
72
+ encodedBody = JSON.stringify(body);
73
+ }
74
+ else if (body && bodyType === "form") {
75
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
76
+ encodedBody = encodeFormBody(body);
77
+ }
78
+ const response = await fetch(url.toString(), {
79
+ method,
80
+ headers,
81
+ body: encodedBody,
82
+ });
83
+ if (!response.ok) {
84
+ const errorBody = await response.text();
85
+ throw parseApiError(response.status, errorBody);
86
+ }
87
+ const text = await response.text();
88
+ if (!text)
89
+ return {};
90
+ return JSON.parse(text);
91
+ }
92
+ }
93
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { FreeAgentClient } from "./client.js";
5
+ import { registerCompanyTools } from "./tools/company.js";
6
+ import { registerUserTools } from "./tools/users.js";
7
+ import { registerContactTools } from "./tools/contacts.js";
8
+ import { registerProjectTools } from "./tools/projects.js";
9
+ import { registerTaskTools } from "./tools/tasks.js";
10
+ import { registerTimeslipTools } from "./tools/timeslips.js";
11
+ import { registerInvoiceTools } from "./tools/invoices.js";
12
+ import { registerEstimateTools } from "./tools/estimates.js";
13
+ import { registerBillTools } from "./tools/bills.js";
14
+ import { registerCreditNoteTools } from "./tools/credit-notes.js";
15
+ import { registerExpenseTools } from "./tools/expenses.js";
16
+ import { registerBankingTools } from "./tools/banking.js";
17
+ import { registerCategoryTools } from "./tools/categories.js";
18
+ import { registerAccountingTools } from "./tools/accounting.js";
19
+ const FREEAGENT_ACCESS_TOKEN = process.env.FREEAGENT_ACCESS_TOKEN;
20
+ const FREEAGENT_BASE_URL = process.env.FREEAGENT_BASE_URL;
21
+ if (!FREEAGENT_ACCESS_TOKEN) {
22
+ console.error("Missing required environment variable: FREEAGENT_ACCESS_TOKEN");
23
+ process.exit(1);
24
+ }
25
+ const client = new FreeAgentClient(FREEAGENT_ACCESS_TOKEN, FREEAGENT_BASE_URL);
26
+ const server = new McpServer({
27
+ name: "freeagent-mcp",
28
+ version: "1.0.0",
29
+ });
30
+ registerCompanyTools(server, client);
31
+ registerUserTools(server, client);
32
+ registerContactTools(server, client);
33
+ registerProjectTools(server, client);
34
+ registerTaskTools(server, client);
35
+ registerTimeslipTools(server, client);
36
+ registerInvoiceTools(server, client);
37
+ registerEstimateTools(server, client);
38
+ registerBillTools(server, client);
39
+ registerCreditNoteTools(server, client);
40
+ registerExpenseTools(server, client);
41
+ registerBankingTools(server, client);
42
+ registerCategoryTools(server, client);
43
+ registerAccountingTools(server, client);
44
+ async function main() {
45
+ const transport = new StdioServerTransport();
46
+ await server.connect(transport);
47
+ console.error("FreeAgent MCP Server running on stdio");
48
+ }
49
+ main().catch((error) => {
50
+ console.error("Fatal error:", error);
51
+ process.exit(1);
52
+ });
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,sBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;AAClE,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAE1D,IAAI,CAAC,sBAAsB,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;IAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;AAE/E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExC,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;AACzD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { FreeAgentClient } from "../client.js";
3
+ export declare function registerAccountingTools(server: McpServer, client: FreeAgentClient): void;
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ import { jsonResponse, errorResponse, logToolCall, buildParams } from "../utils.js";
3
+ export function registerAccountingTools(server, client) {
4
+ server.tool("freeagent_get_profit_and_loss", "Get the profit and loss summary from FreeAgent with optional date range filtering", {
5
+ from_date: z
6
+ .string()
7
+ .optional()
8
+ .describe("Start date for the P&L report in YYYY-MM-DD format"),
9
+ to_date: z
10
+ .string()
11
+ .optional()
12
+ .describe("End date for the P&L report in YYYY-MM-DD format"),
13
+ }, async ({ from_date, to_date }) => {
14
+ logToolCall("freeagent_get_profit_and_loss", { from_date, to_date });
15
+ try {
16
+ const params = buildParams({ from_date, to_date });
17
+ const data = await client.get("/accounting/profit_and_loss/summary", params);
18
+ return jsonResponse(data);
19
+ }
20
+ catch (error) {
21
+ return errorResponse(error);
22
+ }
23
+ });
24
+ server.tool("freeagent_get_balance_sheet", "Get the balance sheet from FreeAgent, optionally as at a specific date", {
25
+ as_at_date: z
26
+ .string()
27
+ .optional()
28
+ .describe("Date to retrieve the balance sheet as at, in YYYY-MM-DD format"),
29
+ }, async ({ as_at_date }) => {
30
+ logToolCall("freeagent_get_balance_sheet", { as_at_date });
31
+ try {
32
+ const params = buildParams({ as_at_date });
33
+ const data = await client.get("/accounting/balance_sheet", params);
34
+ return jsonResponse(data);
35
+ }
36
+ catch (error) {
37
+ return errorResponse(error);
38
+ }
39
+ });
40
+ server.tool("freeagent_get_opening_balances", "Get the opening balances from the FreeAgent balance sheet", {}, async () => {
41
+ logToolCall("freeagent_get_opening_balances");
42
+ try {
43
+ const data = await client.get("/accounting/balance_sheet/opening_balances");
44
+ return jsonResponse(data);
45
+ }
46
+ catch (error) {
47
+ return errorResponse(error);
48
+ }
49
+ });
50
+ server.tool("freeagent_get_trial_balance", "Get the trial balance summary from FreeAgent with optional date range filtering", {
51
+ from_date: z
52
+ .string()
53
+ .optional()
54
+ .describe("Start date for the trial balance in YYYY-MM-DD format"),
55
+ to_date: z
56
+ .string()
57
+ .optional()
58
+ .describe("End date for the trial balance in YYYY-MM-DD format"),
59
+ }, async ({ from_date, to_date }) => {
60
+ logToolCall("freeagent_get_trial_balance", { from_date, to_date });
61
+ try {
62
+ const params = buildParams({ from_date, to_date });
63
+ const data = await client.get("/accounting/trial_balance/summary", params);
64
+ return jsonResponse(data);
65
+ }
66
+ catch (error) {
67
+ return errorResponse(error);
68
+ }
69
+ });
70
+ server.tool("freeagent_get_trial_balance_opening", "Get the trial balance opening balances from FreeAgent", {}, async () => {
71
+ logToolCall("freeagent_get_trial_balance_opening");
72
+ try {
73
+ const data = await client.get("/accounting/trial_balance/summary/opening_balances");
74
+ return jsonResponse(data);
75
+ }
76
+ catch (error) {
77
+ return errorResponse(error);
78
+ }
79
+ });
80
+ }
81
+ //# sourceMappingURL=accounting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounting.js","sourceRoot":"","sources":["../../src/tools/accounting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { FreeAgentClient } from "../client.js";
3
+ export declare function registerBankingTools(server: McpServer, client: FreeAgentClient): void;