@mgsoftwarebv/mcp-server-bridge 3.0.2 β†’ 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +224 -210
  2. package/dist/index.js +119955 -2312
  3. package/dist/index.js.map +1 -1
  4. package/package.json +57 -56
package/README.md CHANGED
@@ -1,210 +1,224 @@
1
- # @mgsoftwarebv/mcp-server-bridge
2
-
3
- An MCP server that connects **Cursor / Claude Desktop / Windsurf** directly to your **Refront** Postgres database, exposing tickets, customers, projects, AI dev sessions and time tracking as MCP tools and resources.
4
-
5
- Since v3.0 the bridge talks straight to Postgres via Drizzle ORM β€” the previous PostgREST/JWT transport has been removed.
6
-
7
- ## πŸ“¦ Installation
8
-
9
- ```bash
10
- npm install -g @mgsoftwarebv/mcp-server-bridge
11
- ```
12
-
13
- ## πŸ”§ Cursor Configuration
14
-
15
- Add the following to your `~/.cursor/mcp.json`. You always need two things:
16
-
17
- 1. An **API key** from your Refront dashboard (`/settings/developer`, format `mid_...`).
18
- 2. A **Postgres connection string** for your Refront database (`DATABASE_URL`).
19
-
20
- ```json
21
- {
22
- "mcpServers": {
23
- "refront": {
24
- "command": "npx",
25
- "args": [
26
- "-y",
27
- "@mgsoftwarebv/mcp-server-bridge@latest",
28
- "--api-key=mid_your_api_key_here",
29
- "--database-url=postgresql://USER:PASSWORD@HOST:PORT/DBNAME"
30
- ]
31
- }
32
- }
33
- }
34
- ```
35
-
36
- Both values can also be supplied via environment variables instead of CLI flags:
37
-
38
- ```json
39
- {
40
- "mcpServers": {
41
- "refront": {
42
- "command": "npx",
43
- "args": ["-y", "@mgsoftwarebv/mcp-server-bridge@latest"],
44
- "env": {
45
- "MG_TICKETS_API_KEY": "mid_your_api_key_here",
46
- "DATABASE_PRIMARY_POOLER_URL": "postgresql://USER:PASSWORD@HOST:PORT/DBNAME"
47
- }
48
- }
49
- }
50
- }
51
- ```
52
-
53
- ### πŸ”‘ Getting an API Key
54
-
55
- 1. Go to your Refront dashboard: `/settings/developer`
56
- 2. Create a new API key
57
- 3. Copy the key (format: `mid_...`)
58
- 4. Use it in your MCP configuration
59
-
60
- ### πŸ—„οΈ Getting the Database URL
61
-
62
- - **Refront SaaS customers**: ask MG Software for a read-only Postgres user that points at your team's database (we do not hardcode a default connection string here for security reasons).
63
- - **Self-hosted**: use the same `DATABASE_PRIMARY_POOLER_URL` you configured for the API/dashboard.
64
-
65
- The bridge uses `@refront/db/job-client`, which is tuned for a single connection per process and gracefully closes idle connections.
66
-
67
- ## πŸ“‹ Command-Line Options
68
-
69
- ```bash
70
- # Basic usage
71
- mg-tickets-mcp --api-key=mid_your_key --database-url=postgresql://...
72
-
73
- # Via environment variables
74
- export MG_TICKETS_API_KEY=mid_your_key
75
- export DATABASE_PRIMARY_POOLER_URL=postgresql://USER:PASSWORD@HOST:PORT/DBNAME
76
- mg-tickets-mcp
77
- ```
78
-
79
- `--database-url` falls back to `DATABASE_PRIMARY_POOLER_URL`, then to `DATABASE_URL`. The bridge exits at startup if no connection string is provided.
80
-
81
- For attachment downloads you also need to expose Cloudflare R2 credentials (`R2_ENDPOINT`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, optional `R2_PUBLIC_DOMAIN`). Without them the attachment / image inlining tools will return an error, but everything else keeps working.
82
-
83
- ## 🏒 Multi-provider support
84
-
85
- A single API key now works even if you belong to **multiple providers** (workspaces). The key is bound to one provider as its default, but every team-scoped tool accepts an optional `teamId` argument that is validated against your team memberships.
86
-
87
- How it resolves which provider a tool acts on:
88
-
89
- - **`teamId` provided** β†’ it is validated against your memberships and used.
90
- - **`teamId` omitted, you belong to one provider** β†’ that provider is used automatically (no change for single-provider users).
91
- - **`teamId` omitted, you belong to several** β†’ list/create tools return the list of your providers and ask the AI to re-call with a `teamId`. By-id and session tools resolve across all your providers (the record id disambiguates), and accept `teamId` to narrow.
92
-
93
- Use **get-teams** to list the providers you can act on and copy a `teamId`.
94
-
95
- ## πŸ› οΈ Available Tools
96
-
97
- ### Teams
98
- - **get-teams** β€” list the provider teams (workspaces) you can act on; use a returned id as `teamId` on other tools
99
-
100
- ### Tickets, Customers & Projects
101
- - **get-tickets** β€” list tickets with filters (status, priority, project, customer, text query)
102
- - **get-ticket-by-id** β€” fetch one ticket with comment text, a full attachment listing (ids), and inline images (base64)
103
- - **create-ticket** β€” create a new ticket
104
- - **update-ticket** β€” update fields (title, description, status, priority, type, project, customer, assignee, estimated hours); `assigneeId: null` unassigns
105
- - **add-ticket-comment** β€” add a comment (plain text or TipTap JSON); `isInternal` for internal-only notes
106
- - **get-ticket-comments** β€” read all comments as plain text (author, internal flag, timestamp)
107
- - **get-ticket-attachment** β€” get a 1-hour signed download URL for any ticket/comment attachment (any file type)
108
- - **get-customers** β€” list/search customers
109
- - **create-customer** β€” create a customer
110
- - **get-projects** β€” list/search projects
111
- - **create-project** β€” create a project
112
-
113
- > **Note:** Ticket writes (`update-ticket`, `add-ticket-comment`) are recorded in the dashboard's ticket activity feed but do **not** send notifications (email/Slack/in-app) or trigger `@mention` routing. Notification delivery is a planned follow-up.
114
-
115
- ### AI Development Tracking
116
- - **start-ai-session-smart** β€” start an AI dev session with time tracking
117
- - **track-manual-follow-up** β€” record a manual follow-up prompt and adjust the time estimate
118
- - **sync-session-todos** β€” replace/extend the todo list for a session
119
- - **add-follow-up-todos** β€” append todos that came up during follow-up
120
- - **update-session-status** β€” change the session status (`started`, `in_progress`, `paused`, `completed`, `failed`)
121
- - **get-session-context** β€” read back current session state (ticket, todos, follow-ups)
122
- - **get-completion-context** β€” full context bundle for generating a customer response
123
- - **save-customer-response** β€” store the AI-generated customer response for provider approval
124
- - **complete-ai-session** β€” finalize the session, create/update a draft agenda event
125
-
126
- ### Time Tracking
127
- - **log-hours** β€” log work hours as a draft agenda event (see the `/hours` Cursor command)
128
-
129
- ### GitHub Code Exploration
130
- - **get-github-file** β€” read one file from the GitHub repo linked to a project
131
- - **list-github-directory** β€” list a directory in the GitHub repo linked to a project
132
-
133
- ## ⏱️ Quick Hour Logging with `/hours`
134
-
135
- The `/hours` Cursor command makes logging time effortless:
136
-
137
- 1. **Do your work in Cursor** β€” chat and code normally.
138
- 2. **Type `/hours`** when you're done.
139
- 3. **The AI analyzes the chat** and estimates how long a senior developer (without AI) would have spent.
140
- 4. **Workspace ↔ project matching** is automatic where possible.
141
- 5. **A draft entry** is created in the tracker (not billed yet).
142
-
143
- ### How it works
144
-
145
- 1. Lists all projects via `get-projects`.
146
- 2. Matches the workspace folder name to the closest project (or skips matching when ambiguous).
147
- 3. Analyzes the chat β€” what was built/fixed.
148
- 4. Estimates a realistic time budget (investigation + implementation + testing).
149
- 5. Creates a tracker entry as draft.
150
-
151
- ## πŸ“š Available Resources
152
-
153
- - **tickets://recent** β€” most recent tickets across all accessible teams
154
- - **customers://all** β€” all accessible customers
155
- - **projects://active** β€” all accessible projects
156
-
157
- ## πŸ” Debugging
158
-
159
- The bridge logs to stderr so you can capture debug output without breaking the MCP stdio protocol:
160
-
161
- ```bash
162
- mg-tickets-mcp --api-key=mid_... --database-url=postgresql://... 2>debug.log
163
- ```
164
-
165
- Debug output shows:
166
- - Database connection / startup status
167
- - API key validation hash
168
- - Tool dispatch and access decisions
169
- - Errors with stack traces
170
-
171
- ## πŸ—οΈ Development
172
-
173
- ```bash
174
- git clone https://github.com/mgsoftwarebv/tickets-v2.git
175
- cd tickets-v2/packages/mcp-server-bridge
176
-
177
- bun install
178
- bun run build
179
-
180
- node dist/index.js --api-key=mid_... --database-url=postgresql://...
181
- ```
182
-
183
- ## πŸ”„ Updates
184
-
185
- ```bash
186
- npm update -g @mgsoftwarebv/mcp-server-bridge
187
- # Or via npx (no install required)
188
- npx @mgsoftwarebv/mcp-server-bridge@latest --api-key=mid_...
189
- ```
190
-
191
- ## πŸ†˜ Troubleshooting
192
-
193
- ### ❌ "API key is required"
194
- - Pass `--api-key=` or set `MG_TICKETS_API_KEY`.
195
- - Make sure the key has the format `mid_...` (length 68).
196
-
197
- ### ❌ "Database URL is required"
198
- - Pass `--database-url=postgresql://...` or set `DATABASE_PRIMARY_POOLER_URL` / `DATABASE_URL`.
199
- - Confirm the user can reach the database from your machine (firewall, VPN, etc).
200
-
201
- ### ❌ "API key not found or invalid"
202
- - Generate a new API key in `/settings/developer` and check it is enabled.
203
- - Confirm the key belongs to a team that exists in the database you're connecting to.
204
-
205
- ### ❌ "R2 storage is not configured"
206
- - Image / attachment tools need `R2_ENDPOINT`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`. Set them in the `env` block of your `mcp.json` if you need attachment support.
207
-
208
- ## πŸ“„ License
209
-
210
- MIT Β© MG Software B.V.
1
+ # @mgsoftwarebv/mcp-server-bridge
2
+
3
+ An MCP server that connects **Cursor / Claude Desktop / Windsurf** directly to your **Refront** Postgres database, exposing tickets, customers, projects, AI dev sessions and time tracking as MCP tools and resources.
4
+
5
+ Since v3.0 the bridge talks straight to Postgres via Drizzle ORM β€” the previous PostgREST/JWT transport has been removed.
6
+
7
+ ## πŸ“¦ Installation
8
+
9
+ ```bash
10
+ npm install -g @mgsoftwarebv/mcp-server-bridge
11
+ ```
12
+
13
+ ## πŸ”§ Cursor Configuration
14
+
15
+ Add the following to your `~/.cursor/mcp.json`. You always need two things:
16
+
17
+ 1. An **API key** from your Refront dashboard (`/settings/developer`, format `mid_...`).
18
+ 2. A **Postgres connection string** for your Refront database (`DATABASE_URL`).
19
+
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "refront": {
24
+ "command": "npx",
25
+ "args": [
26
+ "-y",
27
+ "@mgsoftwarebv/mcp-server-bridge@latest",
28
+ "--api-key=mid_your_api_key_here",
29
+ "--database-url=postgresql://USER:PASSWORD@HOST:PORT/DBNAME"
30
+ ]
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Both values can also be supplied via environment variables instead of CLI flags:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "refront": {
42
+ "command": "npx",
43
+ "args": ["-y", "@mgsoftwarebv/mcp-server-bridge@latest"],
44
+ "env": {
45
+ "MG_TICKETS_API_KEY": "mid_your_api_key_here",
46
+ "DATABASE_PRIMARY_POOLER_URL": "postgresql://USER:PASSWORD@HOST:PORT/DBNAME"
47
+ }
48
+ }
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### πŸ”‘ Getting an API Key
54
+
55
+ 1. Go to your Refront dashboard: `/settings/developer`
56
+ 2. Create a new API key
57
+ 3. Copy the key (format: `mid_...`)
58
+ 4. Use it in your MCP configuration
59
+
60
+ ### πŸ—„οΈ Getting the Database URL
61
+
62
+ - **Refront SaaS customers**: ask MG Software for a read-only Postgres user that points at your team's database (we do not hardcode a default connection string here for security reasons).
63
+ - **Self-hosted**: use the same `DATABASE_PRIMARY_POOLER_URL` you configured for the API/dashboard.
64
+
65
+ The bridge uses `@refront/db/job-client`, which is tuned for a single connection per process and gracefully closes idle connections.
66
+
67
+ ## πŸ“‹ Command-Line Options
68
+
69
+ ```bash
70
+ # Basic usage
71
+ mg-tickets-mcp --api-key=mid_your_key --database-url=postgresql://...
72
+
73
+ # Via environment variables
74
+ export MG_TICKETS_API_KEY=mid_your_key
75
+ export DATABASE_PRIMARY_POOLER_URL=postgresql://USER:PASSWORD@HOST:PORT/DBNAME
76
+ mg-tickets-mcp
77
+ ```
78
+
79
+ `--database-url` falls back to `DATABASE_PRIMARY_POOLER_URL`, then to `DATABASE_URL`. The bridge exits at startup if no connection string is provided.
80
+
81
+ For attachment downloads you also need to expose Cloudflare R2 credentials (`R2_ENDPOINT`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, optional `R2_PUBLIC_DOMAIN`). Without them the attachment / image inlining tools will return an error, but everything else keeps working.
82
+
83
+ ## 🏒 Multi-provider support
84
+
85
+ A single API key now works even if you belong to **multiple providers** (workspaces). The key is bound to one provider as its default, but every team-scoped tool accepts an optional `teamId` argument that is validated against your team memberships.
86
+
87
+ How it resolves which provider a tool acts on:
88
+
89
+ - **`teamId` provided** β†’ it is validated against your memberships and used.
90
+ - **`teamId` omitted, you belong to one provider** β†’ that provider is used automatically (no change for single-provider users).
91
+ - **`teamId` omitted, you belong to several** β†’ list/create tools return the list of your providers and ask the AI to re-call with a `teamId`. By-id and session tools resolve across all your providers (the record id disambiguates), and accept `teamId` to narrow.
92
+
93
+ Use **get-teams** to list the providers you can act on and copy a `teamId`.
94
+
95
+ ## πŸ› οΈ Available Tools
96
+
97
+ ### Teams
98
+ - **get-teams** β€” list the provider teams (workspaces) you can act on; use a returned id as `teamId` on other tools
99
+
100
+ ### Tickets, Customers & Projects
101
+ - **get-tickets** β€” list tickets with filters (status, priority, project, customer, text query)
102
+ - **get-ticket-by-id** β€” fetch one ticket with comment text, a full attachment listing (ids), and inline images (base64)
103
+ - **create-ticket** β€” create a new ticket
104
+ - **update-ticket** β€” update fields (title, description, status, priority, type, project, customer, assignee, estimated hours); `assigneeId: null` unassigns
105
+ - **add-ticket-comment** β€” add a comment (plain text or TipTap JSON); `isInternal` for internal-only notes
106
+ - **get-ticket-comments** β€” read all comments as plain text (author, internal flag, timestamp)
107
+ - **get-ticket-attachment** β€” get a 1-hour signed download URL for any ticket/comment attachment (any file type)
108
+ - **get-customers** β€” list/search customers
109
+ - **create-customer** β€” create a customer
110
+ - **get-projects** β€” list/search projects
111
+ - **create-project** β€” create a project
112
+
113
+ > **Note:** Ticket writes (`update-ticket`, `add-ticket-comment`) are recorded in the dashboard's ticket activity feed but do **not** send notifications (email/Slack/in-app) or trigger `@mention` routing. Notification delivery is a planned follow-up.
114
+
115
+ ### Quote / Proposal Documents
116
+ - **list-documents** β€” list documents with filters (type, status, customer, title search)
117
+ - **get-document** β€” fetch one document with metadata and the full blocks JSON
118
+ - **create-document** β€” create a document from content blocks (cover, toc, heading, text, callout, table, chart incl. multi-series, pricing, timeline, two_column, divider, signature); supports a `teamId` provider override and links to a `customerId`
119
+ - **update-document** β€” change title/status/customer, replace all blocks, or append blocks
120
+
121
+ Document text runs through a built-in **humanizer** that strips AI-sounding patterns (em-dashes, NL/EN clichΓ©s like "naadloos"/"seamless", filler phrases). Control it per call with `humanize`:
122
+
123
+ - `"rules"` (default) β€” deterministic cleanup, no API key needed; the tool result includes a change report
124
+ - `"full"` β€” rules + an LLM rewrite pass (requires `OPENAI_API_KEY` in the bridge `env`)
125
+ - `"off"` β€” store the blocks exactly as provided
126
+
127
+ Optional PDF compilation: pass `compilePdf: true` to trigger the `compile-document-pdf` Trigger.dev job after create/update. This requires `TRIGGER_SECRET_KEY` (and optionally `TRIGGER_API_URL`) in the bridge `env`; without it the dashboard compiles the PDF when the document is opened or shared.
128
+
129
+ ### AI Development Tracking
130
+ - **start-ai-session-smart** β€” start an AI dev session with time tracking
131
+ - **track-manual-follow-up** β€” record a manual follow-up prompt and adjust the time estimate
132
+ - **sync-session-todos** β€” replace/extend the todo list for a session
133
+ - **add-follow-up-todos** β€” append todos that came up during follow-up
134
+ - **update-session-status** β€” change the session status (`started`, `in_progress`, `paused`, `completed`, `failed`)
135
+ - **get-session-context** β€” read back current session state (ticket, todos, follow-ups)
136
+ - **get-completion-context** β€” full context bundle for generating a customer response
137
+ - **save-customer-response** β€” store the AI-generated customer response for provider approval
138
+ - **complete-ai-session** β€” finalize the session, create/update a draft agenda event
139
+
140
+ ### Time Tracking
141
+ - **log-hours** β€” log work hours as a draft agenda event (see the `/hours` Cursor command)
142
+
143
+ ### GitHub Code Exploration
144
+ - **get-github-file** β€” read one file from the GitHub repo linked to a project
145
+ - **list-github-directory** β€” list a directory in the GitHub repo linked to a project
146
+
147
+ ## ⏱️ Quick Hour Logging with `/hours`
148
+
149
+ The `/hours` Cursor command makes logging time effortless:
150
+
151
+ 1. **Do your work in Cursor** β€” chat and code normally.
152
+ 2. **Type `/hours`** when you're done.
153
+ 3. **The AI analyzes the chat** and estimates how long a senior developer (without AI) would have spent.
154
+ 4. **Workspace ↔ project matching** is automatic where possible.
155
+ 5. **A draft entry** is created in the tracker (not billed yet).
156
+
157
+ ### How it works
158
+
159
+ 1. Lists all projects via `get-projects`.
160
+ 2. Matches the workspace folder name to the closest project (or skips matching when ambiguous).
161
+ 3. Analyzes the chat β€” what was built/fixed.
162
+ 4. Estimates a realistic time budget (investigation + implementation + testing).
163
+ 5. Creates a tracker entry as draft.
164
+
165
+ ## πŸ“š Available Resources
166
+
167
+ - **tickets://recent** β€” most recent tickets across all accessible teams
168
+ - **customers://all** β€” all accessible customers
169
+ - **projects://active** β€” all accessible projects
170
+
171
+ ## πŸ” Debugging
172
+
173
+ The bridge logs to stderr so you can capture debug output without breaking the MCP stdio protocol:
174
+
175
+ ```bash
176
+ mg-tickets-mcp --api-key=mid_... --database-url=postgresql://... 2>debug.log
177
+ ```
178
+
179
+ Debug output shows:
180
+ - Database connection / startup status
181
+ - API key validation hash
182
+ - Tool dispatch and access decisions
183
+ - Errors with stack traces
184
+
185
+ ## πŸ—οΈ Development
186
+
187
+ ```bash
188
+ git clone https://github.com/mgsoftwarebv/tickets-v2.git
189
+ cd tickets-v2/packages/mcp-server-bridge
190
+
191
+ bun install
192
+ bun run build
193
+
194
+ node dist/index.js --api-key=mid_... --database-url=postgresql://...
195
+ ```
196
+
197
+ ## πŸ”„ Updates
198
+
199
+ ```bash
200
+ npm update -g @mgsoftwarebv/mcp-server-bridge
201
+ # Or via npx (no install required)
202
+ npx @mgsoftwarebv/mcp-server-bridge@latest --api-key=mid_...
203
+ ```
204
+
205
+ ## πŸ†˜ Troubleshooting
206
+
207
+ ### ❌ "API key is required"
208
+ - Pass `--api-key=` or set `MG_TICKETS_API_KEY`.
209
+ - Make sure the key has the format `mid_...` (length 68).
210
+
211
+ ### ❌ "Database URL is required"
212
+ - Pass `--database-url=postgresql://...` or set `DATABASE_PRIMARY_POOLER_URL` / `DATABASE_URL`.
213
+ - Confirm the user can reach the database from your machine (firewall, VPN, etc).
214
+
215
+ ### ❌ "API key not found or invalid"
216
+ - Generate a new API key in `/settings/developer` and check it is enabled.
217
+ - Confirm the key belongs to a team that exists in the database you're connecting to.
218
+
219
+ ### ❌ "R2 storage is not configured"
220
+ - Image / attachment tools need `R2_ENDPOINT`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`. Set them in the `env` block of your `mcp.json` if you need attachment support.
221
+
222
+ ## πŸ“„ License
223
+
224
+ MIT Β© MG Software B.V.