Browse Source

docs: update low-code MCP token setup

pull/25780/head
SALİH ÖZKARA 3 months ago
parent
commit
c9e4cde103
  1. BIN
      docs/en/images/openiddict-client-credentials-application.png
  2. 2
      docs/en/low-code/designer.md
  3. 2
      docs/en/low-code/index.md
  4. 281
      docs/en/low-code/mcp.md
  5. 38
      docs/en/modules/openiddict-pro.md

BIN
docs/en/images/openiddict-client-credentials-application.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

2
docs/en/low-code/designer.md

@ -165,7 +165,7 @@ Use **Health** before shipping changes. It helps catch missing display propertie
## MCP Integration
The Designer and the low-code MCP surface overlap when the selected layer is **Runtime JSON**, but they are not the same editing surface. The Designer can inspect source-controlled and runtime layers, while [MCP Integration](mcp.md) is intentionally runtime-only and targets the database-backed model. Use the Designer when you want interactive editing and visual feedback. Use MCP when an agent or script needs a structured read, validate, apply, and health-check workflow against the runtime model.
The Designer and the low-code MCP surface overlap when the selected layer is **Runtime JSON**, but they are not the same editing surface. The Designer can inspect source-controlled and runtime layers, while [MCP Integration](mcp.md) is a remote HTTP MCP endpoint that is intentionally runtime-only and targets the database-backed model. Use the Designer when you want interactive editing and visual feedback. Use MCP when an authenticated agent or script needs repeatable runtime automation.
After MCP-driven changes, reopen the relevant Designer section or review [Health](health.md) before reporting the model as ready.

2
docs/en/low-code/index.md

@ -176,7 +176,7 @@ The designer stores and reads the same descriptor metadata described in the refe
| [Health](health.md) | Selected-layer readiness review across entities, pages, forms, page groups, permissions, and scripts |
| [Dashboards](dashboards.md) | Dashboard page descriptors, visualization layout, filters, and runtime data flow |
| [Page Groups](page-groups.md) | Dynamic menu folders, nesting, ordering, and page grouping |
| [MCP Integration](mcp.md) | Runtime designer automation with structured reads, validation, apply, and health review |
| [MCP Integration](mcp.md) | Remote MCP endpoint, OpenIddict token setup, and authenticated runtime automation |
| [Attributes & Fluent API](fluent-api.md) | Source-controlled C# metadata and runtime overrides |
| [Model Descriptor Files](model-json.md) | JSON descriptor files and public descriptor schemas used by the designer and runtime |
| [Reference Entities](reference-entities.md) | Lookups to existing entities such as Identity users |

281
docs/en/low-code/mcp.md

