@codespar/mcp-siigo 0.1.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 ADDED
@@ -0,0 +1,53 @@
1
+ # MCP Siigo
2
+
3
+ MCP server for **Siigo** — Colombian accounting platform with integrated DIAN electronic invoicing.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Set your credentials
9
+ export SIIGO_API_KEY="your-api-key"
10
+ export SIIGO_ACCESS_TOKEN="your-access-token"
11
+
12
+ # Run via stdio
13
+ npx tsx packages/colombia/siigo/src/index.ts
14
+
15
+ # Run via HTTP
16
+ npx tsx packages/colombia/siigo/src/index.ts --http
17
+ ```
18
+
19
+ ## Environment Variables
20
+
21
+ | Variable | Required | Description |
22
+ |----------|----------|-------------|
23
+ | `SIIGO_API_KEY` | Yes | API key from Siigo |
24
+ | `SIIGO_ACCESS_TOKEN` | Yes | Bearer access token |
25
+ | `MCP_HTTP` | No | Set to `"true"` to enable HTTP transport |
26
+ | `MCP_PORT` | No | HTTP port (default: 3000) |
27
+
28
+ ## Tools
29
+
30
+ | Tool | Description |
31
+ |------|-------------|
32
+ | `create_invoice` | Create an invoice (DIAN electronic invoice) |
33
+ | `get_invoice` | Get invoice details by ID |
34
+ | `list_invoices` | List invoices |
35
+ | `create_credit_note` | Create a credit note |
36
+ | `list_customers` | List customers |
37
+ | `create_customer` | Create a customer |
38
+ | `list_products` | List products |
39
+ | `create_product` | Create a product |
40
+ | `list_taxes` | List available tax types |
41
+ | `list_payment_methods` | List payment methods |
42
+
43
+ ## Auth
44
+
45
+ Uses **Bearer token** authentication. Obtain your access token from the Siigo developer portal.
46
+
47
+ ## API Reference
48
+
49
+ - [Siigo API Docs](https://siigodeveloper.siigo.com/)
50
+
51
+ ---
52
+
53
+ **Enterprise?** Contact us at [codespar.com](https://codespar.com) for dedicated support, custom integrations, and SLAs.
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Server for Siigo — Colombian accounting + DIAN e-invoicing.
4
+ *
5
+ * Tools:
6
+ * - create_invoice: Create an invoice (DIAN electronic invoice)
7
+ * - get_invoice: Get invoice by ID
8
+ * - list_invoices: List invoices
9
+ * - create_credit_note: Create a credit note
10
+ * - list_customers: List customers
11
+ * - create_customer: Create a customer
12
+ * - list_products: List products
13
+ * - create_product: Create a product
14
+ * - list_taxes: List available tax types
15
+ * - list_payment_methods: List payment methods
16
+ *
17
+ * Environment:
18
+ * SIIGO_API_KEY — API key
19
+ * SIIGO_ACCESS_TOKEN — Access token (Bearer)
20
+ */
21
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,413 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Server for Siigo — Colombian accounting + DIAN e-invoicing.
4
+ *
5
+ * Tools:
6
+ * - create_invoice: Create an invoice (DIAN electronic invoice)
7
+ * - get_invoice: Get invoice by ID
8
+ * - list_invoices: List invoices
9
+ * - create_credit_note: Create a credit note
10
+ * - list_customers: List customers
11
+ * - create_customer: Create a customer
12
+ * - list_products: List products
13
+ * - create_product: Create a product
14
+ * - list_taxes: List available tax types
15
+ * - list_payment_methods: List payment methods
16
+ *
17
+ * Environment:
18
+ * SIIGO_API_KEY — API key
19
+ * SIIGO_ACCESS_TOKEN — Access token (Bearer)
20
+ */
21
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
24
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
25
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
26
+ const ACCESS_TOKEN = process.env.SIIGO_ACCESS_TOKEN || "";
27
+ const BASE_URL = "https://api.siigo.com/v1";
28
+ async function siigoRequest(method, path, body) {
29
+ const headers = {
30
+ "Content-Type": "application/json",
31
+ "Accept": "application/json",
32
+ "Authorization": `Bearer ${ACCESS_TOKEN}`,
33
+ };
34
+ const res = await fetch(`${BASE_URL}${path}`, {
35
+ method,
36
+ headers,
37
+ body: body ? JSON.stringify(body) : undefined,
38
+ });
39
+ if (!res.ok) {
40
+ const err = await res.text();
41
+ throw new Error(`Siigo API ${res.status}: ${err}`);
42
+ }
43
+ return res.json();
44
+ }
45
+ const server = new Server({ name: "mcp-siigo", version: "0.1.0" }, { capabilities: { tools: {} } });
46
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
47
+ tools: [
48
+ {
49
+ name: "create_invoice",
50
+ description: "Create an invoice (DIAN electronic invoice)",
51
+ inputSchema: {
52
+ type: "object",
53
+ properties: {
54
+ document: {
55
+ type: "object",
56
+ description: "Document type",
57
+ properties: { id: { type: "number", description: "Document type ID" } },
58
+ required: ["id"],
59
+ },
60
+ date: { type: "string", description: "Invoice date (YYYY-MM-DD)" },
61
+ customer: {
62
+ type: "object",
63
+ description: "Customer reference",
64
+ properties: {
65
+ identification: { type: "string", description: "Customer NIT or CC" },
66
+ branch_office: { type: "number", description: "Branch office (default 0)" },
67
+ },
68
+ required: ["identification"],
69
+ },
70
+ items: {
71
+ type: "array",
72
+ description: "Invoice items",
73
+ items: {
74
+ type: "object",
75
+ properties: {
76
+ code: { type: "string", description: "Product code" },
77
+ description: { type: "string", description: "Description" },
78
+ quantity: { type: "number", description: "Quantity" },
79
+ price: { type: "number", description: "Unit price" },
80
+ discount: { type: "number", description: "Discount percentage" },
81
+ taxes: {
82
+ type: "array",
83
+ description: "Taxes",
84
+ items: {
85
+ type: "object",
86
+ properties: {
87
+ id: { type: "number", description: "Tax ID" },
88
+ name: { type: "string", description: "Tax name" },
89
+ percentage: { type: "number", description: "Tax percentage" },
90
+ },
91
+ },
92
+ },
93
+ },
94
+ required: ["code", "quantity", "price"],
95
+ },
96
+ },
97
+ payments: {
98
+ type: "array",
99
+ description: "Payment methods",
100
+ items: {
101
+ type: "object",
102
+ properties: {
103
+ id: { type: "number", description: "Payment method ID" },
104
+ value: { type: "number", description: "Payment amount" },
105
+ },
106
+ required: ["id", "value"],
107
+ },
108
+ },
109
+ },
110
+ required: ["document", "date", "customer", "items", "payments"],
111
+ },
112
+ },
113
+ {
114
+ name: "get_invoice",
115
+ description: "Get invoice details by ID",
116
+ inputSchema: {
117
+ type: "object",
118
+ properties: { invoiceId: { type: "string", description: "Invoice ID" } },
119
+ required: ["invoiceId"],
120
+ },
121
+ },
122
+ {
123
+ name: "list_invoices",
124
+ description: "List invoices",
125
+ inputSchema: {
126
+ type: "object",
127
+ properties: {
128
+ page: { type: "number", description: "Page number" },
129
+ page_size: { type: "number", description: "Page size (max 100)" },
130
+ date_start: { type: "string", description: "Start date (YYYY-MM-DD)" },
131
+ date_end: { type: "string", description: "End date (YYYY-MM-DD)" },
132
+ },
133
+ },
134
+ },
135
+ {
136
+ name: "create_credit_note",
137
+ description: "Create a credit note against an invoice",
138
+ inputSchema: {
139
+ type: "object",
140
+ properties: {
141
+ document: {
142
+ type: "object",
143
+ description: "Document type",
144
+ properties: { id: { type: "number", description: "Document type ID for credit notes" } },
145
+ required: ["id"],
146
+ },
147
+ date: { type: "string", description: "Credit note date (YYYY-MM-DD)" },
148
+ customer: {
149
+ type: "object",
150
+ description: "Customer reference",
151
+ properties: { identification: { type: "string", description: "Customer NIT or CC" } },
152
+ required: ["identification"],
153
+ },
154
+ items: {
155
+ type: "array",
156
+ description: "Items to credit",
157
+ items: {
158
+ type: "object",
159
+ properties: {
160
+ code: { type: "string", description: "Product code" },
161
+ quantity: { type: "number", description: "Quantity" },
162
+ price: { type: "number", description: "Unit price" },
163
+ },
164
+ required: ["code", "quantity", "price"],
165
+ },
166
+ },
167
+ reason: { type: "string", description: "Reason for the credit note" },
168
+ },
169
+ required: ["document", "date", "customer", "items"],
170
+ },
171
+ },
172
+ {
173
+ name: "list_customers",
174
+ description: "List customers",
175
+ inputSchema: {
176
+ type: "object",
177
+ properties: {
178
+ page: { type: "number", description: "Page number" },
179
+ page_size: { type: "number", description: "Page size" },
180
+ identification: { type: "string", description: "Filter by NIT/CC" },
181
+ },
182
+ },
183
+ },
184
+ {
185
+ name: "create_customer",
186
+ description: "Create a customer",
187
+ inputSchema: {
188
+ type: "object",
189
+ properties: {
190
+ type: { type: "string", description: "Customer type (Customer, Supplier, Other)" },
191
+ person_type: { type: "string", description: "Person type (Person, Company)" },
192
+ id_type: { type: "string", description: "ID type (13=CC, 31=NIT, 22=CE)" },
193
+ identification: { type: "string", description: "NIT or CC number" },
194
+ name: { type: "array", description: "Name array [first_name, last_name]", items: { type: "string" } },
195
+ commercial_name: { type: "string", description: "Commercial/business name" },
196
+ contacts: {
197
+ type: "array",
198
+ description: "Contact info",
199
+ items: {
200
+ type: "object",
201
+ properties: {
202
+ first_name: { type: "string", description: "First name" },
203
+ last_name: { type: "string", description: "Last name" },
204
+ email: { type: "string", description: "Email" },
205
+ phone: { type: "string", description: "Phone" },
206
+ },
207
+ },
208
+ },
209
+ address: {
210
+ type: "object",
211
+ description: "Address",
212
+ properties: {
213
+ address: { type: "string", description: "Street address" },
214
+ city: { type: "object", properties: { country_code: { type: "string" }, state_code: { type: "string" }, city_code: { type: "string" } } },
215
+ },
216
+ },
217
+ },
218
+ required: ["type", "person_type", "id_type", "identification", "name"],
219
+ },
220
+ },
221
+ {
222
+ name: "list_products",
223
+ description: "List products",
224
+ inputSchema: {
225
+ type: "object",
226
+ properties: {
227
+ page: { type: "number", description: "Page number" },
228
+ page_size: { type: "number", description: "Page size" },
229
+ code: { type: "string", description: "Filter by product code" },
230
+ },
231
+ },
232
+ },
233
+ {
234
+ name: "create_product",
235
+ description: "Create a product",
236
+ inputSchema: {
237
+ type: "object",
238
+ properties: {
239
+ code: { type: "string", description: "Product code" },
240
+ name: { type: "string", description: "Product name" },
241
+ account_group: { type: "number", description: "Account group ID" },
242
+ type: { type: "string", description: "Product type (Product, Service)" },
243
+ stock_control: { type: "boolean", description: "Enable stock control" },
244
+ unit: { type: "string", description: "Unit of measure" },
245
+ taxes: {
246
+ type: "array",
247
+ description: "Tax configuration",
248
+ items: {
249
+ type: "object",
250
+ properties: {
251
+ id: { type: "number", description: "Tax ID" },
252
+ },
253
+ },
254
+ },
255
+ prices: {
256
+ type: "array",
257
+ description: "Price list",
258
+ items: {
259
+ type: "object",
260
+ properties: {
261
+ currency_code: { type: "string", description: "Currency (COP)" },
262
+ price_list: { type: "array", items: { type: "object", properties: { position: { type: "number" }, value: { type: "number" } } } },
263
+ },
264
+ },
265
+ },
266
+ },
267
+ required: ["code", "name"],
268
+ },
269
+ },
270
+ {
271
+ name: "list_taxes",
272
+ description: "List available tax types",
273
+ inputSchema: { type: "object", properties: {} },
274
+ },
275
+ {
276
+ name: "list_payment_methods",
277
+ description: "List available payment methods",
278
+ inputSchema: { type: "object", properties: {} },
279
+ },
280
+ ],
281
+ }));
282
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
283
+ const { name, arguments: args } = request.params;
284
+ try {
285
+ switch (name) {
286
+ case "create_invoice":
287
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("POST", "/invoices", {
288
+ document: args?.document,
289
+ date: args?.date,
290
+ customer: args?.customer,
291
+ items: args?.items,
292
+ payments: args?.payments,
293
+ }), null, 2) }] };
294
+ case "get_invoice":
295
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("GET", `/invoices/${args?.invoiceId}`), null, 2) }] };
296
+ case "list_invoices": {
297
+ const params = new URLSearchParams();
298
+ if (args?.page)
299
+ params.set("page", String(args.page));
300
+ if (args?.page_size)
301
+ params.set("page_size", String(args.page_size));
302
+ if (args?.date_start)
303
+ params.set("date_start", args.date_start);
304
+ if (args?.date_end)
305
+ params.set("date_end", args.date_end);
306
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("GET", `/invoices?${params}`), null, 2) }] };
307
+ }
308
+ case "create_credit_note":
309
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("POST", "/credit-notes", {
310
+ document: args?.document,
311
+ date: args?.date,
312
+ customer: args?.customer,
313
+ items: args?.items,
314
+ reason: args?.reason,
315
+ }), null, 2) }] };
316
+ case "list_customers": {
317
+ const params = new URLSearchParams();
318
+ if (args?.page)
319
+ params.set("page", String(args.page));
320
+ if (args?.page_size)
321
+ params.set("page_size", String(args.page_size));
322
+ if (args?.identification)
323
+ params.set("identification", args.identification);
324
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("GET", `/customers?${params}`), null, 2) }] };
325
+ }
326
+ case "create_customer":
327
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("POST", "/customers", {
328
+ type: args?.type,
329
+ person_type: args?.person_type,
330
+ id_type: args?.id_type,
331
+ identification: args?.identification,
332
+ name: args?.name,
333
+ commercial_name: args?.commercial_name,
334
+ contacts: args?.contacts,
335
+ address: args?.address,
336
+ }), null, 2) }] };
337
+ case "list_products": {
338
+ const params = new URLSearchParams();
339
+ if (args?.page)
340
+ params.set("page", String(args.page));
341
+ if (args?.page_size)
342
+ params.set("page_size", String(args.page_size));
343
+ if (args?.code)
344
+ params.set("code", args.code);
345
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("GET", `/products?${params}`), null, 2) }] };
346
+ }
347
+ case "create_product":
348
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("POST", "/products", {
349
+ code: args?.code,
350
+ name: args?.name,
351
+ account_group: args?.account_group,
352
+ type: args?.type,
353
+ stock_control: args?.stock_control,
354
+ unit: args?.unit,
355
+ taxes: args?.taxes,
356
+ prices: args?.prices,
357
+ }), null, 2) }] };
358
+ case "list_taxes":
359
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("GET", "/taxes"), null, 2) }] };
360
+ case "list_payment_methods":
361
+ return { content: [{ type: "text", text: JSON.stringify(await siigoRequest("GET", "/payment-types"), null, 2) }] };
362
+ default:
363
+ return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
364
+ }
365
+ }
366
+ catch (err) {
367
+ return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
368
+ }
369
+ });
370
+ async function main() {
371
+ if (process.argv.includes("--http") || process.env.MCP_HTTP === "true") {
372
+ const { default: express } = await import("express");
373
+ const { randomUUID } = await import("node:crypto");
374
+ const app = express();
375
+ app.use(express.json());
376
+ const transports = new Map();
377
+ app.get("/health", (_req, res) => res.json({ status: "ok", sessions: transports.size }));
378
+ app.post("/mcp", async (req, res) => {
379
+ const sid = req.headers["mcp-session-id"];
380
+ if (sid && transports.has(sid)) {
381
+ await transports.get(sid).handleRequest(req, res, req.body);
382
+ return;
383
+ }
384
+ if (!sid && isInitializeRequest(req.body)) {
385
+ const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
386
+ t.onclose = () => { if (t.sessionId)
387
+ transports.delete(t.sessionId); };
388
+ const s = new Server({ name: "mcp-siigo", version: "0.1.0" }, { capabilities: { tools: {} } });
389
+ server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v));
390
+ server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v));
391
+ await s.connect(t);
392
+ await t.handleRequest(req, res, req.body);
393
+ return;
394
+ }
395
+ res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null });
396
+ });
397
+ app.get("/mcp", async (req, res) => { const sid = req.headers["mcp-session-id"]; if (sid && transports.has(sid))
398
+ await transports.get(sid).handleRequest(req, res);
399
+ else
400
+ res.status(400).send("Invalid session"); });
401
+ app.delete("/mcp", async (req, res) => { const sid = req.headers["mcp-session-id"]; if (sid && transports.has(sid))
402
+ await transports.get(sid).handleRequest(req, res);
403
+ else
404
+ res.status(400).send("Invalid session"); });
405
+ const port = Number(process.env.MCP_PORT) || 3000;
406
+ app.listen(port, () => { console.error(`MCP HTTP server on http://localhost:${port}/mcp`); });
407
+ }
408
+ else {
409
+ const transport = new StdioServerTransport();
410
+ await server.connect(transport);
411
+ }
412
+ }
413
+ main().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@codespar/mcp-siigo",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for Siigo — Colombian accounting + DIAN e-invoicing",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "mcp-siigo": "dist/index.js"
9
+ },
10
+ "files": ["dist"],
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "start": "node dist/index.js"
14
+ },
15
+ "dependencies": {
16
+ "@modelcontextprotocol/sdk": "^1.0.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^22.0.0",
20
+ "typescript": "^5.8.0"
21
+ },
22
+ "license": "MIT",
23
+ "keywords": ["siigo", "accounting", "colombia", "dian", "e-invoicing", "mcp"],
24
+ "mcpName": "io.github.codespar/mcp-siigo"
25
+ }