@mgsoftwarebv/mcp-server-bridge 3.0.1 β 3.3.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 +224 -210
- package/dist/index.js +120089 -2295
- package/dist/index.js.map +1 -1
- package/package.json +57 -55
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
|
-
###
|
|
116
|
-
- **
|
|
117
|
-
- **
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
120
|
-
|
|
121
|
-
- **
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
###
|
|
130
|
-
- **
|
|
131
|
-
- **
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
###
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
|
|
171
|
-
##
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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.
|