@ -1,213 +1,158 @@
```json
//[doc-seo]
{
"Description": "Use the ABP Low-Code Designer MCP integration to inspect, validate, and apply structured runtime mutations to the database-backed low-code model."
"Description": "Connect remote MCP clients to the ABP Low-Code Designer MCP endpoint with OpenIddict client credentials tokens."
}
```
# MCP Integration
> **Preview:** The low-code MCP surface is part of the preview Low-Code System. Tool names, mutation metadata, and validation advice may change before general availability.
> **Preview:** The low-code MCP surface is part of the preview Low-Code System. Endpoint behavior, authorization requirements, and mutation metadata may change before general availability.
The low-code designer exposes a Model Context Protocol (MCP) surface for automation. It is intended for agents and scripted tooling that need to inspect or mutate the same **runtime database-backed** model that the Designer edits in the **Runtime JSON** layer.
The Low-Code Designer exposes a **remote Model Context Protocol (MCP) server** from the running ABP HTTP API host. It is not a local `stdio` tool package. MCP clients connect to your application over HTTP, authenticate with an OpenIddict access token, and work against the same **runtime database-backed** model that the Designer edits in the **Runtime JSON** layer.
## Scope
Use [Model Descriptor Files](model-json.md) when you need source-controlled `_Dynamic/model/**/*.json` files. Use MCP when an agent or automation needs authenticated, structured runtime access that the Designer can immediately show.
The MCP surface is **runtime-only**:
## Remote Endpoint
* It always works against the database-backed runtime model.
* It does not choose between layers at call time.
* It is not the right surface for source-controlled `_Dynamic/model/**/*.json` files.
Use [Model Descriptor Files](model-json.md) when you need source-controlled descriptors. Use MCP when an agent or automation needs safe, structured changes to the runtime model that the Designer can immediately show.
The low-code MCP endpoint is hosted by the backend application that includes the Low-Code Designer HTTP API module:
## Tool Reference
All tools below work against the **runtime database-backed** model only.
### Core Workflow Tools
| Tool | Use it for |
|------|------------|
| `lowcode_designer_get_capabilities` | Read the server's runtime-only scope, write rules, recommended workflow, and example mutation targets |
| `lowcode_designer_get_mutation_metadata` | Fetch the current `concurrencyStamp` and the valid semantic target tree before planning a write |
| `lowcode_designer_validate_mutations` | Dry-run a mutation batch and get structured validation feedback without writing |
| `lowcode_designer_apply_mutations` | Apply a validated mutation batch to the runtime model; this is the **only write tool** |
| `lowcode_designer_get_health_snapshot` | Re-check the full runtime model after changes to catch broken references or invalid layouts |
### Entity and Enum Tools
| Tool | Use it for |
|------|------------|
| `lowcode_designer_get_entities` | List runtime entities; optionally include configured reference entities |
| `lowcode_designer_get_entity` | Read one entity with properties, validators, interceptors, and child metadata |
| `lowcode_designer_get_entity_delete_impact` | Review references that would break or change if an entity is removed |
| `lowcode_designer_get_enum_types` | List available enum types |
| `lowcode_designer_get_enum` | Read one enum and its values |
| `lowcode_designer_get_enum_delete_impact` | Review what depends on an enum before removing it |
### Page, Form, and Permission Tools
| Tool | Use it for |
|------|------------|
| `lowcode_designer_get_page_groups` | List page groups used for runtime navigation folders |
| `lowcode_designer_get_pages` | List pages across page types, including dashboard pages |
| `lowcode_designer_get_page` | Read one page descriptor, including columns, filters, dashboard config, and form links |
| `lowcode_designer_get_page_permission_config` | Read the page's permission bindings before changing access rules |
| `lowcode_designer_get_forms` | List forms |
| `lowcode_designer_get_form` | Read one form with fields, flat layout placements, validations, and rules |
| `lowcode_designer_get_form_delete_impact` | Review what depends on a form before removing it |
| `lowcode_designer_get_permissions` | List runtime low-code permission definitions |
| `lowcode_designer_get_permission_delete_impact` | Review where a permission is referenced before removing it |
### Script and Action Tools
| Tool | Use it for |
|------|------------|
| `lowcode_designer_get_endpoints` | List scripted custom endpoints |
| `lowcode_designer_get_endpoint` | Read one endpoint with route, method, JavaScript, and analyzed references |
| `lowcode_designer_get_script_autocomplete_metadata` | Discover the script globals, helpers, entities, and metadata available for a script type |
| `lowcode_designer_test_script` | Dry-run endpoint, interceptor, event handler, background job, or background worker JavaScript |
| `lowcode_designer_get_script_event_handlers` | List script event handlers |
| `lowcode_designer_get_script_event_handler` | Read one event handler |
| `lowcode_designer_get_script_background_jobs` | List script background jobs |
| `lowcode_designer_get_script_background_job` | Read one background job |
| `lowcode_designer_get_script_background_worker_scheduler_capabilities` | Read whether the runtime supports dynamic worker registration and cron scheduling |
| `lowcode_designer_get_script_background_workers` | List script background workers |
| `lowcode_designer_get_script_background_worker` | Read one background worker with schedule and JavaScript |
## Common Sequences
### Change an Entity or Form
1. Read the current item with `lowcode_designer_get_entity` or `lowcode_designer_get_form`.
2. Fetch `lowcode_designer_get_mutation_metadata`.
3. Build a small mutation batch against the returned target tree.
4. Run `lowcode_designer_validate_mutations`.
5. Apply with `lowcode_designer_apply_mutations`.
6. Re-read the item and run `lowcode_designer_get_health_snapshot`.
### Change a Dashboard or Page Group
1. Read the page with `lowcode_designer_get_page` or list groups with `lowcode_designer_get_page_groups`.
2. Fetch mutation metadata and validate the exact batch.
3. Apply the change.
4. Re-open the page via `lowcode_designer_get_page` and confirm health.
### Remove a Shared Item Safely
1. Call the matching delete-impact tool first, such as `lowcode_designer_get_entity_delete_impact`, `lowcode_designer_get_enum_delete_impact`, `lowcode_designer_get_form_delete_impact`, or `lowcode_designer_get_permission_delete_impact`.
2. Fix or remove dependent references.
3. Validate the removal batch.
4. Apply and then re-check health.
### Review or Debug a Script
1. Read the action or endpoint with its `get_*` tool.
2. Fetch `lowcode_designer_get_script_autocomplete_metadata` for the relevant script type.
3. Run `lowcode_designer_test_script`.
4. Persist the change through mutations only after the dry run looks correct.
## Mental Model
MCP is not a raw JSON document editor. It is a semantic mutation layer over low-code concepts such as:
* Entities and properties
* Pages, page groups, and dashboards
* Forms and form layout
* Permissions
* Custom endpoints and script actions
The MCP surface includes read/query capabilities, mutation metadata, dry-run validation, a single mutation apply path, and a health snapshot. The normal workflow is:
1. Read the current runtime model state for the item you want to change.
2. Fetch the latest mutation metadata and keep its `concurrencyStamp`.
3. Build a small ordered mutation batch that touches only the changed paths.
4. Dry-run the batch with validation.
5. Apply the batch.
6. Re-read the changed item and review [Health](health.md).
```text
https://localhost:<host-port>/mcp/low-code-designer
```
## Concurrency and Validation
Connection details:
Every runtime write depends on the latest `concurrencyStamp`. If another write changes the runtime model first, your apply attempt becomes stale and must be rebuilt from the refreshed model state.
* **Transport:** Streamable HTTP / HTTP MCP transport
* **Authentication:** `Authorization: Bearer <access-token>`
* **Server name:** `abp-low-code-runtime-designer`
* **Scope:** Runtime database-backed low-code model only
Validation happens before apply and returns structured feedback instead of requiring a client to guess from generic failures. The validation layer checks:
Use the backend host URL, not the React runtime URL and not the Admin Console SPA URL. In tiered solutions, connect to the HTTP API host where the low-code designer API module is loaded.
* Stale concurrency stamps
* Target path syntax
* Missing required input such as `data` or move destinations
* Primitive-only `Set` data
* Final descriptor shape after the batch is simulated
* Entity property type and foreign key rules
* Form layout consistency
* Dashboard layout consistency
* Runtime override rules for descriptors inherited from lower layers
## Required Permissions
Treat validation as part of the normal write flow, not as an optional extra.
The endpoint requires the Low-Code Designer permission group:
## Mutation Model
| Permission | Required for |
|------------|--------------|
| `AbpLowCodeDesigner.Default` | Connecting and reading runtime model metadata |
| `AbpLowCodeDesigner.Edit` | Validating and applying runtime model changes |
| `AbpLowCodeDesigner.ScriptTest` | Running script dry-runs through MCP |
Runtime writes are intentionally narrow:
Grant these permissions to the **OpenIddict application/client** that will request the token, not only to a user or role. In Admin Console, use the permission action on the OpenIddict application row and grant the required Low-Code Designer permissions for the client.
* `Add` creates a keyed descriptor or collection member.
* `Set` changes a scalar value or a supported primitive list.
* `Remove` deletes the semantic target.
* `Move` relocates an existing node without resending the whole object.
See the [Permission Management Module](../modules/permission-management.md#permission-management-dialog) for the standard permission dialog behavior.
Important behavior:
## Create an Access Token
* `Set` data must stay primitive: string, number, boolean, `null`, or a supported primitive string list.
* Do not replace whole descriptor trees when only one field changed.
* Keep batches small and semantic. Send changed paths, not full model payloads.
* If a mapped entity or property is removed with drop behavior, the runtime model can also remove the physical table or column in the runtime layer.
For unattended MCP automation, create a dedicated OpenIddict application instead of reusing an interactive user token.
## Runtime Override and Schema Rules
1. Open **Admin Console**.
2. Go to **OpenIddict** > **Applications**.
3. Create a new application, for example `LowCodeMcpClient`.
4. Set **Client type** to `Confidential client`.
5. Set a strong **Client secret** and store it securely.
6. Open the **Authorization** tab and enable **Allow client credentials flow**.
7. Open the **Scopes** tab and allow the API scope used by the backend that hosts the low-code APIs, for example `<YourAppName>`.
8. Save the application.
9. From the application row, open **Permissions** and grant the Low-Code Designer permissions required by your MCP scenario.
Runtime MCP writes can extend descriptors that originate from lower layers, but they do not have unlimited control over inherited schema.
The OpenIddict application and scope management screens are described in [Creating a Client Credentials Application](../modules/openiddict-pro.md#creating-a-client-credentials-application).
For entity properties inherited from a lower layer, runtime edits are intentionally restricted. Typical runtime-safe changes are display labels and runtime-owned validators. Inherited storage details such as type, database mapping, default value, required or unique behavior, foreign key settings, and file or image storage options remain immutable in runtime.
The Admin Console application screen should show the confidential client with **Allow client credentials flow** enabled:
This separation matches the low-code layer model:
![openiddict-client-credentials-application](../images/openiddict-client-credentials-application.png)
* Runtime database-backed changes use **direct** schema mutation.
* Source-controlled JSON layer changes use the normal **migration** workflow.
Request an access token from the OpenIddict authority with the saved client id, client secret, and selected API scope. In non-tiered solutions this is usually the same backend host; in tiered solutions it is usually the Auth Server URL:
If you are working in `_Dynamic/model`, MCP is the wrong tool. Use the source-controlled descriptor flow and migrations instead.
```bash
curl -X POST "https://localhost:<auth-server-port>/connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=LowCodeMcpClient" \
-d "client_secret=<client-secret>" \
-d "scope=<YourAppName>"
```
## Layout and Type Conventions
Use the returned `access_token` as the bearer token in the MCP client configuration.
Several conventions matter when MCP clients generate mutations:
```text
Authorization: Bearer <access-token>
```
* Use canonical lowercase entity property types: `string`, `int`, `long`, `decimal`, `datetime`, `boolean`, `guid`, `enum`, `date`, `time`, `file`, `image`, `money`.
* Use canonical lowercase form field types: `text`, `textarea`, `number`, `checkbox`, `date`, `datetime`, `select`, `lookup`, `guid`, `computed`, `time`, `file`, `image`, `money`.
* Form layout is flat and id-keyed under `layout.tabs[].groups[].fields[]`. Each placement carries `row`, `colSpan`, and optional `colStart`.
* Dashboard layout is flat and name-keyed under `dashboard.visualizations[]`. Each visualization carries `row`, `order`, and `width`.
* Page and page-group icons are CSS class strings, not URLs or image file paths.
* For foreign access, `foreignKey.access` values are `none`, `view`, or `edit`.
## Connect From An MCP Client
These rules matter because validation and runtime rendering assume them. For example, a form can define fields correctly but still render an empty group if no valid placements point to those field IDs.
For ABP AI Management or another MCP client that supports remote HTTP servers, create a server entry with:
## Designer and MCP Together
| Setting | Value |
|---------|-------|
| Name | `ABP Low-Code Designer` |
| Transport | HTTP / Streamable HTTP |
| Endpoint URL | `https://localhost:<host-port>/mcp/low-code-designer` |
| Authentication | Bearer token |
| Token | The OpenIddict access token created for `LowCodeMcpClient` |
Use the Designer when you want:
For clients that use JSON configuration, the same connection usually looks like this:
* Interactive editing
* Visual context for entities, pages, forms, and permissions
* Manual review before publishing
```json
{
"mcpServers": {
"abp-low-code-designer": {
"type": "streamable-http",
"url": "https://localhost:<host-port>/mcp/low-code-designer",
"headers": {
"Authorization": "Bearer <access-token>"
}
}
}
}
```
Client configuration names differ by product. If your client uses `http`, `streamableHttp`, or a separate `authorization` field, keep the same endpoint URL and bearer token.
Use MCP when you want:
## Runtime-Only Scope
* Agent-driven or scripted changes
* Repeatable runtime mutation workflows
* Structured validation before write
* Safe, incremental edits instead of raw JSON replacement
The MCP surface is **runtime-only**:
* It always reads and writes the database-backed runtime model.
* It does not choose between source-controlled and runtime layers at call time.
* It does not edit source-controlled `_Dynamic/model/**/*.json` descriptor files.
* It does not replace the normal migration workflow for source-controlled model changes.
Runtime MCP writes can extend descriptors that originate from lower layers, but inherited storage details remain restricted. For example, runtime edits can typically change display labels and runtime-owned validators, but cannot change inherited property type, database mapping, required or unique behavior, foreign key settings, or file and image storage options.
## Safe Automation Workflow
After the MCP client connects, let it discover the available capabilities from the server. The normal write workflow should still be conservative:
1. Read the current runtime item before planning a change.
2. Fetch the current mutation metadata and concurrency stamp.
3. Build a small mutation batch that touches only the changed semantic paths.
4. Validate the batch before writing.
5. Apply the validated batch.
6. Re-read the changed item and review [Health](health.md).
Treat validation and health review as part of the normal MCP workflow. They are especially important for forms, dashboard layouts, relation changes, and delete operations that can leave broken references.
## Troubleshooting
| Problem | Check |
|---------|-------|
| `401 Unauthorized` | The MCP client is not sending `Authorization: Bearer <access-token>`, the token expired, or the token was issued by an authority that the backend host does not trust. |
| `403 Forbidden` | The OpenIddict client does not have the required `AbpLowCodeDesigner.*` permissions. |
| Client cannot connect | Verify that the backend host is running and that the URL points to `/mcp/low-code-designer` on the HTTP API host. |
| Writes fail | Grant `AbpLowCodeDesigner.Edit`, refresh the token, and rebuild the change from the latest runtime metadata. |
| Script dry-run fails with authorization | Grant `AbpLowCodeDesigner.ScriptTest` and generate a new token. |
## Designer and MCP Together
The two surfaces are complementary. A common workflow is to inspect or prototype in the Designer, automate a repeatable mutation flow through MCP, then reopen the Designer and [Health](health.md) to confirm the result.
Use the Designer when you want interactive editing and visual review. Use MCP when a remote agent or automation needs authenticated, repeatable runtime changes. After MCP-driven changes, reopen the relevant Designer section or review [Health](health.md) before treating the runtime model as ready.
## See Also
* [Low-Code Designer](designer.md)
* [Health](health.md)
* [Dashboards](dashboards.md)
* [Page Groups](page-groups.md)
* [Model Descriptor Files](model-json.md)
* [OpenIddict Module (Pro)](../modules/openiddict-pro.md#creating-a-client-credentials-application)
* [Permission Management Module](../modules/permission-management.md#permission-management-dialog)

38
docs/en/modules/openiddict-pro.md

@ -50,6 +50,44 @@ You can create new application or edit existing applications in this page:
![openiddict-edit-application-modal](../images/openiddict-edit-application-modal.png)
##### Creating a Client Credentials Application
Use a client credentials application when a machine-to-machine client, automation, or MCP client needs to call protected backend APIs without an interactive user login.
1. Open **Administration** > **OpenIddict** > **Applications**.
2. Click **New Application**.
3. Enter a unique **Client Id**, for example `InternalAutomationClient`.
4. Set **Client Type** to `Confidential client`.
5. Enter a strong **Client Secret** and store it securely. The secret is required when the client requests a token.
6. Open the **Authorization** tab and enable **Allow client credentials flow**.
7. Open the **Scopes** tab and select the API scopes the client can request.
8. Save the application.
The application screen should show the `client_credentials` grant enabled. Use the **Scopes** tab to select the API scope that the client can request.
![openiddict-client-credentials-application](../images/openiddict-client-credentials-application.png)
If the client will call APIs protected by ABP permissions, grant permissions to the application after saving it. Open the application row's **Actions** menu, select **Permissions**, and grant the required permissions for the **Client (OpenIddict Applications)** provider.
Request an access token from the OpenIddict token endpoint with the `client_credentials` grant:
```bash
curl -X POST "https://localhost:<auth-server-port>/connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=InternalAutomationClient" \
-d "client_secret=<client-secret>" \
-d "scope=<api-scope>"
```
Use the returned `access_token` as a bearer token when calling protected APIs:
```text
Authorization: Bearer <access-token>
```
In non-tiered applications, the OpenIddict authority is typically the backend host. In tiered applications, use the Auth Server URL for `/connect/token`.
#### API Scope Management
OpenIddict module allows to manage API scope. To allow applications to request access tokens for APIs, you need to define API scopes.

Loading…
Cancel
Save