invoicesnest-mcp 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/README.md +291 -0
- package/build/api/business.api.js +15 -0
- package/build/api/client.api.js +9 -0
- package/build/api/client.js +42 -0
- package/build/api/dashboard.api.js +6 -0
- package/build/api/invoice.api.js +40 -0
- package/build/auth.js +10 -0
- package/build/config.js +11 -0
- package/build/index.js +12 -0
- package/build/schemas/client.schema.js +10 -0
- package/build/schemas/dashboard.schema.js +13 -0
- package/build/schemas/invoice.schema.js +43 -0
- package/build/server.js +235 -0
- package/build/tools/createClient.js +63 -0
- package/build/tools/createInvoice.js +165 -0
- package/build/tools/create_client.js +80 -0
- package/build/tools/create_invoice.js +145 -0
- package/build/tools/dashboard.js +46 -0
- package/build/tools/deleteInvoice.js +54 -0
- package/build/tools/delete_invoice.js +41 -0
- package/build/tools/duplicate_invoice.js +85 -0
- package/build/tools/explain_invoice.js +78 -0
- package/build/tools/generate_business_summary.js +94 -0
- package/build/tools/getBusinessContext.js +34 -0
- package/build/tools/getInvoice.js +55 -0
- package/build/tools/get_business_context.js +27 -0
- package/build/tools/get_invoice.js +41 -0
- package/build/tools/health_check.js +37 -0
- package/build/tools/list_capabilities.js +43 -0
- package/build/tools/payment_status.js +48 -0
- package/build/tools/recommend_payment_followup.js +49 -0
- package/build/tools/recurring.js +108 -0
- package/build/tools/recurring_invoice.js +100 -0
- package/build/tools/revenue.js +46 -0
- package/build/tools/searchClients.js +44 -0
- package/build/tools/search_clients.js +34 -0
- package/build/tools/search_everything.js +71 -0
- package/build/tools/search_invoices.js +41 -0
- package/build/tools/sendInvoice.js +54 -0
- package/build/tools/send_invoice.js +43 -0
- package/build/tools/updateInvoice.js +89 -0
- package/build/tools/update_invoice.js +74 -0
- package/build/tools/who_am_i.js +40 -0
- package/build/types/index.js +1 -0
- package/build/utils/currency.js +16 -0
- package/build/utils/dates.js +15 -0
- package/build/utils/errors.js +32 -0
- package/build/utils/formatter.js +8 -0
- package/build/utils/logger.js +17 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# InvoicesNest MCP Server
|
|
2
|
+
|
|
3
|
+
    
