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.
- package/LICENSE +21 -0
- package/README.md +359 -0
- package/build/client.d.ts +18 -0
- package/build/client.js +93 -0
- package/build/client.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +53 -0
- package/build/index.js.map +1 -0
- package/build/tools/accounting.d.ts +3 -0
- package/build/tools/accounting.js +81 -0
- package/build/tools/accounting.js.map +1 -0
- package/build/tools/banking.d.ts +3 -0
- package/build/tools/banking.js +151 -0
- package/build/tools/banking.js.map +1 -0
- package/build/tools/bills.d.ts +3 -0
- package/build/tools/bills.js +127 -0
- package/build/tools/bills.js.map +1 -0
- package/build/tools/categories.d.ts +3 -0
- package/build/tools/categories.js +33 -0
- package/build/tools/categories.js.map +1 -0
- package/build/tools/company.d.ts +3 -0
- package/build/tools/company.js +46 -0
- package/build/tools/company.js.map +1 -0
- package/build/tools/contacts.d.ts +3 -0
- package/build/tools/contacts.js +171 -0
- package/build/tools/contacts.js.map +1 -0
- package/build/tools/credit-notes.d.ts +3 -0
- package/build/tools/credit-notes.js +139 -0
- package/build/tools/credit-notes.js.map +1 -0
- package/build/tools/estimates.d.ts +3 -0
- package/build/tools/estimates.js +150 -0
- package/build/tools/estimates.js.map +1 -0
- package/build/tools/expenses.d.ts +3 -0
- package/build/tools/expenses.js +155 -0
- package/build/tools/expenses.js.map +1 -0
- package/build/tools/invoices.d.ts +3 -0
- package/build/tools/invoices.js +166 -0
- package/build/tools/invoices.js.map +1 -0
- package/build/tools/projects.d.ts +3 -0
- package/build/tools/projects.js +107 -0
- package/build/tools/projects.js.map +1 -0
- package/build/tools/tasks.d.ts +3 -0
- package/build/tools/tasks.js +159 -0
- package/build/tools/tasks.js.map +1 -0
- package/build/tools/timeslips.d.ts +3 -0
- package/build/tools/timeslips.js +194 -0
- package/build/tools/timeslips.js.map +1 -0
- package/build/tools/users.d.ts +3 -0
- package/build/tools/users.js +136 -0
- package/build/tools/users.js.map +1 -0
- package/build/utils.d.ts +18 -0
- package/build/utils.js +37 -0
- package/build/utils.js.map +1 -0
- 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
|
+
[](https://www.npmjs.com/package/freeagent-mcp)
|
|
4
|
+
[](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
|
+
}
|
package/build/client.js
ADDED
|
@@ -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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"}
|
package/build/index.d.ts
ADDED
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":"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"}
|
|
@@ -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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"}
|