suppa-mcp 1.0.0__tar.gz
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.
- suppa_mcp-1.0.0/.env.example +26 -0
- suppa_mcp-1.0.0/.gitignore +8 -0
- suppa_mcp-1.0.0/CONNECT.md +280 -0
- suppa_mcp-1.0.0/LICENSE +21 -0
- suppa_mcp-1.0.0/PKG-INFO +289 -0
- suppa_mcp-1.0.0/README.md +267 -0
- suppa_mcp-1.0.0/SETUP.md +266 -0
- suppa_mcp-1.0.0/examples/claude_desktop_config.json +12 -0
- suppa_mcp-1.0.0/examples/claude_desktop_config.python-fallback.json +14 -0
- suppa_mcp-1.0.0/examples/cursor_mcp.json +12 -0
- suppa_mcp-1.0.0/examples/generic_mcp.json +15 -0
- suppa_mcp-1.0.0/pyproject.toml +34 -0
- suppa_mcp-1.0.0/scripts/install-claude-startup.ps1 +37 -0
- suppa_mcp-1.0.0/scripts/smoke_test.py +82 -0
- suppa_mcp-1.0.0/scripts/start-claude-with-suppa.ps1 +73 -0
- suppa_mcp-1.0.0/scripts/test_auth.py +276 -0
- suppa_mcp-1.0.0/scripts/uninstall-claude-startup.ps1 +15 -0
- suppa_mcp-1.0.0/src/suppa_mcp/__init__.py +63 -0
- suppa_mcp-1.0.0/src/suppa_mcp/__main__.py +3 -0
- suppa_mcp-1.0.0/src/suppa_mcp/auth.py +373 -0
- suppa_mcp-1.0.0/src/suppa_mcp/config.py +87 -0
- suppa_mcp-1.0.0/src/suppa_mcp/http_client.py +190 -0
- suppa_mcp-1.0.0/src/suppa_mcp/registry.py +73 -0
- suppa_mcp-1.0.0/src/suppa_mcp/server.py +585 -0
- suppa_mcp-1.0.0/src/suppa_mcp/store.py +83 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tenants.py +363 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tools/__init__.py +0 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tools/docs.py +369 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tools/entity.py +160 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tools/forms.py +481 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tools/migrate.py +395 -0
- suppa_mcp-1.0.0/src/suppa_mcp/tools/tasks.py +415 -0
- suppa_mcp-1.0.0/src/suppa_mcp/utils.py +52 -0
- suppa_mcp-1.0.0/uv.lock +976 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# ── Suppa 2.0 (target platform) ──────────────────────────────────────────────
|
|
2
|
+
# Optional default tenant. A user JWT (full access incl. Tasks) or an API key.
|
|
3
|
+
# For multi-tenant use you can leave SUPPA_API_KEY empty and authenticate per
|
|
4
|
+
# tenant at runtime (suppa_login) — tokens are stored in the OS keychain.
|
|
5
|
+
SUPPA_API_KEY=your-suppa-2.0-token-here
|
|
6
|
+
SUPPA_BASE_URL=https://modern.suppa.me
|
|
7
|
+
SUPPA_LANG=en
|
|
8
|
+
SUPPA_TZ=Europe/Kyiv
|
|
9
|
+
# Entity ID used for file uploads (default 37)
|
|
10
|
+
# SUPPA_TASKS_ENTITY_ID=37
|
|
11
|
+
# Where the tenant registry (tenants.json) is stored (default: ~/.suppa-mcp)
|
|
12
|
+
# SUPPA_MCP_HOME=
|
|
13
|
+
|
|
14
|
+
# ── Google login (suppa_login) ───────────────────────────────────────────────
|
|
15
|
+
# Shared Google OAuth client for the in-browser login. Defaults to the Suppa
|
|
16
|
+
# web client; override only if your tenants use a different one.
|
|
17
|
+
# SUPPA_GOOGLE_CLIENT_ID=294101885657-…apps.googleusercontent.com
|
|
18
|
+
# Local port for the login page. http://localhost:<port> must be in the Google
|
|
19
|
+
# client's "Authorized JavaScript origins". Default 8765.
|
|
20
|
+
# SUPPA_MCP_LOGIN_PORT=8765
|
|
21
|
+
|
|
22
|
+
# ── Suppa 1.0 (source platform) — only for the migration connector ───────────
|
|
23
|
+
# Provide one of API key / access token (access token takes priority).
|
|
24
|
+
# SUPPA_V1_BASE_URL=https://sp.modern-expo.com
|
|
25
|
+
# SUPPA_V1_API_KEY=your-suppa-1.0-api-key
|
|
26
|
+
# SUPPA_V1_ACCESS_TOKEN=your-suppa-1.0-access-token
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Connecting the Suppa 2.0 MCP Server to Any Agent
|
|
2
|
+
|
|
3
|
+
This is a step‑by‑step plan to connect the Suppa 2.0 MCP Server to any
|
|
4
|
+
MCP‑compatible AI agent and use it for day‑to‑day development against the Suppa
|
|
5
|
+
platform.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. How it works (architecture)
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart LR
|
|
13
|
+
A[AI Agent\nClaude / Copilot / Cursor] -- MCP stdio --> B[suppa_mcp server\nruns locally]
|
|
14
|
+
B -- HTTPS + Bearer token --> C[(Suppa Platform\nmodern.suppa.me)]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- The agent talks to the server over the **MCP stdio transport** — it only sees
|
|
18
|
+
*tool names and results*, never your credentials.
|
|
19
|
+
- The server reads `SUPPA_API_KEY` from its **local environment** and adds it to
|
|
20
|
+
the `Authorization` header of each HTTPS request.
|
|
21
|
+
- Because the server runs on your machine, there are no CORS/proxy/sandbox‑domain
|
|
22
|
+
problems.
|
|
23
|
+
|
|
24
|
+
**Security boundary:** the API key never leaves your machine and is never placed
|
|
25
|
+
in the model context.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. One‑time setup
|
|
30
|
+
|
|
31
|
+
### 2.1 Prerequisites
|
|
32
|
+
- Python **3.10+** on PATH (`python --version`).
|
|
33
|
+
- A Suppa token. Either:
|
|
34
|
+
- a **user JWT** (full access incl. Tasks) — copy the `accessToken` cookie from
|
|
35
|
+
the browser while logged into `modern.suppa.me`, or
|
|
36
|
+
- an ** API key** (Docs/Entities/Forms/Users).
|
|
37
|
+
|
|
38
|
+
### 2.2 Install the server
|
|
39
|
+
```bash
|
|
40
|
+
# from a clone of the repo
|
|
41
|
+
cd suppa2.0-mcp-server
|
|
42
|
+
pip install -e .
|
|
43
|
+
|
|
44
|
+
# …or directly from the repository
|
|
45
|
+
pip install "git+https://git.modern-expo.com/asu/me-development/skills.git#subdirectory=suppa2.0-mcp-server"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2.3 Authenticate
|
|
49
|
+
|
|
50
|
+
There are two ways to provide credentials. **For teams and multiple tenants,
|
|
51
|
+
prefer browser login (A)** — the agent config then holds no secrets and is
|
|
52
|
+
identical for everyone.
|
|
53
|
+
|
|
54
|
+
#### A. Browser login (recommended, multi-tenant)
|
|
55
|
+
|
|
56
|
+
Leave `SUPPA_API_KEY` unset. Once connected, ask the agent to **log in**:
|
|
57
|
+
|
|
58
|
+
- “**Log in to Suppa testing.modern.me**” → runs `suppa_login`, opens a local
|
|
59
|
+
page, you sign in with Google. Tokens are stored in your **OS keychain** and
|
|
60
|
+
**refreshed automatically** — you won't log in again until the refresh window
|
|
61
|
+
lapses (~10 days of inactivity).
|
|
62
|
+
- “**Switch to the prod tenant**” → `suppa_use_tenant`.
|
|
63
|
+
- “**List my Suppa tenants**” → `suppa_list_tenants`.
|
|
64
|
+
|
|
65
|
+
**One-time admin setup (per Google OAuth client):** add
|
|
66
|
+
`http://localhost:8765` to the client's **Authorized JavaScript origins** in
|
|
67
|
+
Google Cloud (match `SUPPA_MCP_LOGIN_PORT` if you change it). Without this,
|
|
68
|
+
Google Identity Services won't issue a token to the local page.
|
|
69
|
+
|
|
70
|
+
#### B. Static token (single tenant / CI)
|
|
71
|
+
|
|
72
|
+
Create a `.env` next to the project (it is git‑ignored), **or** pass the value
|
|
73
|
+
in the agent's `env` block (next section).
|
|
74
|
+
|
|
75
|
+
```ini
|
|
76
|
+
SUPPA_API_KEY=your-jwt-or-api-key
|
|
77
|
+
SUPPA_BASE_URL=https://modern.suppa.me
|
|
78
|
+
SUPPA_LANG=en
|
|
79
|
+
SUPPA_TZ=Europe/Kyiv
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### Optional: Suppa 1.0 → 2.0 migration connector
|
|
83
|
+
The `suppa_migrate_entities_from_v1` tool reads entity schemas from a **Suppa 1.0**
|
|
84
|
+
backend and recreates them on this Suppa 2.0 platform. Set these extra variables to
|
|
85
|
+
enable it:
|
|
86
|
+
|
|
87
|
+
```ini
|
|
88
|
+
SUPPA_V1_BASE_URL=https://sp.modern-expo.com
|
|
89
|
+
# provide one of the two (access token takes priority):
|
|
90
|
+
SUPPA_V1_API_KEY=your-suppa-1.0-api-key
|
|
91
|
+
SUPPA_V1_ACCESS_TOKEN=your-suppa-1.0-access-token
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The tool is **dry-run by default** — call it with `dry_run=false` only after
|
|
95
|
+
reviewing the printed plan. It migrates custom entities (set `include_builtin=true`
|
|
96
|
+
to include builtin ones) and creates relation fields in a second pass.
|
|
97
|
+
|
|
98
|
+
**Recommended reviewable workflow** — generate an entity-list file, inspect/edit it,
|
|
99
|
+
then create the entities in 2.0 from that exact file:
|
|
100
|
+
|
|
101
|
+
1. Export the plan (no writes to 2.0):
|
|
102
|
+
`suppa_migrate_entities_from_v1(dry_run=true, output_file="migration_plan.json")`
|
|
103
|
+
2. Open `migration_plan.json` and review the `entities` array and `warnings`
|
|
104
|
+
(unsupported field types, out-of-set relation targets). Edit if needed.
|
|
105
|
+
3. Create everything in 2.0 from the reviewed file:
|
|
106
|
+
`suppa_migrate_entities_from_v1(dry_run=false, plan_file="migration_plan.json")`
|
|
107
|
+
|
|
108
|
+
The plan file structure is:
|
|
109
|
+
|
|
110
|
+
```jsonc
|
|
111
|
+
{
|
|
112
|
+
"source": "https://sp.modern-expo.com",
|
|
113
|
+
"target": "https://modern.suppa.me",
|
|
114
|
+
"entity_count": 2,
|
|
115
|
+
"warnings": ["Task.weird: unsupported type 'GeoPoint' — skipped"],
|
|
116
|
+
"entities": [
|
|
117
|
+
{
|
|
118
|
+
"name": "Task",
|
|
119
|
+
"title": "Task",
|
|
120
|
+
"title_field_name": "subject", // verified to exist among scalar_fields
|
|
121
|
+
"scalar_fields": [{ "name": "subject", "title": "Subject", "type": "text", "required": false }],
|
|
122
|
+
"enum_fields": [{ "name": "status", "title": "Status", "type": "enum",
|
|
123
|
+
"enum_name": "Task_status", "values": ["Active", "Done"], "required": true }],
|
|
124
|
+
"relation_fields": [{ "name": "project", "title": "Project", "type": "relation",
|
|
125
|
+
"relation_entity": "Project", "required": false }]
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
### 2.4 Smoke test (optional)
|
|
133
|
+
```bash
|
|
134
|
+
python -m suppa_mcp # should start and wait on stdio (Ctrl+C to exit)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 3. Connect your agent
|
|
140
|
+
|
|
141
|
+
Every MCP client uses the same launch command:
|
|
142
|
+
`python -m suppa_mcp` with the env var set.
|
|
143
|
+
|
|
144
|
+
### Claude Desktop
|
|
145
|
+
Edit `claude_desktop_config.json`
|
|
146
|
+
(`%APPDATA%/Claude/` on Windows, `~/Library/Application Support/Claude/` on macOS):
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"mcpServers": {
|
|
150
|
+
"suppa": {
|
|
151
|
+
"command": "python",
|
|
152
|
+
"args": ["-m", "suppa_mcp"],
|
|
153
|
+
"env": { "SUPPA_API_KEY": "your-token-here" }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### VS Code (GitHub Copilot agent mode)
|
|
160
|
+
Create `.vscode/mcp.json` in your workspace. Use an **input prompt** so you are
|
|
161
|
+
asked for the token in a **masked modal** — it is stored in VS Code's secret
|
|
162
|
+
storage (OS keychain) and never written to disk or sent to the chat:
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"inputs": [
|
|
166
|
+
{
|
|
167
|
+
"type": "promptString",
|
|
168
|
+
"id": "suppa-token",
|
|
169
|
+
"description": "Suppa API token (user JWT for full Tasks access)",
|
|
170
|
+
"password": true
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
"servers": {
|
|
174
|
+
"suppa": {
|
|
175
|
+
"command": "python",
|
|
176
|
+
"args": ["-m", "suppa_mcp"],
|
|
177
|
+
"env": { "SUPPA_API_KEY": "${input:suppa-token}" }
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
Start the `suppa` server (or open Copilot Chat **Agent** mode) → VS Code shows the
|
|
183
|
+
masked prompt once → the `suppa_*` tools appear in the tool picker.
|
|
184
|
+
|
|
185
|
+
### Cursor
|
|
186
|
+
`Settings → MCP → Add new server`:
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"suppa": {
|
|
190
|
+
"command": "python",
|
|
191
|
+
"args": ["-m", "suppa_mcp"],
|
|
192
|
+
"env": { "SUPPA_API_KEY": "your-token-here" }
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Windsurf / any other MCP client
|
|
198
|
+
Add a stdio server with command `python`, args `["-m", "suppa_mcp"]`, and the
|
|
199
|
+
`SUPPA_API_KEY` environment variable. That is all any compliant client needs.
|
|
200
|
+
|
|
201
|
+
### Claude Code (CLI)
|
|
202
|
+
If this server is delivered as a **plugin**, Claude Code prompts for the token in
|
|
203
|
+
a **masked modal** at enable time (via the plugin's `userConfig`) and stores it
|
|
204
|
+
in your system keychain — no token in chat, no token on disk.
|
|
205
|
+
|
|
206
|
+
To register the server manually instead, run:
|
|
207
|
+
```bash
|
|
208
|
+
claude mcp add suppa -- python -m suppa_mcp
|
|
209
|
+
```
|
|
210
|
+
Claude Code stores the server config in `~/.claude.json` under your user profile.
|
|
211
|
+
Provide the token via your shell environment (`SUPPA_API_KEY`) so it is not
|
|
212
|
+
written into a shared config file.
|
|
213
|
+
|
|
214
|
+
Start a new session and verify with `/mcp` — you should see **suppa** with 50 tools listed.
|
|
215
|
+
|
|
216
|
+
> Never paste real tokens into the chat, into a committed `.env`, or into a
|
|
217
|
+
> shared config. Prefer the masked modal prompt or your own shell environment.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 4. Verify the connection
|
|
222
|
+
|
|
223
|
+
Ask the agent:
|
|
224
|
+
|
|
225
|
+
- “**List my Suppa documents.**” → calls `suppa_list_docs`.
|
|
226
|
+
- “**Who am I in Suppa?**” → calls `suppa_get_me` (needs a user JWT).
|
|
227
|
+
- “**List the entities in Suppa.**” → calls `suppa_list_entities`.
|
|
228
|
+
|
|
229
|
+
If these return data, the connection works.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 5. Using it for development
|
|
234
|
+
|
|
235
|
+
Typical agent‑driven workflows now available without leaving your editor:
|
|
236
|
+
|
|
237
|
+
| Goal | Ask the agent… | Tools used |
|
|
238
|
+
|------|----------------|------------|
|
|
239
|
+
| Triage work | “Show my active tasks and overdue ones.” | `suppa_search_tasks` |
|
|
240
|
+
| Create work | “Create a task ‘Fix login bug’ assigned to me, due tomorrow.” | `suppa_create_task` |
|
|
241
|
+
| Collaborate | “Comment on task 931692 and @mention Andrii.” | `suppa_add_comment` |
|
|
242
|
+
| Attach artefacts | “Attach ./build/report.pdf to task 931692.” | `suppa_attach_file` |
|
|
243
|
+
| Write docs | “Add a ‘Release notes’ page to doc 23 and fill it.” | `suppa_create_page`, `suppa_create_blocks` |
|
|
244
|
+
| Inspect schema | “Describe the Tasks entity fields.” | `suppa_describe_entity` |
|
|
245
|
+
| Query data | “Find Applications created this month.” | `suppa_search_records` |
|
|
246
|
+
| Build a form | “Generate a form from the Tasks entity and create it.” | `suppa_generate_form_schema`, `suppa_create_form` |
|
|
247
|
+
|
|
248
|
+
### Good practices
|
|
249
|
+
- **IDs are explicit.** Tools take numeric IDs; have the agent *search first*
|
|
250
|
+
(`suppa_search_*` / `suppa_list_*`) then act.
|
|
251
|
+
- **HTML content.** Task/comment descriptions and doc blocks accept HTML; the
|
|
252
|
+
server wraps plain text automatically.
|
|
253
|
+
- **Dates.** `deadline` accepts `today`, `tomorrow`, `+3d`, `+2h`, `+30m`, or ISO.
|
|
254
|
+
- **Tasks need a user JWT.** Swap `SUPPA_API_KEY` to a user token if task tools
|
|
255
|
+
return empty.
|
|
256
|
+
- **Reversibility.** Deletes are soft‑deletes; still confirm before bulk changes.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 6. Troubleshooting
|
|
261
|
+
|
|
262
|
+
| Symptom | Cause | Fix |
|
|
263
|
+
|---------|-------|-----|
|
|
264
|
+
| `SUPPA_API_KEY environment variable is not set` | No token in env/.env | Set it in the agent `env` block |
|
|
265
|
+
| Empty task results | Integrator key, not a user | Use a user JWT |
|
|
266
|
+
| `HTTP 401` | Expired/invalid token | Refresh the token |
|
|
267
|
+
| `HTTP 400 Field … not found` | Wrong field projection | Update the server; report the entity/field |
|
|
268
|
+
| Agent shows no `suppa_*` tools | Server not launched | Check `python -m suppa_mcp` runs and config path is correct |
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 7. Updating
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
cd suppa2.0-mcp-server
|
|
276
|
+
git pull
|
|
277
|
+
pip install -e . # picks up new tools/fixes
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Restart the agent (or reload the MCP server) to load changes.
|
suppa_mcp-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrii Herasymchuk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
suppa_mcp-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: suppa-mcp
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MCP server for the Suppa platform (modern.suppa.me) — Tasks, Docs, Entities, Forms, with multi-tenant Google auth
|
|
5
|
+
Project-URL: Homepage, https://github.com/Andrii-Herasymchuk/skills
|
|
6
|
+
Project-URL: Repository, https://github.com/Andrii-Herasymchuk/skills
|
|
7
|
+
Author-email: Andrii Herasymchuk <cloud.developers@modern-expo.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: ai-tools,claude,mcp,model-context-protocol,suppa
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: keyring>=24.0.0
|
|
20
|
+
Requires-Dist: mcp[cli]>=1.0.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# Suppa 2.0 MCP Server
|
|
24
|
+
|
|
25
|
+
MCP (Model Context Protocol) server for the [Suppa platform](https://modern.suppa.me) — provides AI agents with tools to manage Tasks, Docs/Pages, Entities, and Forms.
|
|
26
|
+
|
|
27
|
+
## Why MCP?
|
|
28
|
+
|
|
29
|
+
- **API key stays local** — never sent to the AI agent, stored only in `.env`
|
|
30
|
+
- **Works with any MCP client** — Claude Desktop, VS Code Copilot, Cursor, Windsurf, etc.
|
|
31
|
+
- **No CORS/proxy issues** — runs locally, makes direct HTTPS calls to Suppa
|
|
32
|
+
- **50+ tools** covering Tasks, Documents, Entity schema, Forms, and 1.0→2.0 migration
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Install
|
|
37
|
+
|
|
38
|
+
**Recommended — zero-install via PyPI.** Point your MCP client at `uvx`
|
|
39
|
+
([uv](https://docs.astral.sh/uv/)); it fetches and runs the latest release on
|
|
40
|
+
demand (the Python equivalent of `npx`), so there's nothing to install or update:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{ "mcpServers": { "suppa": { "command": "uvx", "args": ["suppa-mcp"] } } }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or install the command explicitly:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv tool install suppa-mcp # or: pipx install suppa-mcp / pip install suppa-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This provides a `suppa-mcp` command that any MCP client can launch directly.
|
|
53
|
+
|
|
54
|
+
**From source instead:**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# from a local clone
|
|
58
|
+
cd suppa2.0-mcp-server && pip install -e .
|
|
59
|
+
|
|
60
|
+
# or straight from the repository
|
|
61
|
+
pip install "git+https://git.modern-expo.com/asu/me-development/skills.git#subdirectory=suppa2.0-mcp-server"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Configure
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cp .env.example .env
|
|
68
|
+
# Edit .env and set SUPPA_API_KEY
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then verify your token and connectivity without any client:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
suppa-mcp --check
|
|
75
|
+
# OK: connected to https://modern.suppa.me — 139 entities visible.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 3. Connect to your AI agent
|
|
79
|
+
|
|
80
|
+
Ready-to-copy configs are in [`examples/`](examples). Replace `YOUR_TOKEN_HERE`
|
|
81
|
+
with your Suppa token. All clients use the same `suppa-mcp` command.
|
|
82
|
+
|
|
83
|
+
**Claude Desktop** — merge [`examples/claude_desktop_config.json`](examples/claude_desktop_config.json)
|
|
84
|
+
into `claude_desktop_config.json` (Windows: `%APPDATA%/Claude/`, macOS:
|
|
85
|
+
`~/Library/Application Support/Claude/`):
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"suppa": {
|
|
90
|
+
"command": "suppa-mcp",
|
|
91
|
+
"env": {
|
|
92
|
+
"SUPPA_API_KEY": "YOUR_TOKEN_HERE",
|
|
93
|
+
"SUPPA_BASE_URL": "https://modern.suppa.me"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**VS Code Copilot** — already wired in [`.vscode/mcp.json`](../.vscode/mcp.json);
|
|
101
|
+
it prompts for the token in a masked input. Start the `suppa` server from the
|
|
102
|
+
MCP view.
|
|
103
|
+
|
|
104
|
+
**Cursor / Windsurf / Cline** — use [`examples/cursor_mcp.json`](examples/cursor_mcp.json)
|
|
105
|
+
or [`examples/generic_mcp.json`](examples/generic_mcp.json).
|
|
106
|
+
|
|
107
|
+
> If a client reports `suppa-mcp` not found, its launcher can't see your Python
|
|
108
|
+
> Scripts dir on PATH. Use the explicit-interpreter fallback
|
|
109
|
+
> [`examples/claude_desktop_config.python-fallback.json`](examples/claude_desktop_config.python-fallback.json)
|
|
110
|
+
> (`command` = full path from `where.exe python`, `args` = `["-m","suppa_mcp"]`,
|
|
111
|
+
> `cwd` = this project).
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
## Environment Variables
|
|
115
|
+
|
|
116
|
+
| Variable | Default | Description |
|
|
117
|
+
|----------|---------|-------------|
|
|
118
|
+
| `SUPPA_API_KEY` | (required) | JWT token or API key |
|
|
119
|
+
| `SUPPA_BASE_URL` | `https://modern.suppa.me` | Platform URL |
|
|
120
|
+
| `SUPPA_LANG` | `en` | Language (`en`/`uk`) |
|
|
121
|
+
| `SUPPA_TZ` | `Europe/Kyiv` | Timezone |
|
|
122
|
+
| `SUPPA_TASKS_ENTITY_ID` | `37` | Entity ID for file uploads |
|
|
123
|
+
|
|
124
|
+
## Available Tools (52 total)
|
|
125
|
+
|
|
126
|
+
### Tasks (16 tools)
|
|
127
|
+
| Tool | Description |
|
|
128
|
+
|------|-------------|
|
|
129
|
+
| `suppa_get_me` | Current user profile |
|
|
130
|
+
| `suppa_search_tasks` | Search with filters (my, active, overdue, etc.) |
|
|
131
|
+
| `suppa_count_tasks` | Count matching tasks |
|
|
132
|
+
| `suppa_get_task` | Full task details |
|
|
133
|
+
| `suppa_create_task` | Create task |
|
|
134
|
+
| `suppa_update_task` | Update task fields |
|
|
135
|
+
| `suppa_delete_task` | Soft-delete task |
|
|
136
|
+
| `suppa_move_task` | Move to another stage |
|
|
137
|
+
| `suppa_close_task` | Close (completed stage) |
|
|
138
|
+
| `suppa_add_comment` | Comment with @mentions |
|
|
139
|
+
| `suppa_get_comments` | List task comments |
|
|
140
|
+
| `suppa_attach_file` | Upload & attach file |
|
|
141
|
+
| `suppa_list_workflows` | Available workflows |
|
|
142
|
+
| `suppa_list_stages` | Stages in a workflow |
|
|
143
|
+
| `suppa_list_task_types` | Task type options |
|
|
144
|
+
| `suppa_search_users` | Find users by name |
|
|
145
|
+
|
|
146
|
+
### Docs & Pages (13 tools)
|
|
147
|
+
| Tool | Description |
|
|
148
|
+
|------|-------------|
|
|
149
|
+
| `suppa_list_docs` | List documents |
|
|
150
|
+
| `suppa_get_doc` | Document with page tree |
|
|
151
|
+
| `suppa_create_doc` | Create document |
|
|
152
|
+
| `suppa_update_doc` | Update document |
|
|
153
|
+
| `suppa_delete_doc` | Delete document |
|
|
154
|
+
| `suppa_list_pages` | Pages in a document |
|
|
155
|
+
| `suppa_get_page` | Page metadata |
|
|
156
|
+
| `suppa_create_page` | Create page |
|
|
157
|
+
| `suppa_update_page` | Update page |
|
|
158
|
+
| `suppa_delete_page` | Delete page |
|
|
159
|
+
| `suppa_get_blocks` | Raw block data |
|
|
160
|
+
| `suppa_read_page` | Readable text output |
|
|
161
|
+
| `suppa_create_blocks` | Add blocks to page |
|
|
162
|
+
| `suppa_insert_block` | Insert at position |
|
|
163
|
+
| `suppa_update_block` | Edit block content |
|
|
164
|
+
| `suppa_delete_block` | Remove block |
|
|
165
|
+
| `suppa_reorder_blocks` | Reorder blocks |
|
|
166
|
+
|
|
167
|
+
### Entity & Schema (8 tools)
|
|
168
|
+
| Tool | Description |
|
|
169
|
+
|------|-------------|
|
|
170
|
+
| `suppa_list_entities` | All entities/tables |
|
|
171
|
+
| `suppa_describe_entity` | Full schema |
|
|
172
|
+
| `suppa_search_records` | Query any entity |
|
|
173
|
+
| `suppa_create_entity` | Create new table |
|
|
174
|
+
| `suppa_add_field` | Add field to entity |
|
|
175
|
+
| `suppa_add_enum_values` | Add enum options |
|
|
176
|
+
| `suppa_list_field_types` | Available types |
|
|
177
|
+
| `suppa_create_record` | Insert record |
|
|
178
|
+
| `suppa_update_record` | Update record |
|
|
179
|
+
| `suppa_delete_record` | Delete record |
|
|
180
|
+
|
|
181
|
+
### Forms (6 tools)
|
|
182
|
+
| Tool | Description |
|
|
183
|
+
|------|-------------|
|
|
184
|
+
| `suppa_list_forms` | List forms |
|
|
185
|
+
| `suppa_get_form` | Form with schema |
|
|
186
|
+
| `suppa_create_form` | Create form |
|
|
187
|
+
| `suppa_update_form` | Update form |
|
|
188
|
+
| `suppa_generate_form_schema` | Auto-generate from entity |
|
|
189
|
+
| `suppa_add_field_to_form` | Add field to form |
|
|
190
|
+
| `suppa_list_form_field_types` | Field type catalog |
|
|
191
|
+
|
|
192
|
+
### Migration
|
|
193
|
+
| Tool | Description |
|
|
194
|
+
|------|-------------|
|
|
195
|
+
| `suppa_migrate_entities_from_v1` | Replicate Suppa 1.0 entities/fields into 2.0 (dry-run by default; supports reviewable plan files) |
|
|
196
|
+
|
|
197
|
+
### System
|
|
198
|
+
| Tool | Description |
|
|
199
|
+
|------|-------------|
|
|
200
|
+
| `suppa_health_check` | Health check for stdio clients (config-only or deep connectivity check) |
|
|
201
|
+
|
|
202
|
+
## Authentication
|
|
203
|
+
|
|
204
|
+
The server authenticates with a single bearer token supplied via `SUPPA_API_KEY`:
|
|
205
|
+
|
|
206
|
+
- **User JWT** (account token, e.g. copied from the browser cookie `accessToken`) —
|
|
207
|
+
full access to all domains including Tasks and the `$current-user` magic value.
|
|
208
|
+
- **Integrator API key** — works for Docs, Entities, Forms and Users. Task
|
|
209
|
+
endpoints and `$current-user` may return empty results because they are scoped
|
|
210
|
+
to a real user. Use a user JWT for Task workflows.
|
|
211
|
+
|
|
212
|
+
The token is read only from the environment, sent solely in the `Authorization`
|
|
213
|
+
header to `SUPPA_BASE_URL`, and is **never** exposed to the AI agent.
|
|
214
|
+
|
|
215
|
+
## Development
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Run directly (stdio)
|
|
219
|
+
python -m suppa_mcp
|
|
220
|
+
|
|
221
|
+
# Verify config + connectivity (no client needed)
|
|
222
|
+
python -m suppa_mcp --check
|
|
223
|
+
|
|
224
|
+
# Test with MCP inspector
|
|
225
|
+
mcp dev src/suppa_mcp/server.py
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Auto-start Claude at login (stdio)
|
|
229
|
+
|
|
230
|
+
For Claude Desktop / VS Code, stdio is the preferred model: the MCP client
|
|
231
|
+
spawns this server on demand and reconnects automatically.
|
|
232
|
+
|
|
233
|
+
To make startup reliable, install a login task that runs a preflight health
|
|
234
|
+
check (`suppa-mcp --check`) and then starts Claude if it is not already running.
|
|
235
|
+
|
|
236
|
+
```powershell
|
|
237
|
+
cd suppa2.0-mcp-server
|
|
238
|
+
./scripts/install-claude-startup.ps1 -Python C:\Python314\python.exe
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The installed task (`SuppaClaudeStartup`) runs:
|
|
242
|
+
|
|
243
|
+
- `scripts/start-claude-with-suppa.ps1` at user logon,
|
|
244
|
+
- connectivity check first (fails fast if token/config is invalid),
|
|
245
|
+
- Claude launch only when check passes.
|
|
246
|
+
|
|
247
|
+
Manage it:
|
|
248
|
+
|
|
249
|
+
```powershell
|
|
250
|
+
Start-ScheduledTask -TaskName SuppaClaudeStartup
|
|
251
|
+
Get-ScheduledTask -TaskName SuppaClaudeStartup
|
|
252
|
+
./scripts/uninstall-claude-startup.ps1
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Troubleshooting
|
|
256
|
+
|
|
257
|
+
**`mcp dev` fails with `spawn uv ENOENT`** — the MCP Inspector launches the server
|
|
258
|
+
with [`uv`](https://github.com/astral-sh/uv). Install it and make sure it is on
|
|
259
|
+
your `PATH`, then **restart VS Code** (so the new `PATH` is picked up):
|
|
260
|
+
|
|
261
|
+
```powershell
|
|
262
|
+
python -m pip install uv
|
|
263
|
+
# add the user Scripts dir to PATH if `uv --version` is not found, e.g.
|
|
264
|
+
# %APPDATA%\Python\Python3xx\Scripts
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**`ModuleNotFoundError: No module named 'typing_extensions'` (or `suppa_mcp`)
|
|
268
|
+
when running `mcp dev`** — you have **multiple Python versions** and the `mcp`
|
|
269
|
+
launcher belongs to a different interpreter than the one where `pip install -e .`
|
|
270
|
+
ran. Check with:
|
|
271
|
+
|
|
272
|
+
```powershell
|
|
273
|
+
where.exe python # interpreter that has suppa_mcp installed
|
|
274
|
+
where.exe mcp # the CLI's interpreter — must be the same Python
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Fix by using one interpreter, ideally a project virtual environment:
|
|
278
|
+
|
|
279
|
+
```powershell
|
|
280
|
+
python -m venv .venv
|
|
281
|
+
.\.venv\Scripts\Activate.ps1
|
|
282
|
+
pip install -e .
|
|
283
|
+
mcp dev src/suppa_mcp/server.py
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
> You do **not** need `uv` or `mcp dev` for normal use — MCP clients (VS Code
|
|
287
|
+
> Copilot, Claude, Cursor) launch the server directly via `python -m suppa_mcp`,
|
|
288
|
+
> as configured in `.vscode/mcp.json`. The inspector is only a debugging tool.
|
|
289
|
+
|