|
|
4
|
+
|
|
5
|
+
> **Version**: `1.1.0` | **Status**: `Stable` | **Transport**: `stdio` | **API Compatibility**: `InvoicesNest Backend >= v1.0`
|
|
6
|
+
|
|
7
|
+
Official Model Context Protocol (MCP) server for InvoicesNest.
|
|
8
|
+
|
|
9
|
+
Connect AI assistants such as Claude Desktop, Cursor, VS Code Copilot, and future MCP-compatible clients directly to your InvoicesNest workspace. The server exposes AI-native tools for invoices, clients, recurring billing, analytics, and business resources while keeping all business logic inside the InvoicesNest backend.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Architecture Diagram
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
[ Claude / Cursor / VS Code ]
|
|
17
|
+
│
|
|
18
|
+
│ Model Context Protocol (stdio)
|
|
19
|
+
▼
|
|
20
|
+
[ InvoicesNest MCP Server ]
|
|
21
|
+
│
|
|
22
|
+
│ REST API calls (bypass tunnel headers)
|
|
23
|
+
▼
|
|
24
|
+
[ InvoicesNest API Server ]
|
|
25
|
+
│
|
|
26
|
+
│ prisma
|
|
27
|
+
▼
|
|
28
|
+
[ Database ]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Design Philosophy
|
|
34
|
+
|
|
35
|
+
The MCP server is intentionally thin. It does not implement business rules or calculations directly. Instead, it exposes AI-friendly interfaces and validates request signatures. The InvoicesNest Backend remains the single source of truth. This architecture keeps AI clients lightweight while ensuring consistent business behavior across Web, Mobile, API, and MCP integrations.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Compatible Clients
|
|
40
|
+
|
|
41
|
+
* **Claude Desktop**
|
|
42
|
+
* **Cursor IDE**
|
|
43
|
+
* **VS Code** (using MCP clients)
|
|
44
|
+
* **Continue.dev**
|
|
45
|
+
* **Cline**
|
|
46
|
+
* **Roo Code**
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Installation & Build
|
|
51
|
+
|
|
52
|
+
Ensure you have Node.js (v18+) and npm installed.
|
|
53
|
+
|
|
54
|
+
1. Navigate into the `invoice-mcp` folder:
|
|
55
|
+
```bash
|
|
56
|
+
cd invoice-mcp
|
|
57
|
+
```
|
|
58
|
+
2. Install dependencies:
|
|
59
|
+
```bash
|
|
60
|
+
npm install
|
|
61
|
+
```
|
|
62
|
+
3. Build the TypeScript files:
|
|
63
|
+
```bash
|
|
64
|
+
npm run build
|
|
65
|
+
```
|
|
66
|
+
4. Start the MCP server locally:
|
|
67
|
+
```bash
|
|
68
|
+
npm start
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Project Tree
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
invoice-mcp/
|
|
77
|
+
├── build/ # Compiled JavaScript output
|
|
78
|
+
├── src/
|
|
79
|
+
│ ├── api/ # Decoupled REST API wrappers
|
|
80
|
+
│ │ ├── business.api.ts
|
|
81
|
+
│ │ ├── client.api.ts
|
|
82
|
+
│ │ ├── dashboard.api.ts
|
|
83
|
+
│ │ └── invoice.api.ts
|
|
84
|
+
│ ├── schemas/ # Zod parameter validation schemas
|
|
85
|
+
│ │ ├── client.schema.ts
|
|
86
|
+
│ │ └── invoice.schema.ts
|
|
87
|
+
│ ├── tools/ # 21 MCP Tool handlers
|
|
88
|
+
│ ├── types/ # Shared TypeScript typings
|
|
89
|
+
│ ├── utils/ # Loggers, error formatters, and helpers
|
|
90
|
+
│ ├── config.ts # Central environment constants
|
|
91
|
+
│ ├── index.ts # Bootstraps Stdio server transport
|
|
92
|
+
│ ├── server.ts # Main MCP server routes registration
|
|
93
|
+
│ ├── prompts/ # Reserved for future MCP Prompt handlers
|
|
94
|
+
│ └── resources/ # Reserved for future MCP Resource handlers
|
|
95
|
+
├── package.json
|
|
96
|
+
├── tsconfig.json
|
|
97
|
+
└── README.md
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Environment Variables
|
|
103
|
+
|
|
104
|
+
| Variable | Requirement | Default | Description |
|
|
105
|
+
| :--- | :--- | :--- | :--- |
|
|
106
|
+
| `INVOICESNEST_ACCESS_TOKEN` | **Required** | — | Your JWT account access token from settings dashboard. |
|
|
107
|
+
| `INVOICESNEST_BACKEND_URL` | **Required** | — | Base URL of your InvoicesNest API backend (e.g. `https://api.invoicesnest.com`). |
|
|
108
|
+
| `LOG_LEVEL` | Optional | `info` | Logging verbosity (`info`, `error`, `debug`). |
|
|
109
|
+
| `REQUEST_TIMEOUT` | Optional | `30000` | Backend API request timeout in milliseconds. |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Exposed MCP Resources
|
|
114
|
+
|
|
115
|
+
The MCP Server exposes the following read-only context resources to your LLMs:
|
|
116
|
+
|
|
117
|
+
| Resource URI | MIME Type | Description |
|
|
118
|
+
| :--- | :--- | :--- |
|
|
119
|
+
| `invoicesnest://business/profile` | `application/json` | Active business profiles details (Name, address, email). |
|
|
120
|
+
| `invoicesnest://business/invoice-template` | `application/json` | Active template configurations. |
|
|
121
|
+
| `invoicesnest://business/payment-methods` | `application/json` | Allowed payment options. |
|
|
122
|
+
| `invoicesnest://business/branding` | `application/json` | Logo references and colors codes. |
|
|
123
|
+
| `invoicesnest://business/products` | `application/json` | Product inventory lists. |
|
|
124
|
+
| `invoicesnest://business/services` | `application/json` | Business services catalog. |
|
|
125
|
+
| `invoicesnest://business/tax-rules` | `application/json` | Default tax configurations. |
|
|
126
|
+
| `invoicesnest://business/payment-terms` | `text/plain` | Standard deadline payment guidelines. |
|
|
127
|
+
| `invoicesnest://business/currencies` | `application/json` | Supported currency codes and symbols. |
|
|
128
|
+
| `invoicesnest://business/company-settings` | `application/json` | Timezone metadata records. |
|
|
129
|
+
| `invoicesnest://business/number-format` | `text/plain` | Invoice serial numbering prefixes. |
|
|
130
|
+
| `invoicesnest://business/date-format` | `text/plain` | Selected date representation layout. |
|
|
131
|
+
| `invoicesnest://business/email-template` | `text/html` | HTML template layouts for client deliveries. |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Exposed MCP Tools (21 total)
|
|
136
|
+
|
|
137
|
+
| # | Tool Name | Parameters | Description |
|
|
138
|
+
| :- | :--- | :--- | :--- |
|
|
139
|
+
| 1 | `health_check` | None | Diagnoses access token status and API connection health. |
|
|
140
|
+
| 2 | `who_am_i` | None | Returns active user session, workspaces list, and permission levels. |
|
|
141
|
+
| 3 | `list_capabilities` | None | Outlines active API capabilities and supported modules. |
|
|
142
|
+
| 4 | `get_business_context` | None | Retrieves active merchant profile, currency, and invoice prefix. |
|
|
143
|
+
| 5 | `search_everything` | `query` | Unified parallel search across Invoices, Clients, and Recurring profiles. |
|
|
144
|
+
| 6 | `explain_invoice` | `id` or `invoiceNumber` | Breaks down tax, discount, subtotal, grand total, and overdue status. |
|
|
145
|
+
| 7 | `recommend_payment_followup` | None | Returns overdue age data for LLM to formulate custom payment reminders. |
|
|
146
|
+
| 8 | `generate_business_summary` | None | Aggregates Revenue, Outstanding, MRR, Top Client, Collection Rate. |
|
|
147
|
+
| 9 | `create_invoice` | client details, items | Generates a new mathematically-validated invoice. |
|
|
148
|
+
| 10 | `get_invoice` | `id` or `invoiceNumber` | Reads complete invoice JSON metadata. |
|
|
149
|
+
| 11 | `search_invoices` | `query` | Searches invoices by number, client name, or email. |
|
|
150
|
+
| 12 | `update_invoice` | `id`, update fields | Performs partial field updates on an existing invoice. |
|
|
151
|
+
| 13 | `delete_invoice` | `id` or `invoiceNumber` | Deletes an invoice (subject to backend deletion policy). |
|
|
152
|
+
| 14 | `duplicate_invoice` | `id`, `newInvoiceNumber` | Clones an invoice and assigns the next serial number. |
|
|
153
|
+
| 15 | `create_client` | name, email, phone, address | Registers a new client CRM contact. |
|
|
154
|
+
| 16 | `search_clients` | `query` | Searches saved clients by name or email. |
|
|
155
|
+
| 17 | `recurring_invoice` | `action`, profile data | Manages recurring billing profiles (list, create, pause, resume, skip, delete). |
|
|
156
|
+
| 18 | `payment_status` | `status` | Filters invoices by PAID, PENDING, or OVERDUE. |
|
|
157
|
+
| 19 | `get_revenue_stats` | None | Calculates collected revenue and outstanding cashflow per currency. |
|
|
158
|
+
| 20 | `get_dashboard_summary` | None | Returns invoice count distributions across all statuses. |
|
|
159
|
+
| 21 | `send_invoice` | `id` or `invoiceNumber` | Emails PDF invoice directly to the client's address. |
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Developer Tool Schema Examples
|
|
164
|
+
|
|
165
|
+
### 1. `create_invoice` Input Example
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"clientName": "ABC Corp Ltd",
|
|
169
|
+
"clientEmail": "billing@abccorp.com",
|
|
170
|
+
"items": [
|
|
171
|
+
{
|
|
172
|
+
"description": "API Integration Consulting",
|
|
173
|
+
"quantity": 10,
|
|
174
|
+
"rate": 150
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"taxRate": 15,
|
|
178
|
+
"discountRate": 5,
|
|
179
|
+
"sendEmailToClient": true
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 2. `recurring_invoice` Input Example
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"action": "create",
|
|
187
|
+
"createData": {
|
|
188
|
+
"clientName": "John Doe LLC",
|
|
189
|
+
"clientEmail": "john@doe.com",
|
|
190
|
+
"frequency": "MONTHLY",
|
|
191
|
+
"items": [
|
|
192
|
+
{
|
|
193
|
+
"description": "Monthly Retainer Services",
|
|
194
|
+
"quantity": 1,
|
|
195
|
+
"rate": 2000
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Interactive AI Prompt Library (55+ Real-World Prompt Scenarios)
|
|
205
|
+
|
|
206
|
+
### Invoicing & Drafts
|
|
207
|
+
1. *Create an invoice for ABC Ltd worth $450 with description "Consulting Work".*
|
|
208
|
+
2. *Draft invoice for Ali Khan: 2 hours of Web Development at $100/hr, tax rate 15%.*
|
|
209
|
+
3. *Duplicate invoice INV-0012 but set the status to draft.*
|
|
210
|
+
4. *Update the due date of invoice INV-1002 to next Friday.*
|
|
211
|
+
5. *Delete invoice with serial number INV-0056.*
|
|
212
|
+
6. *Set the shipping cost of invoice INV-0089 to $25.*
|
|
213
|
+
7. *Apply a 10% discount on invoice INV-0023 and recalculate.*
|
|
214
|
+
8. *Add 3 items to invoice INV-1120: Item A for $100, Item B for $200, Item C for $300.*
|
|
215
|
+
9. *Find my recent draft invoices.*
|
|
216
|
+
10. *Get the exact JSON details of invoice INV-0011.*
|
|
217
|
+
|
|
218
|
+
### Client Management & CRM
|
|
219
|
+
11. *Create a client Ali Khan, email ali@example.com, address 123 Street Lahore.*
|
|
220
|
+
12. *Search for a client named Smith.*
|
|
221
|
+
13. *Find the contact details of customer XYZ Corp.*
|
|
222
|
+
14. *Change the email address of client John Doe to john@newmail.com.*
|
|
223
|
+
15. *Add phone number +92-300-1234567 to client Ali Ahmed.*
|
|
224
|
+
16. *Register a new business client: name "Future Tech LLC", email "info@futuretech.co".*
|
|
225
|
+
17. *Does client Ali already exist? Search the database.*
|
|
226
|
+
18. *List all saved clients in my CRM.*
|
|
227
|
+
19. *Update client address for 'Zubair Butt' to 'Main Boulevard Gulberg'.*
|
|
228
|
+
20. *Find the client ID of 'Usman Ghani'.*
|
|
229
|
+
|
|
230
|
+
### Payments & Overdue Tracking
|
|
231
|
+
21. *Show unpaid invoices.*
|
|
232
|
+
22. *List all overdue invoices.*
|
|
233
|
+
23. *Which invoices are still pending payment?*
|
|
234
|
+
24. *How many invoices were paid in USD?*
|
|
235
|
+
25. *Check if invoice INV-0005 has been paid yet.*
|
|
236
|
+
26. *List all PAID invoices.*
|
|
237
|
+
27. *Recommend payment reminders based on currently overdue invoices.*
|
|
238
|
+
28. *Draft a polite email to overdue client John Doe.*
|
|
239
|
+
29. *Find all invoices with outstanding amount higher than $1000.*
|
|
240
|
+
30. *List overdue invoices delayed by more than 30 days.*
|
|
241
|
+
|
|
242
|
+
### Business Reports & Summaries
|
|
243
|
+
31. *How is my business doing? Give me a full business summary.*
|
|
244
|
+
32. *What is my collection rate this month?*
|
|
245
|
+
33. *Calculate my total collected revenue and outstanding cashflow.*
|
|
246
|
+
34. *Who is my top-paying client by cumulative paid totals?*
|
|
247
|
+
35. *Who is my worst payer client in terms of overdue balances?*
|
|
248
|
+
36. *What is my average invoice value?*
|
|
249
|
+
37. *Estimate my Monthly Recurring Revenue (MRR) based on active profiles.*
|
|
250
|
+
38. *Tell me how much revenue is pending in EUR.*
|
|
251
|
+
39. *Explain invoice INV-1020: detail the tax portion and discount value.*
|
|
252
|
+
40. *Summarize active invoice statistics.*
|
|
253
|
+
|
|
254
|
+
### Recurring Invoices
|
|
255
|
+
41. *List all active recurring billing profiles.*
|
|
256
|
+
42. *Pause the recurring invoice for client Ali Khan.*
|
|
257
|
+
43. *Resume the recurring profile with ID active-recur-id.*
|
|
258
|
+
44. *Skip the next scheduled run for recurring invoice recurring-uuid-here.*
|
|
259
|
+
45. *Trigger an immediate run of recurring invoice profile rec_9982.*
|
|
260
|
+
46. *Delete the recurring billing template for Client John.*
|
|
261
|
+
47. *Create a monthly recurring invoice for Client Zubair for $500, starting today.*
|
|
262
|
+
48. *Show all paused recurring profiles.*
|
|
263
|
+
49. *How much recurring revenue do we get from Client ABC LLC?*
|
|
264
|
+
50. *What is the billing frequency of recurring profile rec-1020?*
|
|
265
|
+
|
|
266
|
+
### Debugging & System Context
|
|
267
|
+
51. *Run an MCP connection health check.*
|
|
268
|
+
52. *Who am I logged in as? Show my workspace and permissions.*
|
|
269
|
+
53. *What are the capabilities of the InvoicesNest API?*
|
|
270
|
+
54. *Check if my JWT access token is valid.*
|
|
271
|
+
55. *What is the default currency of my business context?*
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Public Release & Security Roadmap (v1.2)
|
|
276
|
+
|
|
277
|
+
For public directory listing and enterprise distribution, the authentication model will transition from JWT session cookies to:
|
|
278
|
+
1. **Scoped MCP API Keys:** Dynamic creation of token prefix `inv_mcp_...` restricted to read-only or read-write permissions (e.g. `invoices:read`, `clients:write`).
|
|
279
|
+
2. **OAuth2 Authorization Code Flow:** Enable direct browser-based oauth handshakes for external AI clients (ChatGPT GPTs store, Claude Workspaces) without manual credential mapping.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
Proprietary — Copyright © InvoicesNest. All rights reserved.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Changelog
|
|
290
|
+
|
|
291
|
+
See [CHANGELOG.md](./CHANGELOG.md) for full release history.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { callBackendApi } from "./client.js";
|
|
2
|
+
let cachedMetadata = null;
|
|
3
|
+
let cacheExpiry = 0;
|
|
4
|
+
const CACHE_TTL_MS = 10000; // 10 seconds cache TTL
|
|
5
|
+
export const BusinessApi = {
|
|
6
|
+
async getMetadata(forceRefresh = false) {
|
|
7
|
+
const now = Date.now();
|
|
8
|
+
if (!forceRefresh && cachedMetadata && now < cacheExpiry) {
|
|
9
|
+
return cachedMetadata;
|
|
10
|
+
}
|
|
11
|
+
cachedMetadata = await callBackendApi("/api/v1/invoices/metadata", "GET");
|
|
12
|
+
cacheExpiry = now + CACHE_TTL_MS;
|
|
13
|
+
return cachedMetadata;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CONFIG } from "../config.js";
|
|
2
|
+
import { Logger } from "../utils/logger.js";
|
|
3
|
+
export async function callBackendApi(endpoint, method = "GET", body) {
|
|
4
|
+
const startTime = Date.now();
|
|
5
|
+
const token = CONFIG.ACCESS_TOKEN;
|
|
6
|
+
const backendUrl = CONFIG.BACKEND_URL;
|
|
7
|
+
const headers = {
|
|
8
|
+
"Authorization": `Bearer ${token}`,
|
|
9
|
+
"Content-Type": "application/json",
|
|
10
|
+
"bypass-tunnel-reminder": "true",
|
|
11
|
+
"ngrok-skip-browser-warning": "true"
|
|
12
|
+
};
|
|
13
|
+
const url = `${backendUrl.replace(/\/$/, "")}${endpoint}`;
|
|
14
|
+
Logger.info(`Initiating backend request: [${method}] ${url}`, body);
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetch(url, {
|
|
17
|
+
method,
|
|
18
|
+
headers,
|
|
19
|
+
body: body ? JSON.stringify(body) : undefined
|
|
20
|
+
});
|
|
21
|
+
const duration = Date.now() - startTime;
|
|
22
|
+
Logger.info(`Backend response received in ${duration}ms: Status ${response.status}`);
|
|
23
|
+
const responseText = await response.text();
|
|
24
|
+
let responseData;
|
|
25
|
+
try {
|
|
26
|
+
responseData = JSON.parse(responseText);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
responseData = responseText;
|
|
30
|
+
}
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const errorMsg = responseData?.message || responseData?.error || responseText || `HTTP error ${response.status}`;
|
|
33
|
+
throw new Error(errorMsg);
|
|
34
|
+
}
|
|
35
|
+
return responseData.data !== undefined ? responseData.data : responseData;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const duration = Date.now() - startTime;
|
|
39
|
+
Logger.error(`Backend request failed after ${duration}ms`, err);
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { callBackendApi } from "./client.js";
|
|
2
|
+
export const InvoiceApi = {
|
|
3
|
+
async list() {
|
|
4
|
+
return await callBackendApi("/api/v1/invoices", "GET");
|
|
5
|
+
},
|
|
6
|
+
async get(id) {
|
|
7
|
+
return await callBackendApi(`/api/v1/invoices/${id}`, "GET");
|
|
8
|
+
},
|
|
9
|
+
async create(payload) {
|
|
10
|
+
return await callBackendApi("/api/v1/invoices", "POST", payload);
|
|
11
|
+
},
|
|
12
|
+
async update(id, payload) {
|
|
13
|
+
return await callBackendApi(`/api/v1/invoices/${id}`, "PUT", payload);
|
|
14
|
+
},
|
|
15
|
+
async delete(id) {
|
|
16
|
+
return await callBackendApi(`/api/v1/invoices/${id}`, "DELETE");
|
|
17
|
+
},
|
|
18
|
+
async sendEmail(id) {
|
|
19
|
+
return await callBackendApi(`/api/v1/invoices/${id}/resend-email`, "POST");
|
|
20
|
+
},
|
|
21
|
+
// Recurring endpoints
|
|
22
|
+
async listRecurring() {
|
|
23
|
+
return await callBackendApi("/api/v1/recurring", "GET");
|
|
24
|
+
},
|
|
25
|
+
async createRecurring(payload) {
|
|
26
|
+
return await callBackendApi("/api/v1/recurring", "POST", payload);
|
|
27
|
+
},
|
|
28
|
+
async updateRecurring(id, payload) {
|
|
29
|
+
return await callBackendApi(`/api/v1/recurring/${id}`, "PUT", payload);
|
|
30
|
+
},
|
|
31
|
+
async deleteRecurring(id) {
|
|
32
|
+
return await callBackendApi(`/api/v1/recurring/${id}`, "DELETE");
|
|
33
|
+
},
|
|
34
|
+
async runRecurring(id) {
|
|
35
|
+
return await callBackendApi(`/api/v1/recurring/${id}/run`, "POST");
|
|
36
|
+
},
|
|
37
|
+
async skipRecurring(id) {
|
|
38
|
+
return await callBackendApi(`/api/v1/recurring/${id}/skip-next`, "POST");
|
|
39
|
+
}
|
|
40
|
+
};
|
package/build/auth.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CONFIG } from "./config.js";
|
|
2
|
+
export function getAccessToken() {
|
|
3
|
+
if (!CONFIG.ACCESS_TOKEN) {
|
|
4
|
+
throw new Error("Missing INVOICESNEST_ACCESS_TOKEN. Set it in your environment before starting the MCP server.");
|
|
5
|
+
}
|
|
6
|
+
return CONFIG.ACCESS_TOKEN;
|
|
7
|
+
}
|
|
8
|
+
export function getBackendUrl() {
|
|
9
|
+
return CONFIG.BACKEND_URL;
|
|
10
|
+
}
|
package/build/config.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
dotenv.config();
|
|
3
|
+
export const CONFIG = {
|
|
4
|
+
VERSION: "v1",
|
|
5
|
+
API_COMPATIBILITY: "v1",
|
|
6
|
+
BACKEND_URL: process.env.INVOICESNEST_BACKEND_URL || "https://abed-223-123-76-202.ngrok-free.app",
|
|
7
|
+
ACCESS_TOKEN: process.env.INVOICESNEST_ACCESS_TOKEN || "",
|
|
8
|
+
};
|
|
9
|
+
if (!CONFIG.ACCESS_TOKEN) {
|
|
10
|
+
console.error("WARNING: INVOICESNEST_ACCESS_TOKEN is not configured. MCP requests will fail until authorized.");
|
|
11
|
+
}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { server } from "./server.js";
|
|
4
|
+
async function main() {
|
|
5
|
+
const transport = new StdioServerTransport();
|
|
6
|
+
await server.connect(transport);
|
|
7
|
+
console.error("InvoicesNest Model Context Protocol (MCP) server running on stdio transport");
|
|
8
|
+
}
|
|
9
|
+
main().catch((error) => {
|
|
10
|
+
console.error("MCP Server lifecycle crash:", error);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const createClientSchema = z.object({
|
|
3
|
+
name: z.string().min(1, "Client name is required"),
|
|
4
|
+
email: z.string().email("Valid email is required"),
|
|
5
|
+
phone: z.string().optional(),
|
|
6
|
+
address: z.string().optional(),
|
|
7
|
+
taxId: z.string().optional(),
|
|
8
|
+
notes: z.string().optional(),
|
|
9
|
+
businessId: z.string().optional()
|
|
10
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const getDashboardSummarySchema = z.object({});
|
|
3
|
+
export const getRevenueStatsSchema = z.object({});
|
|
4
|
+
export const paymentStatusSchema = z.object({
|
|
5
|
+
status: z.enum(["PAID", "PENDING", "OVERDUE"])
|
|
6
|
+
});
|
|
7
|
+
export const sendInvoiceSchema = z.object({
|
|
8
|
+
id: z.string().optional(),
|
|
9
|
+
invoiceNumber: z.string().optional()
|
|
10
|
+
});
|
|
11
|
+
export const searchInvoicesSchema = z.object({
|
|
12
|
+
query: z.string().optional()
|
|
13
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const createInvoiceSchema = z.object({
|
|
3
|
+
clientName: z.string().min(1, "Client name is required"),
|
|
4
|
+
clientEmail: z.string().email("Valid email is required").optional().or(z.literal("")),
|
|
5
|
+
clientAddress: z.string().optional(),
|
|
6
|
+
clientPhone: z.string().optional(),
|
|
7
|
+
invoiceNumber: z.string().optional(),
|
|
8
|
+
invoiceDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD").optional(),
|
|
9
|
+
dueDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD").optional().or(z.literal("")),
|
|
10
|
+
currency: z.string().length(3, "Currency code must be 3 characters").optional(),
|
|
11
|
+
taxRate: z.number().min(0, "Tax rate cannot be negative").max(100, "Tax rate cannot exceed 100").optional(),
|
|
12
|
+
discountRate: z.number().min(0, "Discount rate cannot be negative").max(100, "Discount rate cannot exceed 100").optional(),
|
|
13
|
+
shipping: z.number().min(0, "Shipping cost cannot be negative").optional(),
|
|
14
|
+
amountPaid: z.number().min(0, "Amount paid cannot be negative").optional(),
|
|
15
|
+
notes: z.string().optional(),
|
|
16
|
+
terms: z.string().optional(),
|
|
17
|
+
status: z.enum(["DRAFT", "SENT", "PAID"]).optional(),
|
|
18
|
+
sendEmailToClient: z.boolean().optional(),
|
|
19
|
+
businessId: z.string().optional(),
|
|
20
|
+
items: z.array(z.object({
|
|
21
|
+
description: z.string().min(1, "Description is required"),
|
|
22
|
+
quantity: z.number().min(0.01, "Quantity must be at least 0.01").optional(),
|
|
23
|
+
rate: z.number().min(0, "Rate cannot be negative").optional()
|
|
24
|
+
})).min(1, "At least one item is required")
|
|
25
|
+
});
|
|
26
|
+
export const updateInvoiceSchema = z.object({
|
|
27
|
+
id: z.string().optional(),
|
|
28
|
+
invoiceNumber: z.string().optional(),
|
|
29
|
+
updateData: z.object({
|
|
30
|
+
clientName: z.string().optional(),
|
|
31
|
+
clientEmail: z.string().email().optional().or(z.literal("")),
|
|
32
|
+
clientAddress: z.string().optional(),
|
|
33
|
+
clientPhone: z.string().optional(),
|
|
34
|
+
status: z.enum(["DRAFT", "SENT", "PAID", "OVERDUE"]).optional(),
|
|
35
|
+
notes: z.string().optional(),
|
|
36
|
+
terms: z.string().optional(),
|
|
37
|
+
dueDate: z.string().optional().or(z.literal("")),
|
|
38
|
+
taxRate: z.number().optional(),
|
|
39
|
+
discountRate: z.number().optional(),
|
|
40
|
+
shipping: z.number().optional(),
|
|
41
|
+
amountPaid: z.number().optional()
|
|
42
|
+
})
|
|
43
|
+
});
|