appilot-mcp 0.2.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/LICENSE +15 -0
- package/README.md +133 -27
- package/dist/appilot-configurator.mcpb +0 -0
- package/dist/cli.d.ts +34 -0
- package/dist/cli.js +173 -0
- package/dist/client.d.ts +45 -1
- package/dist/client.js +74 -1
- package/dist/config.d.ts +21 -0
- package/dist/config.js +6 -0
- package/dist/contract/healthContract.js +31 -4
- package/dist/index.bundle.js +2111 -826
- package/dist/index.d.ts +7 -1
- package/dist/index.js +22 -4
- package/dist/manifest.d.ts +14 -2
- package/dist/manifest.js +31 -9
- package/dist/public-marketplace/.claude-plugin/marketplace.json +20 -0
- package/dist/public-marketplace/README.md +23 -0
- package/dist/public-marketplace/plugins/app-configurator/.claude-plugin/plugin.json +43 -0
- package/dist/public-marketplace/plugins/app-configurator/README.md +328 -0
- package/dist/public-marketplace/plugins/app-configurator/dist/index.bundle.js +57370 -0
- package/dist/public-marketplace/plugins/app-configurator/skills/app-configurator/SKILL.md +267 -0
- package/dist/public-marketplace/plugins/app-configurator/skills/app-configurator/agents/openai.yaml +13 -0
- package/dist/redaction.d.ts +51 -0
- package/dist/redaction.js +59 -0
- package/dist/remote/consent.d.ts +10 -2
- package/dist/remote/consent.js +16 -6
- package/dist/remote/consentMessages.d.ts +6 -1
- package/dist/remote/consentMessages.js +15 -6
- package/dist/remote/httpServer.d.ts +10 -0
- package/dist/remote/httpServer.js +126 -40
- package/dist/remote/oauth.d.ts +10 -1
- package/dist/remote/oauth.js +29 -11
- package/dist/scaffold.d.ts +68 -6
- package/dist/scaffold.js +424 -97
- package/dist/server.js +175 -18
- package/dist/userClient.d.ts +213 -0
- package/dist/userClient.js +400 -0
- package/dist/userServer.d.ts +47 -0
- package/dist/userServer.js +248 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/examples/app.appilot.json +212 -0
- package/mcpb/manifest.json +117 -21
- package/package.json +5 -3
- package/skills/app-configurator/SKILL.md +61 -19
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appilot-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Appilot MCP server: read, validate
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Appilot MCP server: provision an Appilot app, scaffold and verify the host integration, then read, validate and fix its content-model configuration against the config health contract. Endpoint-agnostic (cloud or on-premise), scoped-service-token auth, local static gate + optional live DOM soak.",
|
|
5
5
|
"homepage": "https://appilot.space",
|
|
6
6
|
"author": "BetterKnow GmbH",
|
|
7
7
|
"keywords": [
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"dist",
|
|
26
26
|
"skills",
|
|
27
|
+
"examples",
|
|
27
28
|
"mcpb",
|
|
28
29
|
".mcp.json",
|
|
29
30
|
".codex-plugin",
|
|
@@ -66,6 +67,7 @@
|
|
|
66
67
|
"test": "vitest run",
|
|
67
68
|
"test:watch": "vitest",
|
|
68
69
|
"start:http": "node dist/index.bundle.js --http",
|
|
69
|
-
"build:mcpb": "node scripts/build-mcpb.mjs"
|
|
70
|
+
"build:mcpb": "node scripts/build-mcpb.mjs",
|
|
71
|
+
"build:marketplace": "node scripts/build-public-marketplace.mjs"
|
|
70
72
|
}
|
|
71
73
|
}
|
|
@@ -18,7 +18,9 @@ well-formed configuration; every rule maps to a real failure mode.
|
|
|
18
18
|
- **Connected (Appilot MCP server available).** `capabilities`, `read_config` and
|
|
19
19
|
`validate_config` read and audit. `entity_template`, `create_entity`,
|
|
20
20
|
`update_entity`, `delete_entity` and `validate_action_plan` author, across all
|
|
21
|
-
eight entity kinds. `
|
|
21
|
+
eight entity kinds. `whoami`, `list_apps`, `list_widget_keys`, `create_app`,
|
|
22
|
+
`verify_domain`, `scaffold_integration` and `integration_snippet` set an app up
|
|
23
|
+
from nothing. `inspect_page` looks at the screen. `export_config` /
|
|
22
24
|
`import_config` back up, clone and promote. `soak_selectors` and
|
|
23
25
|
`verify_integration` prove it works on the real page. Prefer this mode. Always
|
|
24
26
|
start with `capabilities` so you configure against what THIS instance supports
|
|
@@ -39,25 +41,52 @@ runs in the customer's own repository, where you already are.
|
|
|
39
41
|
1. **`whoami`.** Which org does this credential reach, and which scopes does it
|
|
40
42
|
hold? A mistyped or revoked token should fail here, not as an opaque 401
|
|
41
43
|
halfway through. Provisioning needs `provision:write`, minted in the
|
|
42
|
-
Backoffice under
|
|
44
|
+
Backoffice under Service tokens with the preset called **Set up
|
|
45
|
+
integrations**. Only an organization administrator can mint it, so a
|
|
46
|
+
configurator who is not one has to ask for it rather than work around it.
|
|
47
|
+
`list_apps` then answers what already exists, and `list_widget_keys` answers
|
|
48
|
+
which keys were already minted, so a re-run recognises them instead of asking
|
|
49
|
+
for more.
|
|
43
50
|
2. **`create_app`** with the app name and the domains it runs on. Idempotent, so
|
|
44
51
|
a re-run converges rather than creating a second app. It returns the script
|
|
45
52
|
tag, the boot snippet, and (once, at creation) the widget key and its secret.
|
|
46
53
|
A **live** key needs a verified domain: on a hostname nobody has proved they
|
|
47
54
|
control, the key comes back `blocked` with the TXT record to publish, while
|
|
48
|
-
the app and its domains are created anyway. Publish the record
|
|
49
|
-
pass `isTest` for a test key that
|
|
55
|
+
the app and its domains are created anyway. Publish the record, then
|
|
56
|
+
`verify_domain` with `trigger`, or pass `isTest: true` for a test key that
|
|
57
|
+
claims nothing. The parameter is `isTest`, the same name the manifest and the
|
|
58
|
+
API use.
|
|
50
59
|
The **key** is publishable and belongs in the page. The **secret** is not: it
|
|
51
60
|
goes in the host's backend environment and must never reach a browser or a
|
|
52
61
|
client bundle. If you are connected over the remote transport the secret is
|
|
53
62
|
withheld on purpose; point the user at the Backoffice for it.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
|
|
64
|
+
**Working on the user's own machine.** There are two answers and they are not
|
|
65
|
+
equal. Preferred: have them run the app on a hostname that resolves to
|
|
66
|
+
127.0.0.1 (`myapp.lvh.me:3000`, or an `/etc/hosts` entry) and register THAT
|
|
67
|
+
hostname as a domain. The page then resolves its tenant by hostname, no widget
|
|
68
|
+
key is needed, verification is not required for that path, and the turn gets
|
|
69
|
+
the full app context: views, controls, forms, plans, knowledge. Fallback:
|
|
70
|
+
bare `localhost` with a `wk_test_` key, which gets the organization and the
|
|
71
|
+
user and NO app context, because no domain resolves. Never pass `localhost` or
|
|
72
|
+
`127.0.0.1` as a domain: they name every developer's machine, one row for the
|
|
73
|
+
whole platform, and the write is refused.
|
|
74
|
+
3. **`scaffold_integration`** for the host's framework, or `other` when the
|
|
75
|
+
backend is not Node (Django, Rails, PHP), which returns the raw exchange
|
|
76
|
+
instead. It returns file CONTENTS, which you write into the repository. The
|
|
77
|
+
identity relay is the piece that matters: `resolveUser` is the security
|
|
78
|
+
boundary and must derive the user from a credential the host already trusts,
|
|
79
|
+
never from the request body. The boot file reads the publishable key from the
|
|
80
|
+
framework's public variable (`NEXT_PUBLIC_APPILOT_WIDGET_KEY`,
|
|
81
|
+
`VITE_APPILOT_WIDGET_KEY`, `PUBLIC_APPILOT_WIDGET_KEY`); do not replace that
|
|
82
|
+
with a literal. `integration_snippet` returns the same two snippets later, for
|
|
83
|
+
an app that already exists, without a provisioning write.
|
|
58
84
|
4. **Make one capability agent-operable** before adding screens' worth of
|
|
59
85
|
configuration. The test for agent-first is whether a user could complete the
|
|
60
|
-
feature end to end through the assistant alone.
|
|
86
|
+
feature end to end through the assistant alone. `scaffold_agent_first` takes a
|
|
87
|
+
`shape`: `create` for an open/fill/submit flow, `navigate` for one step to a
|
|
88
|
+
screen, and `read` for a capability the agent answers, which gets no action
|
|
89
|
+
plan at all.
|
|
61
90
|
5. **`verify_integration`** against the running page. It answers what is actually
|
|
62
91
|
true: does the domain resolve to a tenant, does the relay refuse an
|
|
63
92
|
unauthenticated caller correctly, does the widget boot, is the console clean.
|
|
@@ -65,12 +94,23 @@ runs in the customer's own repository, where you already are.
|
|
|
65
94
|
6. Then configure the content model, below, and `validate_config`.
|
|
66
95
|
|
|
67
96
|
**A whole tenant as one file.** `plan_manifest` / `apply_manifest` take an
|
|
68
|
-
`appilot.app-manifest`: the app, its domains, its keys, and a ConfigBundle.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
97
|
+
`appilot.app-manifest`: the app, its domains, its keys, and a ConfigBundle. A
|
|
98
|
+
complete example ships with the server at `examples/app.appilot.json`; copy it
|
|
99
|
+
rather than assembling one from doc snippets. Keep it in the repository under
|
|
100
|
+
version control, so configuration is diffable in a pull request and promotable
|
|
101
|
+
from staging to production. `apply_manifest` requires the `planToken` that
|
|
102
|
+
`plan_manifest` returned for the same file, so you cannot apply something nobody
|
|
103
|
+
previewed, and an edit between the two calls fails rather than committing
|
|
104
|
+
silently.
|
|
105
|
+
|
|
106
|
+
Two things about an apply are worth saying out loud. Only the CONFIG half is
|
|
107
|
+
revisioned: every commit persists a `pre_restore` revision, so a wrong import is
|
|
108
|
+
undone by restoring it, while a domain or a key the provisioning half created is
|
|
109
|
+
undone by hand. And provisioning is asked for by the manifest, not by the tool:
|
|
110
|
+
an apply whose app, domains and keys already exist needs only `config:write`,
|
|
111
|
+
which is what lets a CI token keep content in sync without being able to claim
|
|
112
|
+
domains. Outside an MCP client, `appilot-mcp plan <file>` and
|
|
113
|
+
`appilot-mcp apply <file>` are the same two calls from a shell.
|
|
74
114
|
|
|
75
115
|
## The content model (what you configure)
|
|
76
116
|
|
|
@@ -239,10 +279,12 @@ file is safe to save, commit, or share. `read_config` stays the reasoning view;
|
|
|
239
279
|
## Guardrails
|
|
240
280
|
|
|
241
281
|
- Confirm before writing. Show the diff you intend to apply; get a yes.
|
|
242
|
-
- Writing needs a `config:write` service token; reading
|
|
243
|
-
`config:read`; provisioning needs `provision:write`. If a call
|
|
244
|
-
|
|
245
|
-
|
|
282
|
+
- Writing needs a `config:write` service token; reading and validating need only
|
|
283
|
+
`config:read`; provisioning needs `provision:write`. If a call is refused on
|
|
284
|
+
scope, say which scope is missing and who grants it: `provision:write` comes
|
|
285
|
+
from an organization administrator in the Backoffice, under Service tokens
|
|
286
|
+
with the "Set up integrations" preset, or from the account approval screen. Do
|
|
287
|
+
not work around it.
|
|
246
288
|
- **Never put a widget secret in a file that ships to the browser.** It goes in
|
|
247
289
|
the server environment: no `NEXT_PUBLIC_` prefix, no `VITE_`, no committed
|
|
248
290
|
`.env`. The publishable key is different and belongs in the page.
|