@dversum/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/README.md +235 -0
- package/dist/bin/dversum-mcp.d.ts +3 -0
- package/dist/bin/dversum-mcp.d.ts.map +1 -0
- package/dist/bin/dversum-mcp.js +7 -0
- package/dist/bin/dversum-mcp.js.map +1 -0
- package/dist/src/client.d.ts +13 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +66 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.d.ts +6 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +20 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/context.d.ts +8 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +6 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +128 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/tools/absences.d.ts +4 -0
- package/dist/src/tools/absences.d.ts.map +1 -0
- package/dist/src/tools/absences.js +44 -0
- package/dist/src/tools/absences.js.map +1 -0
- package/dist/src/tools/calendar.d.ts +4 -0
- package/dist/src/tools/calendar.d.ts.map +1 -0
- package/dist/src/tools/calendar.js +69 -0
- package/dist/src/tools/calendar.js.map +1 -0
- package/dist/src/tools/clients.d.ts +4 -0
- package/dist/src/tools/clients.d.ts.map +1 -0
- package/dist/src/tools/clients.js +72 -0
- package/dist/src/tools/clients.js.map +1 -0
- package/dist/src/tools/contacts.d.ts +4 -0
- package/dist/src/tools/contacts.d.ts.map +1 -0
- package/dist/src/tools/contacts.js +40 -0
- package/dist/src/tools/contacts.js.map +1 -0
- package/dist/src/tools/finance.d.ts +4 -0
- package/dist/src/tools/finance.d.ts.map +1 -0
- package/dist/src/tools/finance.js +67 -0
- package/dist/src/tools/finance.js.map +1 -0
- package/dist/src/tools/invoices.d.ts +4 -0
- package/dist/src/tools/invoices.d.ts.map +1 -0
- package/dist/src/tools/invoices.js +97 -0
- package/dist/src/tools/invoices.js.map +1 -0
- package/dist/src/tools/notifications.d.ts +4 -0
- package/dist/src/tools/notifications.d.ts.map +1 -0
- package/dist/src/tools/notifications.js +24 -0
- package/dist/src/tools/notifications.js.map +1 -0
- package/dist/src/tools/organization.d.ts +4 -0
- package/dist/src/tools/organization.d.ts.map +1 -0
- package/dist/src/tools/organization.js +20 -0
- package/dist/src/tools/organization.js.map +1 -0
- package/dist/src/tools/pages.d.ts +4 -0
- package/dist/src/tools/pages.d.ts.map +1 -0
- package/dist/src/tools/pages.js +46 -0
- package/dist/src/tools/pages.js.map +1 -0
- package/dist/src/tools/projects.d.ts +4 -0
- package/dist/src/tools/projects.d.ts.map +1 -0
- package/dist/src/tools/projects.js +49 -0
- package/dist/src/tools/projects.js.map +1 -0
- package/dist/src/tools/quotes.d.ts +4 -0
- package/dist/src/tools/quotes.d.ts.map +1 -0
- package/dist/src/tools/quotes.js +62 -0
- package/dist/src/tools/quotes.js.map +1 -0
- package/dist/src/tools/storage.d.ts +4 -0
- package/dist/src/tools/storage.d.ts.map +1 -0
- package/dist/src/tools/storage.js +45 -0
- package/dist/src/tools/storage.js.map +1 -0
- package/dist/src/tools/tasks.d.ts +4 -0
- package/dist/src/tools/tasks.d.ts.map +1 -0
- package/dist/src/tools/tasks.js +72 -0
- package/dist/src/tools/tasks.js.map +1 -0
- package/dist/src/tools/time.d.ts +4 -0
- package/dist/src/tools/time.d.ts.map +1 -0
- package/dist/src/tools/time.js +81 -0
- package/dist/src/tools/time.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# @dversum/mcp-server
|
|
2
|
+
|
|
3
|
+
Official [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the **dVersum** business management API. Lets AI assistants like Claude Desktop, Cursor, and Windsurf interact with your dVersum workspace — managing clients, projects, tasks, invoices, time tracking, and more.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Claude Desktop
|
|
8
|
+
|
|
9
|
+
Add this to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"dversum": {
|
|
15
|
+
"command": "npx",
|
|
16
|
+
"args": ["-y", "@dversum/mcp-server"],
|
|
17
|
+
"env": {
|
|
18
|
+
"DVERSUM_API_URL": "https://api.dversum.com/api/v1",
|
|
19
|
+
"DVERSUM_API_TOKEN": "your-jwt-token"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Cursor / Windsurf
|
|
27
|
+
|
|
28
|
+
Add to your MCP settings:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"dversum": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["-y", "@dversum/mcp-server"],
|
|
36
|
+
"env": {
|
|
37
|
+
"DVERSUM_API_URL": "https://api.dversum.com/api/v1",
|
|
38
|
+
"DVERSUM_API_TOKEN": "your-jwt-token"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Docker (Production)
|
|
46
|
+
|
|
47
|
+
### Quick start
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd mcp-server
|
|
51
|
+
|
|
52
|
+
# Create .env file
|
|
53
|
+
echo "DVERSUM_API_URL=https://api.dversum.com/api/v1" > .env
|
|
54
|
+
echo "DVERSUM_API_TOKEN=your-jwt-token" >> .env
|
|
55
|
+
|
|
56
|
+
# Run
|
|
57
|
+
docker compose up -d
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The server starts on port **3100** with a health check at `/health` and the MCP endpoint at `/mcp`.
|
|
61
|
+
|
|
62
|
+
### Build & run manually
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
docker build -t dversum-mcp .
|
|
66
|
+
docker run -d \
|
|
67
|
+
-p 3100:3100 \
|
|
68
|
+
-e DVERSUM_API_URL=https://api.dversum.com/api/v1 \
|
|
69
|
+
-e DVERSUM_API_TOKEN=your-jwt-token \
|
|
70
|
+
--name dversum-mcp \
|
|
71
|
+
--restart unless-stopped \
|
|
72
|
+
dversum-mcp
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Connect remote MCP to Claude Desktop
|
|
76
|
+
|
|
77
|
+
Once the Docker container is running, point Claude Desktop to the remote endpoint:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"dversum": {
|
|
83
|
+
"url": "http://your-server:3100/mcp"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Environment Variables
|
|
90
|
+
|
|
91
|
+
| Variable | Required | Description |
|
|
92
|
+
|----------|----------|-------------|
|
|
93
|
+
| `DVERSUM_API_URL` | Yes | Base URL of your dVersum API (e.g. `https://api.dversum.com/api/v1`) |
|
|
94
|
+
| `DVERSUM_API_TOKEN` | Yes | Your JWT authentication token |
|
|
95
|
+
| `MCP_TRANSPORT` | No | `stdio` (default) or `http` (for Docker/remote) |
|
|
96
|
+
| `MCP_PORT` | No | HTTP port when using `http` transport (default: `3100`) |
|
|
97
|
+
|
|
98
|
+
## Available Tools (53)
|
|
99
|
+
|
|
100
|
+
### Clients (CRM)
|
|
101
|
+
| Tool | Description |
|
|
102
|
+
|------|-------------|
|
|
103
|
+
| `list_clients` | List all clients with pagination |
|
|
104
|
+
| `get_client` | Get client details |
|
|
105
|
+
| `create_client` | Create a new client |
|
|
106
|
+
| `update_client` | Update client details |
|
|
107
|
+
| `delete_client` | Delete a client |
|
|
108
|
+
|
|
109
|
+
### Contacts
|
|
110
|
+
| Tool | Description |
|
|
111
|
+
|------|-------------|
|
|
112
|
+
| `list_contacts` | List all contacts |
|
|
113
|
+
| `get_contact` | Get contact details |
|
|
114
|
+
| `create_contact` | Create a new contact |
|
|
115
|
+
|
|
116
|
+
### Projects
|
|
117
|
+
| Tool | Description |
|
|
118
|
+
|------|-------------|
|
|
119
|
+
| `list_projects` | List all projects |
|
|
120
|
+
| `get_project` | Get project details |
|
|
121
|
+
| `create_project` | Create a new project |
|
|
122
|
+
| `get_project_board` | Get full kanban board (columns + tasks) |
|
|
123
|
+
|
|
124
|
+
### Tasks
|
|
125
|
+
| Tool | Description |
|
|
126
|
+
|------|-------------|
|
|
127
|
+
| `get_task` | Get task details (assignees, subtasks, tags) |
|
|
128
|
+
| `create_task` | Create a task in a project column |
|
|
129
|
+
| `update_task` | Update task properties |
|
|
130
|
+
| `move_task` | Move task to a different column |
|
|
131
|
+
| `assign_task` | Add an assignee to a task |
|
|
132
|
+
| `list_task_comments` | List comments on a task |
|
|
133
|
+
|
|
134
|
+
### Time Tracking
|
|
135
|
+
| Tool | Description |
|
|
136
|
+
|------|-------------|
|
|
137
|
+
| `list_time_entries` | List time entries (filter by date, project) |
|
|
138
|
+
| `create_time_entry` | Log a completed time entry |
|
|
139
|
+
| `start_timer` | Start a running timer |
|
|
140
|
+
| `stop_timer` | Stop a running timer |
|
|
141
|
+
| `get_running_timer` | Get the currently running timer |
|
|
142
|
+
| `get_time_stats` | Get time tracking statistics |
|
|
143
|
+
|
|
144
|
+
### Calendar
|
|
145
|
+
| Tool | Description |
|
|
146
|
+
|------|-------------|
|
|
147
|
+
| `list_events` | List calendar events in a date range |
|
|
148
|
+
| `get_event` | Get event details |
|
|
149
|
+
| `create_event` | Create a calendar event |
|
|
150
|
+
| `update_event` | Update an event |
|
|
151
|
+
| `delete_event` | Delete an event |
|
|
152
|
+
|
|
153
|
+
### Invoices
|
|
154
|
+
| Tool | Description |
|
|
155
|
+
|------|-------------|
|
|
156
|
+
| `list_invoices` | List invoices (filter by status, client, type) |
|
|
157
|
+
| `get_invoice` | Get invoice with line items and totals |
|
|
158
|
+
| `create_invoice` | Create a draft invoice |
|
|
159
|
+
| `update_invoice_status` | Change invoice status |
|
|
160
|
+
| `send_invoice_email` | Send invoice via email |
|
|
161
|
+
| `create_invoice_from_time` | Create invoice from tracked time |
|
|
162
|
+
|
|
163
|
+
### Quotes
|
|
164
|
+
| Tool | Description |
|
|
165
|
+
|------|-------------|
|
|
166
|
+
| `list_quotes` | List quotes/proposals |
|
|
167
|
+
| `get_quote` | Get quote with line items |
|
|
168
|
+
| `create_quote` | Create a draft quote |
|
|
169
|
+
| `convert_quote_to_invoice` | Convert accepted quote to invoice |
|
|
170
|
+
|
|
171
|
+
### Finance
|
|
172
|
+
| Tool | Description |
|
|
173
|
+
|------|-------------|
|
|
174
|
+
| `get_finance_overview` | Monthly revenue vs expenses |
|
|
175
|
+
| `get_vat_summary` | USt-Voranmeldung (KZ 81/86/66/83) |
|
|
176
|
+
| `list_received_invoices` | List incoming invoices |
|
|
177
|
+
| `list_suppliers` | List all suppliers |
|
|
178
|
+
|
|
179
|
+
### Team Planning (Absences)
|
|
180
|
+
| Tool | Description |
|
|
181
|
+
|------|-------------|
|
|
182
|
+
| `list_absences` | List team absences |
|
|
183
|
+
| `create_absence` | Create an absence entry |
|
|
184
|
+
| `get_vacation_stats` | Get vacation quota/usage stats |
|
|
185
|
+
|
|
186
|
+
### Pages
|
|
187
|
+
| Tool | Description |
|
|
188
|
+
|------|-------------|
|
|
189
|
+
| `list_pages` | List all pages |
|
|
190
|
+
| `get_page` | Get page with content |
|
|
191
|
+
| `create_page` | Create a new page |
|
|
192
|
+
| `update_page_content` | Update page content |
|
|
193
|
+
|
|
194
|
+
### File Storage
|
|
195
|
+
| Tool | Description |
|
|
196
|
+
|------|-------------|
|
|
197
|
+
| `list_files` | List files in a folder |
|
|
198
|
+
| `list_folders` | List folders |
|
|
199
|
+
| `create_folder` | Create a new folder |
|
|
200
|
+
| `get_folder_tree` | Get full folder hierarchy |
|
|
201
|
+
|
|
202
|
+
### Notifications
|
|
203
|
+
| Tool | Description |
|
|
204
|
+
|------|-------------|
|
|
205
|
+
| `list_notifications` | List recent notifications |
|
|
206
|
+
| `get_unread_count` | Get unread notification count |
|
|
207
|
+
|
|
208
|
+
### Organization
|
|
209
|
+
| Tool | Description |
|
|
210
|
+
|------|-------------|
|
|
211
|
+
| `get_organization` | Get organization details |
|
|
212
|
+
| `list_members` | List team members |
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Clone the repo
|
|
218
|
+
git clone https://github.com/dversum/dversum.git
|
|
219
|
+
cd dversum/mcp-server
|
|
220
|
+
|
|
221
|
+
# Install dependencies
|
|
222
|
+
npm install
|
|
223
|
+
|
|
224
|
+
# Build
|
|
225
|
+
npm run build
|
|
226
|
+
|
|
227
|
+
# Run locally
|
|
228
|
+
DVERSUM_API_URL=http://localhost:8080/api/v1 \
|
|
229
|
+
DVERSUM_API_TOKEN=your-jwt-token \
|
|
230
|
+
node dist/bin/dversum-mcp.js
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dversum-mcp.d.ts","sourceRoot":"","sources":["../../bin/dversum-mcp.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dversum-mcp.js","sourceRoot":"","sources":["../../bin/dversum-mcp.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class DversumClient {
|
|
2
|
+
private baseUrl;
|
|
3
|
+
private fallbackToken;
|
|
4
|
+
constructor(baseUrl: string, fallbackToken: string);
|
|
5
|
+
private buildUrl;
|
|
6
|
+
private request;
|
|
7
|
+
get<T>(path: string, params?: Record<string, string>): Promise<T>;
|
|
8
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
9
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
10
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
11
|
+
delete(path: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAEA,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;gBAElB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IAKlD,OAAO,CAAC,QAAQ;YAYF,OAAO;IA6Cf,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { getRequestToken } from "./context.js";
|
|
2
|
+
export class DversumClient {
|
|
3
|
+
baseUrl;
|
|
4
|
+
fallbackToken;
|
|
5
|
+
constructor(baseUrl, fallbackToken) {
|
|
6
|
+
this.baseUrl = baseUrl;
|
|
7
|
+
this.fallbackToken = fallbackToken;
|
|
8
|
+
}
|
|
9
|
+
buildUrl(path, params) {
|
|
10
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
11
|
+
if (params) {
|
|
12
|
+
for (const [key, value] of Object.entries(params)) {
|
|
13
|
+
if (value !== undefined && value !== null && value !== "") {
|
|
14
|
+
url.searchParams.set(key, value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return url.toString();
|
|
19
|
+
}
|
|
20
|
+
async request(method, path, options) {
|
|
21
|
+
const url = this.buildUrl(path, options?.params);
|
|
22
|
+
const token = getRequestToken() ?? this.fallbackToken;
|
|
23
|
+
const headers = {
|
|
24
|
+
Authorization: `Bearer ${token}`,
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
};
|
|
27
|
+
const fetchOptions = { method, headers };
|
|
28
|
+
if (options?.body !== undefined) {
|
|
29
|
+
fetchOptions.body = JSON.stringify(options.body);
|
|
30
|
+
}
|
|
31
|
+
const response = await fetch(url, fetchOptions);
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
let errorMessage = `API error ${response.status}: ${response.statusText}`;
|
|
34
|
+
try {
|
|
35
|
+
const errorBody = (await response.json());
|
|
36
|
+
if (errorBody.error) {
|
|
37
|
+
errorMessage = errorBody.error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Use default error message
|
|
42
|
+
}
|
|
43
|
+
throw new Error(errorMessage);
|
|
44
|
+
}
|
|
45
|
+
if (response.status === 204) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return (await response.json());
|
|
49
|
+
}
|
|
50
|
+
async get(path, params) {
|
|
51
|
+
return this.request("GET", path, { params });
|
|
52
|
+
}
|
|
53
|
+
async post(path, body) {
|
|
54
|
+
return this.request("POST", path, { body });
|
|
55
|
+
}
|
|
56
|
+
async put(path, body) {
|
|
57
|
+
return this.request("PUT", path, { body });
|
|
58
|
+
}
|
|
59
|
+
async patch(path, body) {
|
|
60
|
+
return this.request("PATCH", path, { body });
|
|
61
|
+
}
|
|
62
|
+
async delete(path) {
|
|
63
|
+
await this.request("DELETE", path);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# 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 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAyBnC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function loadConfig() {
|
|
2
|
+
const apiUrl = process.env.DVERSUM_API_URL;
|
|
3
|
+
const apiToken = process.env.DVERSUM_API_TOKEN || "";
|
|
4
|
+
const transport = process.env.MCP_TRANSPORT || "stdio";
|
|
5
|
+
if (!apiUrl) {
|
|
6
|
+
throw new Error("DVERSUM_API_URL environment variable is required.\n" +
|
|
7
|
+
"Set it to your dVersum API base URL, e.g. https://api.dversum.com/api/v1");
|
|
8
|
+
}
|
|
9
|
+
// Token is required for stdio mode (single user), optional for HTTP mode (per-user auth via headers)
|
|
10
|
+
if (!apiToken && transport !== "http") {
|
|
11
|
+
throw new Error("DVERSUM_API_TOKEN environment variable is required for stdio mode.\n" +
|
|
12
|
+
"Set it to your dVersum JWT authentication token.\n" +
|
|
13
|
+
"In HTTP mode (MCP_TRANSPORT=http), tokens are provided per-request via Authorization header.");
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
apiUrl: apiUrl.replace(/\/+$/, ""),
|
|
17
|
+
apiToken,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;IACrD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC;IAEvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,qDAAqD;YACnD,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IAED,qGAAqG;IACrG,IAAI,CAAC,QAAQ,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,sEAAsE;YACpE,oDAAoD;YACpD,8FAA8F,CACjG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
interface RequestStore {
|
|
3
|
+
token: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const requestContext: AsyncLocalStorage<RequestStore>;
|
|
6
|
+
export declare function getRequestToken(): string | undefined;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,cAAc,iCAAwC,CAAC;AAEpE,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAMrD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,iBAAiB,EAAgB,CAAC;AAEpE,MAAM,UAAU,eAAe;IAC7B,OAAO,cAAc,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuCpE,wBAAgB,YAAY,IAAI;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAY3E;AAoGD,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ1C"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createServer as createHttpServer } from "node:http";
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
|
+
import { DversumClient } from "./client.js";
|
|
6
|
+
import { loadConfig } from "./config.js";
|
|
7
|
+
import { requestContext } from "./context.js";
|
|
8
|
+
import { registerClientTools } from "./tools/clients.js";
|
|
9
|
+
import { registerContactTools } from "./tools/contacts.js";
|
|
10
|
+
import { registerProjectTools } from "./tools/projects.js";
|
|
11
|
+
import { registerTaskTools } from "./tools/tasks.js";
|
|
12
|
+
import { registerTimeTools } from "./tools/time.js";
|
|
13
|
+
import { registerCalendarTools } from "./tools/calendar.js";
|
|
14
|
+
import { registerInvoiceTools } from "./tools/invoices.js";
|
|
15
|
+
import { registerQuoteTools } from "./tools/quotes.js";
|
|
16
|
+
import { registerFinanceTools } from "./tools/finance.js";
|
|
17
|
+
import { registerAbsenceTools } from "./tools/absences.js";
|
|
18
|
+
import { registerPageTools } from "./tools/pages.js";
|
|
19
|
+
import { registerStorageTools } from "./tools/storage.js";
|
|
20
|
+
import { registerNotificationTools } from "./tools/notifications.js";
|
|
21
|
+
import { registerOrganizationTools } from "./tools/organization.js";
|
|
22
|
+
function registerAllTools(server, apiClient) {
|
|
23
|
+
registerClientTools(server, apiClient);
|
|
24
|
+
registerContactTools(server, apiClient);
|
|
25
|
+
registerProjectTools(server, apiClient);
|
|
26
|
+
registerTaskTools(server, apiClient);
|
|
27
|
+
registerTimeTools(server, apiClient);
|
|
28
|
+
registerCalendarTools(server, apiClient);
|
|
29
|
+
registerInvoiceTools(server, apiClient);
|
|
30
|
+
registerQuoteTools(server, apiClient);
|
|
31
|
+
registerFinanceTools(server, apiClient);
|
|
32
|
+
registerAbsenceTools(server, apiClient);
|
|
33
|
+
registerPageTools(server, apiClient);
|
|
34
|
+
registerStorageTools(server, apiClient);
|
|
35
|
+
registerNotificationTools(server, apiClient);
|
|
36
|
+
registerOrganizationTools(server, apiClient);
|
|
37
|
+
}
|
|
38
|
+
export function createServer() {
|
|
39
|
+
const config = loadConfig();
|
|
40
|
+
const server = new McpServer({
|
|
41
|
+
name: "dversum",
|
|
42
|
+
version: "1.0.0",
|
|
43
|
+
});
|
|
44
|
+
const apiClient = new DversumClient(config.apiUrl, config.apiToken);
|
|
45
|
+
registerAllTools(server, apiClient);
|
|
46
|
+
return { server, fallbackToken: config.apiToken };
|
|
47
|
+
}
|
|
48
|
+
async function startStdio() {
|
|
49
|
+
const { server } = createServer();
|
|
50
|
+
const transport = new StdioServerTransport();
|
|
51
|
+
await server.connect(transport);
|
|
52
|
+
}
|
|
53
|
+
async function handleHttpRequest(req, res, config, fallbackToken) {
|
|
54
|
+
// CORS headers for remote access
|
|
55
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
56
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
|
|
57
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, mcp-session-id");
|
|
58
|
+
if (req.method === "OPTIONS") {
|
|
59
|
+
res.writeHead(204);
|
|
60
|
+
res.end();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Health check
|
|
64
|
+
if (req.url === "/health" && req.method === "GET") {
|
|
65
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
66
|
+
res.end(JSON.stringify({ status: "ok", server: "dversum-mcp" }));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// MCP endpoint
|
|
70
|
+
if (req.url === "/mcp") {
|
|
71
|
+
console.log(`[MCP] ${req.method} /mcp from ${req.headers["user-agent"] || "unknown"}`);
|
|
72
|
+
// Extract Bearer token from Authorization header
|
|
73
|
+
const authHeader = req.headers.authorization;
|
|
74
|
+
const token = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined;
|
|
75
|
+
const effectiveToken = token || fallbackToken;
|
|
76
|
+
if (!effectiveToken) {
|
|
77
|
+
res.writeHead(401, { "Content-Type": "application/json" });
|
|
78
|
+
res.end(JSON.stringify({
|
|
79
|
+
error: "Authorization required. Send a Bearer token in the Authorization header.",
|
|
80
|
+
}));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Stateless mode: create a new server + transport per request
|
|
84
|
+
const server = new McpServer({ name: "dversum", version: "1.0.0" });
|
|
85
|
+
const apiClient = new DversumClient(config.apiUrl, config.apiToken);
|
|
86
|
+
registerAllTools(server, apiClient);
|
|
87
|
+
const transport = new StreamableHTTPServerTransport({
|
|
88
|
+
sessionIdGenerator: undefined, // Stateless mode
|
|
89
|
+
});
|
|
90
|
+
await server.connect(transport);
|
|
91
|
+
await requestContext.run({ token: effectiveToken }, async () => {
|
|
92
|
+
await transport.handleRequest(req, res);
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
res.writeHead(404);
|
|
97
|
+
res.end("Not found");
|
|
98
|
+
}
|
|
99
|
+
async function startHttp() {
|
|
100
|
+
const config = loadConfig();
|
|
101
|
+
const fallbackToken = config.apiToken;
|
|
102
|
+
const port = parseInt(process.env.MCP_PORT || "3100", 10);
|
|
103
|
+
// Use non-async callback to properly catch all errors
|
|
104
|
+
const httpServer = createHttpServer((req, res) => {
|
|
105
|
+
handleHttpRequest(req, res, config, fallbackToken).catch((err) => {
|
|
106
|
+
console.error("[MCP] Unhandled error:", err);
|
|
107
|
+
if (!res.headersSent) {
|
|
108
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
109
|
+
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
httpServer.listen(port, () => {
|
|
114
|
+
console.log(`dVersum MCP server (HTTP) running on port ${port}`);
|
|
115
|
+
console.log(`MCP endpoint: http://localhost:${port}/mcp`);
|
|
116
|
+
console.log(`Health check: http://localhost:${port}/health`);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export async function main() {
|
|
120
|
+
const transport = process.env.MCP_TRANSPORT || "stdio";
|
|
121
|
+
if (transport === "http") {
|
|
122
|
+
await startHttp();
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
await startStdio();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# 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 @@
|
|
|
1
|
+
{"version":3,"file":"absences.d.ts","sourceRoot":"","sources":["../../../src/tools/absences.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,aAAa,QAwDtB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerAbsenceTools(server, client) {
|
|
3
|
+
server.tool("list_absences", "List team absences (vacation, sick leave, home office, etc.).", {
|
|
4
|
+
start_date: z.string().optional().describe("Filter from date (YYYY-MM-DD)"),
|
|
5
|
+
end_date: z.string().optional().describe("Filter to date (YYYY-MM-DD)"),
|
|
6
|
+
type: z
|
|
7
|
+
.enum(["vacation", "sick", "absence", "homeoffice", "business_trip"])
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Filter by absence type"),
|
|
10
|
+
}, async ({ start_date, end_date, type }) => {
|
|
11
|
+
const params = {};
|
|
12
|
+
if (start_date)
|
|
13
|
+
params.start_date = start_date;
|
|
14
|
+
if (end_date)
|
|
15
|
+
params.end_date = end_date;
|
|
16
|
+
if (type)
|
|
17
|
+
params.type = type;
|
|
18
|
+
const data = await client.get("/absences", params);
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
server.tool("create_absence", "Create a new absence entry (vacation, sick leave, etc.).", {
|
|
24
|
+
type: z
|
|
25
|
+
.enum(["vacation", "sick", "absence", "homeoffice", "business_trip"])
|
|
26
|
+
.describe("Absence type"),
|
|
27
|
+
start_date: z.string().describe("Start date (YYYY-MM-DD)"),
|
|
28
|
+
end_date: z.string().describe("End date (YYYY-MM-DD)"),
|
|
29
|
+
note: z.string().optional().describe("Optional note"),
|
|
30
|
+
half_day: z.boolean().optional().describe("Whether this is a half-day absence"),
|
|
31
|
+
}, async (input) => {
|
|
32
|
+
const data = await client.post("/absences", input);
|
|
33
|
+
return {
|
|
34
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
server.tool("get_vacation_stats", "Get vacation quota and usage statistics for the team.", {}, async () => {
|
|
38
|
+
const data = await client.get("/absences/stats");
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=absences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"absences.js","sourceRoot":"","sources":["../../../src/tools/absences.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,MAAqB;IAErB,MAAM,CAAC,IAAI,CACT,eAAe,EACf,+DAA+D,EAC/D;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QAC3E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QACvE,IAAI,EAAE,CAAC;aACJ,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;aACpE,QAAQ,EAAE;aACV,QAAQ,CAAC,wBAAwB,CAAC;KACtC,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;QACvC,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,UAAU;YAAE,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QAC/C,IAAI,QAAQ;YAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzC,IAAI,IAAI;YAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,0DAA0D,EAC1D;QACE,IAAI,EAAE,CAAC;aACJ,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;aACpE,QAAQ,CAAC,cAAc,CAAC;QAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC1D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACtD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;QACrD,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KAChF,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,uDAAuD,EACvD,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACjD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/tools/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,aAAa,QA8FtB"}
|