You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit db5ea00
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: adminforth/documentation/docs/tutorial/09-Plugins/01-agent.md
+8-22Lines changed: 8 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -668,28 +668,19 @@ To define a custom tool, register an API endpoint with `admin.express.endpoint`.
668
668
669
669
By default, `admin.express.endpoint` applies AdminForth authorization. The endpoint handler receives `adminUser` from the user who is controlling the agent. In other words, all permissions and access rights of the agent are defined by that admin user. At the same time, actions done by the agent are automatically attributed in the audit log to the admin user who is controlling the agent.
670
670
671
-
If a tool is risky, you can attach AdminForth agent metadata directly to the endpoint with the `agent` field.
671
+
You can attach AdminForth agent metadata directly to the endpoint with the `agent` field.
672
672
673
673
```ts
674
-
typeAgentRiskLevel='safe'|'danger';
675
-
676
674
typeAgentToolMeta= {
677
-
riskLevel?:AgentRiskLevel;
678
-
confirmation?: {
679
-
title?:string;
680
-
message?:string;
681
-
confirmLabel?:string;
682
-
};
675
+
requiresHumanApproval?:boolean;
676
+
hiddenFromAgents?:boolean;
677
+
onlyReadsData?:boolean;
683
678
};
684
679
```
685
680
686
-
Use it in `.endpoint(...)` like this:
687
-
688
-
-`riskLevel: 'safe'` marks the tool as low-risk.
689
-
-`riskLevel: 'danger'` marks the tool as dangerous.
690
-
-`confirmation` customizes the confirmation dialog shown before the tool is executed.
691
-
692
-
This metadata is rendered into the generated OpenAPI document, so the agent can understand that a tool is dangerous and requires an explicit confirmation UI before execution.
681
+
-`requiresHumanApproval: true` makes the agent ask the user for approval before it runs the tool. MCP clients receive the `destructiveHint` annotation.
682
+
-`hiddenFromAgents: true` keeps the endpoint out of agent tools, both in the agent and in the [MCP server](/docs/tutorial/Plugins/mcp/). Use it for endpoints that serve your admin panel UI and must not be called by agents.
683
+
-`onlyReadsData: true` declares that the endpoint does not change any data. MCP clients receive the `readOnlyHint` annotation, and a [read-only MCP server](/docs/tutorial/Plugins/mcp/#read-only-mode) exposes only such endpoints.
693
684
694
685
This example uses the same email adapter pattern shown in the Email Invite and Email Password Reset plugins. The transport below uses Mailgun only to keep the snippet short; you can replace it with SES or any other adapter from [List of adapters](/docs/tutorial/ListOfAdapters/).
Copy file name to clipboardExpand all lines: adminforth/documentation/docs/tutorial/09-Plugins/30-mcp.md
+20Lines changed: 20 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,8 @@ slug: /tutorial/Plugins/mcp
8
8
9
9
The MCP plugin exposes AdminForth API methods as remote MCP tools. Every request runs as the AdminForth user who created the auth secret, so the same resource permissions, validation, and hooks apply.
10
10
11
+
Endpoints marked with `agent: { hiddenFromAgents: true }` are not exposed. AdminForth and its plugins mark the endpoints the admin panel uses internally, such as login, two-factor authentication, passkeys, and agent chat. Mark your own endpoints the same way to keep them away from agents.
`last_used_at` and `last_used_by_agent` are updated in the background without running resource hooks. Client identity comes from per-request `io.modelcontextprotocol/clientInfo` metadata in MCP `2026-07-28`, with legacy `initialize` and `User-Agent` fallbacks.
120
125
126
+
## Read-only mode
127
+
128
+
A read-only auth secret lets an agent only read data. Check **Read only** when you create the auth secret in **MCP Settings**. The mode is stored in `read_only` and cannot be changed later: create a new auth secret instead.
129
+
130
+
To make every auth secret read-only, set `readOnly: true` in the plugin options. The **Read only** checkbox is then hidden, and new auth secrets are stored as read-only, so they stay read-only if you remove the option later:
131
+
132
+
```ts
133
+
newAdminForthMcpPlugin({
134
+
readOnly: true,
135
+
// ...
136
+
}),
137
+
```
138
+
139
+
In read-only mode the server exposes only endpoints marked with `agent: { onlyReadsData: true }`, such as `get_resource`, `get_resource_data`, and `aggregate`. Creating, updating, and deleting records and running actions are not available. To make your own endpoint available in read-only mode, mark it with `onlyReadsData: true`.
140
+
121
141
## Audit attribution
122
142
123
143
To show which agent acted on behalf of a user, add a nullable field to the audit log table:
description: 'Computes the current menu badge values for the authenticated admin user. Static badges are returned directly, and dynamic badge callbacks are resolved for all configured menu items, including nested items.',
description: 'Returns the definition of a single resource. The response includes translated labels, column metadata, allowed actions, visible bulk actions, frontend action metadata, and resource options after permission checks and removal of backend-only internals.',
description: 'Loads resource rows for list, show, or edit views. The endpoint validates access, applies request hooks, filters, sorting, pagination, record labels, and row click URLs, then returns the final dataset with resource options.',
description: 'Performs aggregation queries (sum, count, avg, min, max, median) on a resource, with optional grouping by field value or date truncation. Requires list and show access to the resource, and only accepts columns the user can read on the show view: backend-only columns and columns hidden from the show view are rejected.',
description: 'Loads dropdown options for a foreign-key column. It resolves the referenced resource or polymorphic resources, applies optional search text, hook-injected filters, pagination, and per-record labels, then returns sanitized option items.',
description: 'Returns min and max values for resource columns that explicitly opt in to min/max queries. This is used to build range-based filter controls without exposing columns that do not allow the query.',
description: 'Creates a new record in the specified resource. The endpoint validates create permissions, required fields, hidden or backend-only field rules, polymorphic foreign keys, and resource hooks before persisting and returning the created primary key.',
description: 'Updates an existing record by primary key. The endpoint validates edit permissions, current record existence, hidden, backend-only, and read-only field rules, polymorphic foreign keys, and resource hooks before saving changes.',
description: 'Deletes an existing record by primary key. The endpoint validates delete permissions, loads the current record, executes configured cascade child deletion, and then removes the record.',
description: 'Executes a custom resource action for a single record. The endpoint validates the resource, action existence, and action permissions, then either returns a redirect URL or executes the action handler and returns its result together with action context.',
description: 'Executes a custom resource action in bulk mode for multiple records. The endpoint validates the resource, action existence, bulk handler availability, and permissions, then runs the bulk handler and returns its result together with action context.',
0 commit comments