@aquera/mcp-ui-render 0.0.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.
- package/CHANGELOG.md +437 -0
- package/CONFIGURATION.md +178 -0
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/RELEASE-NOTES.md +77 -0
- package/TEST-PLAN.md +72 -0
- package/USAGE.md +100 -0
- package/package.json +52 -0
- package/src/controls.d.ts +1 -0
- package/src/controls.js +572 -0
- package/src/controls.js.map +1 -0
- package/src/elements/aq-mcp-config.d.ts +289 -0
- package/src/elements/aq-mcp-config.js +673 -0
- package/src/elements/aq-mcp-config.js.map +1 -0
- package/src/elements/aq-mcp-field.d.ts +92 -0
- package/src/elements/aq-mcp-field.js +275 -0
- package/src/elements/aq-mcp-field.js.map +1 -0
- package/src/elements/aq-mcp-section.d.ts +101 -0
- package/src/elements/aq-mcp-section.js +261 -0
- package/src/elements/aq-mcp-section.js.map +1 -0
- package/src/engine/status.d.ts +31 -0
- package/src/engine/status.js +44 -0
- package/src/engine/status.js.map +1 -0
- package/src/engine/submit.d.ts +26 -0
- package/src/engine/submit.js +37 -0
- package/src/engine/submit.js.map +1 -0
- package/src/engine/validate.d.ts +24 -0
- package/src/engine/validate.js +144 -0
- package/src/engine/validate.js.map +1 -0
- package/src/engine/values.d.ts +20 -0
- package/src/engine/values.js +42 -0
- package/src/engine/values.js.map +1 -0
- package/src/index.d.ts +18 -0
- package/src/index.js +20 -0
- package/src/index.js.map +1 -0
- package/src/mcp-ui-render.css +811 -0
- package/src/registry.d.ts +63 -0
- package/src/registry.js +39 -0
- package/src/registry.js.map +1 -0
- package/src/types.d.ts +239 -0
- package/src/types.js +8 -0
- package/src/types.js.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aquera Inc.
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# @aquera/mcp-ui-render
|
|
2
|
+
|
|
3
|
+
Framework-agnostic **Lit 3** web components that render a `bootstrap` tenant-configuration
|
|
4
|
+
descriptor (see `kb/specs/SPEC-mcp-ui-render.md` and the descriptor contract) using **Nile**.
|
|
5
|
+
Renders identically in Angular (`CUSTOM_ELEMENTS_SCHEMA`), React, or a plain HTML page: no
|
|
6
|
+
framework runtime dependency, no per-connector hand-built form.
|
|
7
|
+
|
|
8
|
+
- **Pure renderer.** No network I/O, holds no secrets. It renders, validates, and emits
|
|
9
|
+
intent (`aq-mcp-change` / `aq-mcp-submit` / `aq-mcp-action`); the host executes tools.
|
|
10
|
+
- **Nile is a peer dependency.** The host provides and registers `@aquera/nile-elements`.
|
|
11
|
+
- **Published to public npm** as `@aquera/mcp-ui-render`, MIT-licensed, alongside the other
|
|
12
|
+
`@aquera` packages. Development happened against the private Verdaccio registry; the public
|
|
13
|
+
line starts at `0.0.1` (D-6b's promotion step — see `RELEASE-NOTES.md`).
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @aquera/mcp-ui-render
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Requires the host to also install and register Nile:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @aquera/nile-elements @aquera/nile @aquera/nile-glyph
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<script type="module">
|
|
31
|
+
import '@aquera/nile-elements'; // host registers Nile once
|
|
32
|
+
import '@aquera/mcp-ui-render/styles.css'; // required — the elements render into light DOM (see USAGE.md)
|
|
33
|
+
import '@aquera/mcp-ui-render';
|
|
34
|
+
const el = document.querySelector('aq-mcp-config');
|
|
35
|
+
el.descriptor = await callBootstrapTool(); // the bootstrap tool result
|
|
36
|
+
el.values = currentValues;
|
|
37
|
+
el.addEventListener('aq-mcp-submit', (e) => host.save(e.detail));
|
|
38
|
+
el.addEventListener('aq-mcp-action', (e) => host.callTool(e.detail.tool, e.detail.args));
|
|
39
|
+
</script>
|
|
40
|
+
<aq-mcp-config></aq-mcp-config>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
See [`USAGE.md`](./USAGE.md) for the Angular / React / plain-HTML integration guides and the
|
|
44
|
+
full event contract, [`CONFIGURATION.md`](./CONFIGURATION.md) for every property, method, event,
|
|
45
|
+
and extensibility hook on `<aq-mcp-config>` / `<aq-mcp-section>` / `<aq-mcp-field>`, and
|
|
46
|
+
[`TEST-PLAN.md`](./TEST-PLAN.md) for how the descriptor contract's §15 conformance checklist maps
|
|
47
|
+
to test coverage.
|
|
48
|
+
|
|
49
|
+
Or open [`REFERENCE.html`](./REFERENCE.html) directly in a browser — a single self-contained page
|
|
50
|
+
covering all of the above (getting started, the descriptor contract, every built-in control,
|
|
51
|
+
validation/dependency/secret rules, the four customization levers, the full API surface, and
|
|
52
|
+
worked examples pulled from real descriptors) in one place, with no build step.
|
|
53
|
+
|
|
54
|
+
## Rendering a single `ui-component`, without a descriptor
|
|
55
|
+
|
|
56
|
+
Sometimes a host just wants one control's output (e.g. a `test-connection-report` result)
|
|
57
|
+
dropped into some div, not the whole `bootstrap` form. Two ways, no full descriptor/section
|
|
58
|
+
required:
|
|
59
|
+
|
|
60
|
+
**`<aq-mcp-field>` on its own** (recommended): it's an independent custom element, not tied to
|
|
61
|
+
`<aq-mcp-config>`. It only ever needs a minimal `field` object plus a `value`:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<aq-mcp-field></aq-mcp-field>
|
|
65
|
+
<script type="module">
|
|
66
|
+
import '@aquera/mcp-ui-render';
|
|
67
|
+
const el = document.querySelector('aq-mcp-field');
|
|
68
|
+
el.field = { attribute: 'connectionTest', datatype: 'none', 'ui-component': 'test-connection-report' };
|
|
69
|
+
el.value = theReportJson; // whatever value shape that ui-component expects
|
|
70
|
+
</script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This still renders `<aq-mcp-field>`'s own two-column row (a label column + the control), so it
|
|
74
|
+
reads as a form-field row rather than a bare block; override `.aq-mcp-field` in
|
|
75
|
+
`mcp-ui-render.css` if that layout isn't wanted. See `apps/mcp-render-demo`'s "Standalone
|
|
76
|
+
`<aq-mcp-field>`" section for a working example.
|
|
77
|
+
|
|
78
|
+
**Bypass the element entirely** with the registry, for the truly bare markup with no wrapper:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { resolveControl } from '@aquera/mcp-ui-render';
|
|
82
|
+
import { render } from 'lit';
|
|
83
|
+
|
|
84
|
+
const renderer = resolveControl('test-connection-report');
|
|
85
|
+
render(renderer({ field: theField, value: theReportJson, error: null, onInput: () => {} }), document.querySelector('#myDiv'));
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This needs the host to import Lit's own `render()`, so it fits better when the host is already
|
|
89
|
+
Lit-based; `<aq-mcp-field>` is the simpler choice for any other framework or plain HTML.
|
|
90
|
+
|
|
91
|
+
## What it does
|
|
92
|
+
|
|
93
|
+
- **Renders a `bootstrap` descriptor**: ordered sections of ordered fields, two-column layout,
|
|
94
|
+
with no per-connector code (`<aq-mcp-config>` → `<aq-mcp-section>` → `<aq-mcp-field>`).
|
|
95
|
+
- **Eleven default controls**, each a Nile element (`properties-table` is the one exception — a
|
|
96
|
+
plain semantic `<table>`, since Nile has no read-only data-table primitive this use case
|
|
97
|
+
needs): `input`, `textarea`, `password`, `select` (+ multi-select for `array`), `radio`,
|
|
98
|
+
`checkbox`, `button`, `file`, `test-connection-report`, `properties-table`, and
|
|
99
|
+
`permissions-report`. An **extensible component registry**
|
|
100
|
+
(`registerControl`) lets a host add or override a `ui-component` without touching the engine;
|
|
101
|
+
an unknown `ui-component` always falls back to the field's datatype default (never dropped).
|
|
102
|
+
`select`/`radio` `options` accept a plain primitive (`value === display text`) or
|
|
103
|
+
`{ value, label }` (`0.5.0`) when the submitted code and its human-readable name differ.
|
|
104
|
+
- **Validation engine.** Compiles each field's `validation` regexes (whole-value, AND-combined),
|
|
105
|
+
applies `isRequired`/`min`/`max`, and pushes the result into the Nile control's own
|
|
106
|
+
`error`/`errorMessage` props; a non-compiling regex logs and never blocks the user. A `file`
|
|
107
|
+
field's `accept`/`maxSizeKB` checks run the same way — **client-side only, advisory**: this is
|
|
108
|
+
a pure renderer with no network I/O, so a connector must still enforce file type/size
|
|
109
|
+
server-side; the UI check is a fast first pass, not the real gate.
|
|
110
|
+
- **Secrets & hidden fields.** Hidden fields render nothing but round-trip unchanged on submit;
|
|
111
|
+
`secret`/`password` fields are masked and never prefilled; `writeOnce` fields render as
|
|
112
|
+
"Replace" and omit from submit unless the user actually enters a new value
|
|
113
|
+
(`WRITE_ONCE_UNCHANGED` sentinel).
|
|
114
|
+
- **Accessible labels.** `input`/`textarea`/`password`/`select` (`0.4.1`) and `radio` (`0.5.0`)
|
|
115
|
+
are given a real, natively associated accessible name — the visible label lives in
|
|
116
|
+
`<aq-mcp-field>`'s own left column, but each control also gets it via Nile's own `label`
|
|
117
|
+
property, with Nile's internal label visually hidden so nothing shows twice. **Known gap:** `checkbox`
|
|
118
|
+
(`nile-slide-toggle`) has no equivalent wiring in Nile itself — its internal checkbox
|
|
119
|
+
isn't `for`/`aria-labelledby`-associated with its `label` at all; not fixable from this
|
|
120
|
+
library's side.
|
|
121
|
+
- **Submit / save-target resolution.** Collects values keyed by `attribute` for the fields that
|
|
122
|
+
applied, resolves each section's save target (its own `submitTool` vs the platform default),
|
|
123
|
+
and emits the payload; it never calls the tool itself.
|
|
124
|
+
- **Dynamic `select`/`radio` options** (`0.5.0`, §9.6). A field with `tool` set and no options
|
|
125
|
+
yet emits `aq-mcp-options-request` once it's applicable — the host calls the tool and feeds
|
|
126
|
+
the result back via `dynamicOptions`, still without this library ever touching the network
|
|
127
|
+
itself (D-4). Pending-a-fetch and a genuine "no options, no way to get any" defect render
|
|
128
|
+
the same (disabled) but only the latter logs the §15 warning.
|
|
129
|
+
- **`properties-table` — a read-only Property/Value summary** (`0.5.0`, `datatype: "none"`,
|
|
130
|
+
never validated/submitted, same contract as `test-connection-report`). For surfacing a
|
|
131
|
+
handful of attributes' current values — typically read-only/hidden tenant attributes that
|
|
132
|
+
matter to see but shouldn't be directly editable fields — without duplicating them as
|
|
133
|
+
disabled form controls. Rows (`PropertiesTableRow[]`) come from either `field.rows` (static,
|
|
134
|
+
declared in the descriptor — the connector already knows the data) or `values[attribute]`
|
|
135
|
+
(dynamic, host-computed at render time — wins if both are present, same priority
|
|
136
|
+
`dynamicOptions` has over `options` for `select`/`radio`). The control formats
|
|
137
|
+
booleans/arrays/plain objects (JSON-stringified)/`null` and truncates long values and
|
|
138
|
+
property names (full text still in each cell's `title`).
|
|
139
|
+
- **Compound field dependency** (`0.5.0`, §12). `Field.dependsOn?: { attribute: string; value:
|
|
140
|
+
string | string[] }[]` — alongside the existing single-attribute
|
|
141
|
+
`dependencyAttribute`/`dependencyValue` — for a field relevant when EITHER of two different
|
|
142
|
+
attributes hits a value (e.g. an FTP-server picker relevant under a direct-connection mode OR
|
|
143
|
+
under an SFTP storage mode, two unrelated fields). Every condition is OR'd together; `[]` or
|
|
144
|
+
omitted behaves as no dependency at all, same as before this addition.
|
|
145
|
+
- **Collapsible field help** (`0.5.0`). `field.help` over 100 characters renders truncated with
|
|
146
|
+
a "View more"/"View less" toggle instead of always showing in full — purely a
|
|
147
|
+
`<aq-mcp-field>` presentation detail, no model change.
|
|
148
|
+
- **`Field.actions` — a multi-action toolbar** (`0.5.0`, §5). `properties-table` uses this to
|
|
149
|
+
render its own card header — title/subtitle from `field.label`/`field.help`, plus a
|
|
150
|
+
right-aligned toolbar of independently-wired buttons (an `icon`-bearing entry renders
|
|
151
|
+
icon-only via `nile-icon-button`; without `icon`, a labeled `nile-button`) — matching the live
|
|
152
|
+
reference's "Generated Configuration" card (a download button + "Edit Configuration"). Each
|
|
153
|
+
entry has its own `tool`/`args`/`confirm`; `aq-mcp-action`'s detail includes which `action`
|
|
154
|
+
fired. `properties-table` is consequently a full-width control (spans the whole field row)
|
|
155
|
+
rather than the usual two-column label/control split — its label still always renders, now in
|
|
156
|
+
its own header instead of `<aq-mcp-field>`'s left column. This icon-vs-label rendering is the
|
|
157
|
+
DEFAULT only — a host wanting different toolbar UI overrides `properties-table` entirely via
|
|
158
|
+
`registerControl` (below), the same escape hatch every other built-in control already has.
|
|
159
|
+
- **`permissions-report` — a scope/permission GRANT table** (`0.5.0`, `datatype: "none"`, never
|
|
160
|
+
validated/submitted). Distinct from `test-connection-report` (that one models PASS/FAIL
|
|
161
|
+
endpoint probes): this renders a validation banner (success/error from `report.valid`) plus a
|
|
162
|
+
"Validation Report" — a running "N Granted" count (always derived from the current `grants`
|
|
163
|
+
array, never a separately-suppliable number) and an All/Success filter, then a Resource
|
|
164
|
+
Type/Permission Type/Access table — matching the live reference's own "Credentials" tab Test
|
|
165
|
+
Connection result exactly. The filter is pure CSS (native radio inputs + a general-sibling
|
|
166
|
+
rule), no Lit reactive state.
|
|
167
|
+
- **Per-section footer customization** (`registerSectionFooter`): a host can replace a
|
|
168
|
+
section's default "Save `<label>`" button with custom markup, keyed by `section.key`. Absent
|
|
169
|
+
a registration, the library's default footer renders unchanged.
|
|
170
|
+
- **Host-driven validation & footer control.** `AqMcpConfig.validateAll()` lets a host bypass
|
|
171
|
+
per-section footers entirely and validate the whole form itself, still getting the library's
|
|
172
|
+
real inline field errors; `showSectionFooters`/`showFooter` hide every footer (default or
|
|
173
|
+
custom) at once. Every edit is also live-validated as it happens, not just on submit.
|
|
174
|
+
- **Configurable section layout.** `sectionsLayout: 'stacked' | 'tabs' | 'accordion'` (default
|
|
175
|
+
`'stacked'`) switches between one-card-per-section, a Nile nav-tab arrangement (`tabsPlacement`
|
|
176
|
+
for horizontal/vertical, `tabsShowErrorIndicator` for a per-tab error dot), and a single-open
|
|
177
|
+
`nile-accordion` stack whose cards tint their edge when a section still has a required field
|
|
178
|
+
empty, so a collapsed section says it needs attention (`accordionOpenSection`,
|
|
179
|
+
`accordionShowFooters`, `accordionColumns` for one- or two-column fields). Validation and submit behave identically in every layout. See [`CONFIGURATION.md`](./CONFIGURATION.md).
|
|
180
|
+
- **Extensibility by construction.** Unknown datatype is treated as `string` (+ warn if
|
|
181
|
+
required); unknown section/field keys are preserved on round-trip; a descriptor `version` MAJOR
|
|
182
|
+
ahead of what the library understands renders best-effort plus a notice, switching on MAJOR only.
|
|
183
|
+
|
|
184
|
+
## Public API (`index.ts`)
|
|
185
|
+
|
|
186
|
+
| Export | What |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `AqMcpConfig`, `AqMcpSection`, `AqMcpField` | the custom element classes (`aq-mcp-config`, `aq-mcp-section`, `aq-mcp-field`) |
|
|
189
|
+
| `Descriptor`, `Section`, `Field`, `FieldAction`, `Values`, `Datatype`, `AuthType` | descriptor type model |
|
|
190
|
+
| `registerControl` / `resolveControl` / `ControlContext` / `ControlRenderer` | the `ui-component` registry |
|
|
191
|
+
| `registerSectionFooter` / `resolveSectionFooter` / `SectionFooterContext` / `SectionFooterRenderer` | the per-section footer registry |
|
|
192
|
+
| `validateField` | the validation engine, standalone |
|
|
193
|
+
| `collectSubmit`, `sectionHasEditableFields`, `WRITE_ONCE_UNCHANGED`, `SubmitPayload` | submit assembly + save-target resolution |
|
|
194
|
+
| `fieldApplies`, `seedDefaults`, `asArray` | dependency/default-seeding helpers |
|
|
195
|
+
| `sectionStatus`, `SectionStatus`, `isEmpty` | section-completeness engine behind the accordion's attention state, standalone |
|
|
196
|
+
|
|
197
|
+
## Status
|
|
198
|
+
|
|
199
|
+
Current version in this repo: **`0.0.1`** — the **first public npm release** (`npm view
|
|
200
|
+
@aquera/mcp-ui-render`). It is the same code as the internal `0.6.0` Verdaccio build, renumbered
|
|
201
|
+
for a registry that has never held this package; `RELEASE-NOTES.md` is the published record and
|
|
202
|
+
`CHANGELOG.md` is the pre-npm history. A `^0.6.0` range will not resolve on npm — pin `0.0.1`.
|
|
203
|
+
|
|
204
|
+
The feature history below is written against the Verdaccio version numbers it happened under, and
|
|
205
|
+
is kept because it explains *why* each behaviour is the way it is. `0.6.0` adds the `sectionsLayout: 'accordion'` layout — a single-open stack of `nile-accordion`
|
|
206
|
+
cards with a label-above-control body in one or two columns (`accordionColumns`) and each field's
|
|
207
|
+
`help` as hint text beneath it, where a card whose section still has a required field empty tints
|
|
208
|
+
its edge so it is findable while collapsed. `0.5.5` gave `datatype: "object"` a real editable
|
|
209
|
+
control:
|
|
210
|
+
`input`/`textarea` previously rendered an object value as the literal text `"[object Object]"`;
|
|
211
|
+
both now pretty-print it as editable JSON and parse typed text back into a real object, keeping
|
|
212
|
+
the raw text as an interim value (never throwing, never corrupting the display) while the JSON is
|
|
213
|
+
mid-typing and not yet valid. `object`'s default `ui-component` also changed from `input` to
|
|
214
|
+
`textarea`. See `CHANGELOG.md` for the full writeup. See
|
|
215
|
+
[`CHANGELOG.md`](./CHANGELOG.md) for the full version history and
|
|
216
|
+
[`CONFIGURATION.md`](./CONFIGURATION.md) for the full property/method/event reference.
|
|
217
|
+
|
|
218
|
+
Built and tested (all of it, via `nx test mcp-ui-render` / `nx test-browser mcp-ui-render`):
|
|
219
|
+
descriptor rendering, the control registry, validation, secrets/submit behaviour, the §15
|
|
220
|
+
conformance suite, per-section footer customization, host-driven validation (`validateAll()`,
|
|
221
|
+
`showSectionFooters`) and live on-change validation (`0.3.0`), the `sectionsLayout: 'tabs'`
|
|
222
|
+
layout (`0.4.0`), the `sectionsLayout: 'accordion'` layout and its `sectionStatus` engine
|
|
223
|
+
(`0.6.0`), and every `0.5.0` feature listed above — including two display fixes: a
|
|
224
|
+
`test-connection-report`/`permissions-report` field with no value yet now renders nothing at all
|
|
225
|
+
(not even its own label, previously left dangling next to blank space), and a `file` field's
|
|
226
|
+
upload hint is derived from its own `accept`/`maxSizeKB` instead of always showing
|
|
227
|
+
`nile-file-upload`'s hardcoded image-upload default. Every feature past `0.2.0` is filed as a
|
|
228
|
+
DRAFT amendment (A through J) in `kb/specs/SPEC-mcp-ui-render.md`, pending Hanu/Ahi ratification
|
|
229
|
+
— already built and shipped, per this spec's own established pattern of documenting after build.
|
|
230
|
+
|
|
231
|
+
The MCP-App (`ext-apps`) delivery mode **is built**, in the `mcp-gateway` app, not a separate
|
|
232
|
+
`mcp-engine` repo: `servers/mcp-gateway-service/apps/mcp-gateway/src/mcp-apps/ui/src/mcp-ui-render-app.js`
|
|
233
|
+
(a vanilla-JS single-file entry using `@modelcontextprotocol/ext-apps`'s core `App` class) plus
|
|
234
|
+
server-side `bootstrap`/`credential_test`/`saveConnectorConfig` tool stubs. Not yet done: adding
|
|
235
|
+
`bootstrap` to the per-appType S3 tool allowlist for any real tenant, and end-to-end verification
|
|
236
|
+
against a real MCP client. See "MCP delivery" in `kb/specs/SPEC-mcp-ui-render.md` and the
|
|
237
|
+
2026-08-01 entry in `kb/QA-QUEUE.md` for the full detail.
|
package/RELEASE-NOTES.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Release notes — `@aquera/mcp-ui-render`
|
|
2
|
+
|
|
3
|
+
Public releases on **npm** (`https://registry.npmjs.org/`). One entry per published version,
|
|
4
|
+
newest first.
|
|
5
|
+
|
|
6
|
+
**On the numbering.** This package was developed against the private Verdaccio registry and
|
|
7
|
+
reached `0.5.4` there. `0.0.1` is the **first public npm release** and deliberately restarts the
|
|
8
|
+
series: npm has never held this package, so the public line begins at the beginning rather than
|
|
9
|
+
inheriting a private history no npm consumer can see. The Verdaccio-era detail is preserved in
|
|
10
|
+
`CHANGELOG.md` and is not replayed here — this file describes what a consumer *gets*, not how it
|
|
11
|
+
was built.
|
|
12
|
+
|
|
13
|
+
**If you were installing from Verdaccio:** `0.0.1` is not a downgrade. It is the same code as the
|
|
14
|
+
internal `0.6.0` line, republished. A dependency range like `^0.6.0` will **not** resolve against
|
|
15
|
+
npm — pin `0.0.1` (or `^0.0.1`) when you switch your registry over.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [0.0.1] — first public release
|
|
20
|
+
|
|
21
|
+
First publication of the framework-agnostic renderer to public npm. Same code as the internal
|
|
22
|
+
`0.6.0` build; no functional change was made for the move.
|
|
23
|
+
|
|
24
|
+
### What the package is
|
|
25
|
+
|
|
26
|
+
**Lit 3 custom elements that render a `bootstrap` tenant-configuration descriptor** — ordered
|
|
27
|
+
sections of ordered fields — with no per-connector code. The element tree is
|
|
28
|
+
`<aq-mcp-config>` → `<aq-mcp-section>` → `<aq-mcp-field>`, and it renders identically in Angular
|
|
29
|
+
(with `CUSTOM_ELEMENTS_SCHEMA`), React, or a plain HTML page.
|
|
30
|
+
|
|
31
|
+
It is a **pure renderer**: no network I/O, and it holds no secrets. It renders, validates, and
|
|
32
|
+
emits intent (`aq-mcp-change`, `aq-mcp-submit`, `aq-mcp-action`); the host executes the tools.
|
|
33
|
+
|
|
34
|
+
### What is in this release
|
|
35
|
+
|
|
36
|
+
- **Three section layouts** — `stacked` (a card per section), `tabs`, and `accordion` (a
|
|
37
|
+
single-open stack whose collapsed cards still report what is inside them and how much is left
|
|
38
|
+
to fill in).
|
|
39
|
+
- **Eleven controls**, each a Nile element: `input`, `textarea`, `password`, `select` (with
|
|
40
|
+
multi-select for `array`), `radio`, `checkbox`, `button`, `file`, `test-connection-report`,
|
|
41
|
+
`properties-table`, and `permissions-report`. `properties-table` is the one deliberate
|
|
42
|
+
exception — a plain semantic `<table>`, because Nile has no read-only data-table primitive that
|
|
43
|
+
fits this use.
|
|
44
|
+
- **An extensible control registry** (`registerControl`) so a host can add or override a
|
|
45
|
+
`ui-component` without touching the engine. An unknown `ui-component` falls back to the field's
|
|
46
|
+
datatype default and is never dropped.
|
|
47
|
+
- **A validation engine** — per-field regexes (whole-value, AND-combined) plus
|
|
48
|
+
`isRequired`/`min`/`max`, pushed into the Nile control's own `error`/`errorMessage`. A regex
|
|
49
|
+
that does not compile is logged and never blocks the user.
|
|
50
|
+
- **Secrets and hidden fields handled deliberately** — hidden fields render nothing but
|
|
51
|
+
round-trip unchanged; `secret`/`password` fields are masked and never prefilled; `writeOnce`
|
|
52
|
+
fields render as "Replace" and are omitted from submit unless the user actually enters a new
|
|
53
|
+
value.
|
|
54
|
+
- **Accessible names** wired natively for `input`, `textarea`, `password`, `select` and `radio`.
|
|
55
|
+
- **Typed ESM with per-element entry points** for tree-shaking, `.d.ts` types, and a stylesheet
|
|
56
|
+
exported as `@aquera/mcp-ui-render/styles.css`.
|
|
57
|
+
|
|
58
|
+
### Known gaps, carried forward rather than quietly dropped
|
|
59
|
+
|
|
60
|
+
- **`checkbox` has no programmatic label association.** `nile-slide-toggle`'s internal checkbox is
|
|
61
|
+
not `for`/`aria-labelledby`-associated with its label in Nile itself. It is not fixable from
|
|
62
|
+
this library, and it is a real accessibility gap for screen-reader users on checkbox fields.
|
|
63
|
+
- **File `accept`/`maxSizeKB` checks are advisory only.** This is a pure renderer with no network
|
|
64
|
+
I/O, so a connector **must** still enforce file type and size server-side. The client-side check
|
|
65
|
+
is a fast first pass, not the gate.
|
|
66
|
+
|
|
67
|
+
### Requirements
|
|
68
|
+
|
|
69
|
+
Nile is a **peer dependency** — the host installs and registers it:
|
|
70
|
+
`@aquera/nile >= 1.2.0`, `@aquera/nile-elements >= 1.9.0`, `@aquera/nile-glyph >= 1.0.0`.
|
|
71
|
+
`lit ^3.2.0` is a direct dependency.
|
|
72
|
+
|
|
73
|
+
### Licensing
|
|
74
|
+
|
|
75
|
+
Published under **MIT**, matching the other `@aquera` packages on npm. The package previously
|
|
76
|
+
declared `UNLICENSED`, which was correct while it was private and wrong for a public release;
|
|
77
|
+
the `LICENSE` file ships inside the tarball.
|
package/TEST-PLAN.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# TEST-PLAN — @aquera/mcp-ui-render
|
|
2
|
+
|
|
3
|
+
Two runnable layers:
|
|
4
|
+
|
|
5
|
+
- **Engine (pure logic)** — `nx test mcp-ui-render` (jest, node env).
|
|
6
|
+
Specs: `test/unit/apps/mcp-ui-render/engine.spec.ts` (validate/values/submit),
|
|
7
|
+
`test/unit/apps/mcp-ui-render/registry.spec.ts` (control + section-footer registries).
|
|
8
|
+
- **Element / rendering (browser)** — `nx test-browser mcp-ui-render`
|
|
9
|
+
(`@web/test-runner` + Chromium, real Nile registered).
|
|
10
|
+
Split by concern under `apps/mcp-ui-render/test/` (each file self-contained; shared
|
|
11
|
+
mount/assert helpers in `test/support/browser-helpers.js`, which is not itself a test
|
|
12
|
+
file):
|
|
13
|
+
- `conformance.browser.js` — hidden/secret fields (§7), dependency reveal (§12), a standing
|
|
14
|
+
regression test for a dependent field's `defaultValue` being seeded when it becomes newly
|
|
15
|
+
applicable mid-session (not just at initial descriptor load, §12), unknown-`ui-component`
|
|
16
|
+
fallback (§9.1), MAJOR-version negotiation (§9.5), section DOM ordering.
|
|
17
|
+
- `controls.browser.js` — control→Nile mapping (§5), the two-column layout, `select`
|
|
18
|
+
without `options` (§15), every built-in control end to end (`textarea`, `select`
|
|
19
|
+
single/multi, `checkbox`, live number validation, `file` incl. the mount-noop guard),
|
|
20
|
+
`datatype: "object"`'s JSON display/parse in `input`/`textarea` (pretty-printed display,
|
|
21
|
+
valid-JSON commits a real object, invalid/incomplete JSON kept as an interim raw string
|
|
22
|
+
without throwing or corrupting the display, defaults to `textarea` not `input`),
|
|
23
|
+
and `test-connection-report`.
|
|
24
|
+
- `layout.browser.js` — `sectionsLayout: 'tabs'` (0.4.0): tab-per-section, hidden-only
|
|
25
|
+
sections excluded from nav, `compact` styling, the error-dot's touched-vs-untouched
|
|
26
|
+
timing, `tabsShowErrorIndicator` opt-out, vertical-placement attributes.
|
|
27
|
+
- `write-once-regression.browser.js` — `writeOnce`/password masking (§7) and the
|
|
28
|
+
standing regression test for the 0.3.1 write-once password bug.
|
|
29
|
+
- `submit.browser.js` — `button` + `confirm` → `aq-mcp-action` (§5), `aq-mcp-submit`
|
|
30
|
+
payload (§13/§14), `validateAll()`, `showSectionFooters`/`showFooter`, a
|
|
31
|
+
`registerSectionFooter` override (0.3.0).
|
|
32
|
+
|
|
33
|
+
## Conformance checklist (contract §15) → coverage
|
|
34
|
+
|
|
35
|
+
| # | §15 item | Layer | Status |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| 1 | Every field carries `attribute`/`datatype`/`ui-component` | descriptor authoring (server) | n/a to renderer |
|
|
38
|
+
| 2 | Unknown `ui-component` → datatype default; field never dropped (§9.1) | element | ✅ browser |
|
|
39
|
+
| 3 | Exactly one auth section `authType`; no auth-type chooser | authoring | n/a (renderer adds no chooser) |
|
|
40
|
+
| 4 | Every auth field is one the shape needs | authoring | n/a |
|
|
41
|
+
| 5 | No field ships a secret value; use `valueFrom: secretRef` | authoring + defensive | ✅ browser (hidden secret not rendered; password never prefilled) |
|
|
42
|
+
| 6 | Section whose every field is `hidden` renders nothing (§7/§12) | element | ✅ browser (hidden field not rendered) |
|
|
43
|
+
| 7 | `none` submits nothing; `writeOnce` never in a read | engine + element | ✅ engine (submit) + ✅ browser (writeOnce Replace, not prefilled) |
|
|
44
|
+
| 8 | Every `button`/`submitTool` names a same-server tool | authoring | n/a (renderer emits the name via `aq-mcp-action`) |
|
|
45
|
+
| 9 | Section with no `submitTool` saved by the platform (§13) | engine + element | ✅ engine + ✅ browser (submit target null) |
|
|
46
|
+
| 10 | Every `select` has `options` | element + warn | ✅ browser (empty→disabled + `console.warn`) |
|
|
47
|
+
| 11 | Every `attribute` under `authorization.*` / `tenantAttributes.*` | authoring | n/a |
|
|
48
|
+
| 12 | `validation` compiles; no pseudo-rules; range via min/max | engine | ✅ engine (§8 per-datatype, bad-regex graceful) |
|
|
49
|
+
| 13 | Every field with `validation` also has `validationmessage` | authoring | n/a (renderer falls back to "Invalid value.") |
|
|
50
|
+
|
|
51
|
+
Additional renderer behaviour covered:
|
|
52
|
+
- **engine** — dependency apply + default seeding (§12, incl. dependency-not-yet-met and array `dependencyValue`), the compound `dependsOn` OR-across-attributes dependency (§9.7: any entry matching is enough, combines with `dependencyAttribute` via OR not AND, an empty `dependsOn: []` is a no-op), unknown-datatype→string+warn (§9.2), number coercion + prefix preservation on submit (§14), file/multi-file validation (`accept`/`maxSizeKB`/`minItems`/`maxItems`), object `requiredKeys`, boundary cases for `isEmpty` (whitespace, boolean `undefined` vs explicit `false`), the `WRITE_ONCE_UNCHANGED` sentinel short-circuiting `validateField` before any datatype check runs — both for `file` (where it would otherwise crash reading `.name` off the sentinel string) and `string` (where it previously "passed" only by accident), `validateFile`'s `instanceof File` guard failing safe (not crashing) for ANY other non-`File` value a `file`-datatype field might hold, `sectionHasEditableFields`, and the `registerControl`/`registerSectionFooter`/`defaultControlFor` extensibility registries (`registry.spec.ts`).
|
|
53
|
+
- **browser** — every built-in control end to end with real Nile elements and real DOM events (`input`, `textarea`, `password`, `select` single/multi, `radio` incl. the §15 no-options-disabled case, `select`/`radio` `{value,label}` options (code emitted, label displayed), `checkbox`, `file` incl. the mount-noop guard, `test-connection-report` incl. the collapsible-mitigation and hard-error paths, `permissions-report` (null-renders-nothing, banner variant follows `valid`, the granted count derived from `grants` not host-supplied, badge variant follows `access`, and the All/Success filter's structural contract — two radios sharing one native group, `data-access` attributes on every row — since the harness never loads `mcp-ui-render.css` so the actual CSS-driven hide/show isn't assertable here), `properties-table` incl. empty/null, boolean/array/em-dash value formatting, plain-object values JSON-stringified (not `[object Object]`), long-value AND long-property-name truncation with the full text in `title`, static `field.rows` with no host-supplied value at all, `values[attribute]` taking priority over `field.rows` when both are present, the card header/title always rendering even with no rows, the `FULL_WIDTH_CONTROLS` layout — no standalone `.aq-mcp-field__label` column, one full-width control column instead — and `field.actions` (an icon-bearing entry renders icon-only via `nile-icon-button`, else a labeled `nile-button`; clicking one emits `aq-mcp-action` with that specific action's own `tool`/`args`, distinct from a sibling action; an action's own `confirm` opens the shared confirm dialog before emitting), dynamic `select`/`radio` options via `dynamicOptions` + `aq-mcp-options-request` (§9.6: request fires once per applicable tool-backed field, respects `dependencyAttribute`, never double-fires, `dynamicOptions` takes priority over static `options`, pending vs. §15-defect warning distinction), control→Nile mapping (§5), dependency reveal (§12), collapsible "View more"/"View less" help text (short help unaffected, long help toggles between truncated and full), `writeOnce` Replace → input (§7), a standing **regression test for the 0.3.1 write-once password bug** (keystroke-by-keystroke typing into a blank field never reverts to masked/Replace), `button` + `confirm` → `nile-dialog` → `aq-mcp-action` (§5), `aq-mcp-submit` payload (§13/§14), MAJOR-ahead version banner (§9.5), two-column layout, section DOM order following `order` (not descriptor array order), the `sectionsLayout: 'tabs'` feature (tab-per-section, hidden-only sections excluded from nav, `compact` styling, the error-indicator dot's touched-vs-untouched timing, `tabsShowErrorIndicator` opt-out, vertical-placement attributes), `validateAll()`, `showSectionFooters`/`showFooter`, and a `registerSectionFooter` override.
|
|
54
|
+
|
|
55
|
+
## Running
|
|
56
|
+
```
|
|
57
|
+
nx test mcp-ui-render # engine (jest, node) — 67 assertions
|
|
58
|
+
nx test-browser mcp-ui-render # rendering (wtr + Chromium) — 66 assertions, 6 files
|
|
59
|
+
```
|
|
60
|
+
`test-browser` requires Playwright's Chromium: `npx playwright install chromium` once.
|
|
61
|
+
|
|
62
|
+
## Known external gap (not a bug in this library)
|
|
63
|
+
|
|
64
|
+
`@aquera/nile-elements@1.9.9` registers `nile-file-upload`/`nile-file-preview` inside
|
|
65
|
+
its full bundle but does not export either as an individual subpath (unlike every other
|
|
66
|
+
element it ships — see its `package.json` `exports` map). A host that imports Nile
|
|
67
|
+
selectively (subpath imports, to avoid pulling in the WYSIWYG editor's CommonJS
|
|
68
|
+
dependency) must import the full `@aquera/nile-elements` bundle instead to get the
|
|
69
|
+
`file` control working, or ask the Nile team to add the missing subpath exports. The
|
|
70
|
+
browser test suite works around this with a pair of logic-free stub custom elements
|
|
71
|
+
(registered in `test/support/browser-helpers.js`) purely so it can test **this
|
|
72
|
+
library's** `file`-control wiring in isolation from that packaging gap.
|
package/USAGE.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Using @aquera/mcp-ui-render
|
|
2
|
+
|
|
3
|
+
The library ships standard custom elements, so every host uses the same tags. The host
|
|
4
|
+
provides the descriptor + current values, registers Nile, and handles the emitted intents.
|
|
5
|
+
|
|
6
|
+
## Events
|
|
7
|
+
|
|
8
|
+
| Event | Detail | When |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| `aq-mcp-change` | `{ attribute, value, values }` | any field edit |
|
|
11
|
+
| `aq-mcp-submit` | `{ sectionKey, submitTool, values }` | per-section Save (validated); `submitTool` is the connector tool or `null` for the platform default (§13) |
|
|
12
|
+
| `aq-mcp-action` | `{ tool, args, confirm, field }` | a `button` (after `confirm`, if any) |
|
|
13
|
+
| `aq-mcp-options-request` | `{ attribute, tool, args }` | a `select`/`radio` field with `tool` set has no options yet and currently applies (§9.6) — at most once per `attribute` |
|
|
14
|
+
|
|
15
|
+
The library performs no network I/O and holds no secrets; the host executes the tools
|
|
16
|
+
(`aq-mcp-submit` → the platform update or the section's `submitTool`; `aq-mcp-action` → the
|
|
17
|
+
button's `tool`; `aq-mcp-options-request` → the field's `tool`, feeding the result back via
|
|
18
|
+
`dynamicOptions`), enforcing the same-server rule.
|
|
19
|
+
|
|
20
|
+
## Styling & light DOM
|
|
21
|
+
|
|
22
|
+
`<aq-mcp-config>`, `<aq-mcp-section>`, and `<aq-mcp-field>` all render into **light DOM**
|
|
23
|
+
(`createRenderRoot()` returns `this` — no shadow root), deliberately: it lets Nile's CSS
|
|
24
|
+
custom-property tokens (`--ng-*`/`--nile-*`) and this package's own stylesheet cascade in from
|
|
25
|
+
the host's page the same way any other content does, with no per-shadow-root style injection.
|
|
26
|
+
|
|
27
|
+
The trade-off is **zero style encapsulation** — the host's global CSS can affect `.aq-mcp-*`
|
|
28
|
+
classes, and vice versa — and it means the host **must** import the stylesheet globally once:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import '@aquera/mcp-ui-render/styles.css';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Without this import the elements still render structurally (every field, control, and section
|
|
35
|
+
appears) but with **no styling at all** — no card borders, no two-column layout, no error
|
|
36
|
+
colors — and **no console error or warning** to point at why. If a new integration looks
|
|
37
|
+
completely unstyled, check for this import first.
|
|
38
|
+
|
|
39
|
+
## Plain HTML
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<script type="module">
|
|
43
|
+
import '@aquera/nile-elements'; // host registers Nile
|
|
44
|
+
import '@aquera/mcp-ui-render/styles.css'; // required — see "Styling & light DOM" above
|
|
45
|
+
import '@aquera/mcp-ui-render';
|
|
46
|
+
const el = document.querySelector('aq-mcp-config');
|
|
47
|
+
el.descriptor = await callBootstrapTool(); // the bootstrap tool result
|
|
48
|
+
el.values = currentValues;
|
|
49
|
+
el.addEventListener('aq-mcp-submit', (e) => host.save(e.detail));
|
|
50
|
+
el.addEventListener('aq-mcp-action', (e) => host.callTool(e.detail.tool, e.detail.args));
|
|
51
|
+
</script>
|
|
52
|
+
<aq-mcp-config></aq-mcp-config>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Angular
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// Standalone component (or NgModule) that renders the custom element:
|
|
59
|
+
@Component({
|
|
60
|
+
selector: 'app-connector-config',
|
|
61
|
+
standalone: true,
|
|
62
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA], // required for aq-mcp-* / nile-* tags
|
|
63
|
+
template: `<aq-mcp-config [descriptor]="descriptor" [values]="values"
|
|
64
|
+
(aq-mcp-submit)="onSubmit($event)" (aq-mcp-action)="onAction($event)"></aq-mcp-config>`,
|
|
65
|
+
})
|
|
66
|
+
export class ConnectorConfigComponent {}
|
|
67
|
+
```
|
|
68
|
+
`import '@aquera/mcp-ui-render'` **and** `import '@aquera/mcp-ui-render/styles.css'` once at
|
|
69
|
+
bootstrap (alongside `@aquera/nile-elements`) — see "Styling & light DOM" above.
|
|
70
|
+
|
|
71
|
+
## React
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import '@aquera/nile-elements';
|
|
75
|
+
import '@aquera/mcp-ui-render/styles.css'; // required — see "Styling & light DOM" above
|
|
76
|
+
import '@aquera/mcp-ui-render';
|
|
77
|
+
|
|
78
|
+
function ConnectorConfig({ descriptor, values, onSubmit }) {
|
|
79
|
+
const ref = useRef<HTMLElement>(null);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
const el = ref.current!;
|
|
82
|
+
(el as any).descriptor = descriptor;
|
|
83
|
+
(el as any).values = values;
|
|
84
|
+
const submit = (e: any) => onSubmit(e.detail);
|
|
85
|
+
el.addEventListener('aq-mcp-submit', submit);
|
|
86
|
+
return () => el.removeEventListener('aq-mcp-submit', submit);
|
|
87
|
+
}, [descriptor, values, onSubmit]);
|
|
88
|
+
return <aq-mcp-config ref={ref} />;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## MCP-App (ext-apps) delivery mode
|
|
93
|
+
|
|
94
|
+
For MCP clients, a thin single-file entry (built with `vite-plugin-singlefile`, Nile inlined)
|
|
95
|
+
imports the same Lit engine and bridges it to the MCP-Apps host: `ontoolresult` →
|
|
96
|
+
`descriptor`/`values`; `aq-mcp-submit`/`aq-mcp-action` → `callServerTool`. This entry is **built**,
|
|
97
|
+
at `servers/mcp-gateway-service/apps/mcp-gateway/src/mcp-apps/ui/src/mcp-ui-render-app.js` (a
|
|
98
|
+
vanilla-JS entry using `@modelcontextprotocol/ext-apps`'s core `App` class — no React), not in a
|
|
99
|
+
separate `mcp-engine` repo (see SPEC-mcp-ui-render §"MCP delivery" and the 2026-08-01 entry in
|
|
100
|
+
`kb/QA-QUEUE.md`).
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aquera/mcp-ui-render",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Framework-agnostic Lit 3 web components that render a Keycloak/MCP bootstrap tenant-configuration descriptor using Nile. Decoupled from any framework — renders in Angular, React, or plain HTML.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"module": "./src/index.js",
|
|
8
|
+
"types": "./src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./src/index.d.ts",
|
|
12
|
+
"import": "./src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./elements/*": {
|
|
15
|
+
"types": "./src/elements/*.d.ts",
|
|
16
|
+
"import": "./src/elements/*.js"
|
|
17
|
+
},
|
|
18
|
+
"./styles.css": "./src/mcp-ui-render.css"
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": [
|
|
21
|
+
"**/controls.js",
|
|
22
|
+
"**/elements/*.js",
|
|
23
|
+
"**/index.js"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"lit": "^3.2.0"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"@aquera/nile": ">=1.2.0",
|
|
30
|
+
"@aquera/nile-elements": ">=1.9.0",
|
|
31
|
+
"@aquera/nile-glyph": ">=1.0.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"mcp",
|
|
35
|
+
"bootstrap",
|
|
36
|
+
"descriptor",
|
|
37
|
+
"lit",
|
|
38
|
+
"web-components",
|
|
39
|
+
"nile",
|
|
40
|
+
"aquera"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"registry": "https://registry.npmjs.org/",
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+ssh://git@bitbucket.org/aquerateam/agentic-access-platform.git",
|
|
50
|
+
"directory": "servers/mcp-gateway-service/apps/mcp-ui-render"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|