@solumflow-app/crm-mcp-server 0.3.1 → 0.4.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 +107 -0
- package/dist/index.js +1022 -203
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @solumflow-app/crm-mcp-server
|
|
2
|
+
|
|
3
|
+
An MCP server that lets an AI agent (Claude Code, Cursor, any MCP client) work
|
|
4
|
+
on a website for one CRM account: place its forms, booking pages, chat and
|
|
5
|
+
tracking script, read its catalogue and events to build pages, and fill the
|
|
6
|
+
catalogue. Every tool is one call of the public API through
|
|
7
|
+
[`@solumflow-app/crm-client`](https://www.npmjs.com/package/@solumflow-app/crm-client);
|
|
8
|
+
the server holds no rules of its own.
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
The quickest way: in the app, open Settings → Integrations → API keys and, in the
|
|
13
|
+
MCP card under the list, tick
|
|
14
|
+
the rights the agent needs and press the button. It makes a key and shows the
|
|
15
|
+
whole command to paste into a terminal.
|
|
16
|
+
|
|
17
|
+
By hand: make a **secret key** (`crms_…`) under Settings → API keys, with the
|
|
18
|
+
scopes the agent needs (see the table below). Then:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
claude mcp add solumflow \
|
|
22
|
+
--env SOLUMFLOW_API_KEY=crms_… \
|
|
23
|
+
--env SOLUMFLOW_API_URL=https://app.example.com \
|
|
24
|
+
-- npx -y @solumflow-app/crm-mcp-server
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Any other MCP client takes the same command and the same two variables:
|
|
28
|
+
|
|
29
|
+
| Variable | |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `SOLUMFLOW_API_KEY` | Required. A secret `crms_` key; a publishable `crmp_` key is refused at start-up. |
|
|
32
|
+
| `SOLUMFLOW_API_URL` | Required. The app's origin, such as `https://app.example.com`, without a path. It is never guessed, so the key cannot be sent to the wrong place. |
|
|
33
|
+
|
|
34
|
+
The server speaks over stdio. Errors go to stderr.
|
|
35
|
+
|
|
36
|
+
## Tools
|
|
37
|
+
|
|
38
|
+
What a key may do is decided by its scopes, on the API's side. A tool whose
|
|
39
|
+
scope the key lacks answers `forbidden` and names the scope it needs.
|
|
40
|
+
|
|
41
|
+
| Tool | Scope | What it does |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| `list_forms` | `website:manage` | Published forms, with their link and embed snippet. |
|
|
44
|
+
| `list_booking_pages` | `website:manage` | Every page a visitor can book on, with its embed snippet. |
|
|
45
|
+
| `list_chat_widgets` | `website:manage` | Chat widgets, the sites each may run on, and the script tag. |
|
|
46
|
+
| `upsert_chat_widget` | `website:manage` | Make or change a chat widget and its allowed sites. |
|
|
47
|
+
| `get_site_tracking` | `website:manage` | The tracking script and the domains it accepts visits from. |
|
|
48
|
+
| `update_site_tracking` | `website:manage` | Add or remove those domains. |
|
|
49
|
+
| `list_catalogs` | `catalog:read` | The product catalogues the key can write to, and their slugs. |
|
|
50
|
+
| `list_catalog_fields` | `catalog:read` | The public custom fields of a catalogue, including how each content block is built. |
|
|
51
|
+
| `list_products` | `catalog:read` | One page of published products, by category or catalogue. |
|
|
52
|
+
| `get_product` | `catalog:read` | One product as its page needs it. |
|
|
53
|
+
| `get_product_availability` | `catalog:read` | Whether a product can be bought now, live. |
|
|
54
|
+
| `list_categories` | `catalog:read` | The category tree, with product counts. |
|
|
55
|
+
| `get_category` | `catalog:read` | One category page and a page of its products. |
|
|
56
|
+
| `read_configurator` | `catalog:read` | A product's 3D configurator document. |
|
|
57
|
+
| `check_configurator_shape` | none | Check a configurator structure or shape the way the app does, without saving it. |
|
|
58
|
+
| `list_events` | `events:read` | Published events in a window, with their ticket page. |
|
|
59
|
+
| `get_event` | `events:read` | One event, with ticket types and prices. |
|
|
60
|
+
| `get_event_availability` | `events:read` | Seats left, live. |
|
|
61
|
+
| `upsert_product` | `catalog:write` | Make or change a product, known by `source` + `externalRef`. |
|
|
62
|
+
| `archive_product` | `catalog:write` | Take a product off the website and out of the shop. |
|
|
63
|
+
| `upsert_category` | `catalog:write` | Make or change a category, known by its slug. |
|
|
64
|
+
| `upsert_field` | `catalog:write` | Make or change a custom field: text, number, select, checkbox, url, date, or a content block (text block, call to action, repeater) with its settings. |
|
|
65
|
+
| `upsert_catalog` | `catalog:write` | Make or rename a product catalogue of its own, such as "Fireplaces". |
|
|
66
|
+
| `upsert_configurator` | `catalog:write`, and `configurator:shape` for a new one or a new shape | Save a 3D configurator, checked first; nothing is sent while it has a problem. |
|
|
67
|
+
| `upload_configurator_file` | `configurator:shape` for a model, `catalog:write` for a texture | Upload a `.glb` model or a `.webp`/`.jpg` texture from disk and get the path the structure names. |
|
|
68
|
+
|
|
69
|
+
Every catalogue tool takes an optional `object`: the slug of another catalogue
|
|
70
|
+
of the account (from `list_catalogs`). Left out, it is the account's own.
|
|
71
|
+
|
|
72
|
+
## Writing the catalogue
|
|
73
|
+
|
|
74
|
+
The write tools change a customer's live catalogue, so it helps to know what the
|
|
75
|
+
API does with them:
|
|
76
|
+
|
|
77
|
+
- **A product's identity is `source` + `externalRef`**: the name of the system it
|
|
78
|
+
comes from and its id there. Sending the same pair again changes the product
|
|
79
|
+
instead of making a second one.
|
|
80
|
+
- **A new product is a draft** unless `availability` says otherwise.
|
|
81
|
+
- **Left out means "leave it"; `null` empties a field.** But `prices`,
|
|
82
|
+
`categories`, `images` and `variants` each replace what the product had as a
|
|
83
|
+
whole, and a variant left out is archived.
|
|
84
|
+
- **Typos do not become data.** A category or a select choice that does not
|
|
85
|
+
exist is refused, unless `createMissingCategories` or `addMissingOptions` asks
|
|
86
|
+
for it.
|
|
87
|
+
- **Archiving keeps the product** for the invoices that name it;
|
|
88
|
+
`upsert_product` with `archived: false` brings it back.
|
|
89
|
+
|
|
90
|
+
The input schemas are the API's own, so an agent is told the same limits the
|
|
91
|
+
routes enforce.
|
|
92
|
+
|
|
93
|
+
## A configurator's shape
|
|
94
|
+
|
|
95
|
+
A configurator's shape (its `geometry`) and its models are a reseller's work.
|
|
96
|
+
Making a configurator, changing its shape or uploading a model needs the
|
|
97
|
+
`configurator:shape` scope, and only somebody who may shape configurators in
|
|
98
|
+
that account -- the reseller who sold it, or the platform -- can give a key
|
|
99
|
+
that scope. It also stops working the moment that person no longer may.
|
|
100
|
+
Everything around the shape (parameters, lists, materials, prices, rules,
|
|
101
|
+
textures) needs only `catalog:write`.
|
|
102
|
+
|
|
103
|
+
## On a React or Next.js site
|
|
104
|
+
|
|
105
|
+
Prefer the components in `@solumflow-app/crm-client/react` (`CrmForm`,
|
|
106
|
+
`CrmBooking`, `CrmChatWidget`, `CrmSiteTracking`) to pasting the HTML snippets
|
|
107
|
+
the tools return.
|