AlistGo/alist · error
MCP manage not permitted
Error message
MCP manage not permitted
What it means
Returned by checkManage (server/mcp/auth.go:143) when a write-oriented MCP operation is attempted by a non-admin whose merged permissions lack PermMCPManage. It fires after checkAccess has already passed, so path access and the MCP access bit are fine — the additional 'manage' (write-level) grant is missing.
Source
Thrown at server/mcp/auth.go:143
meta, _ := op.GetNearestMeta(reqPath)
if !common.CanAccessWithRoles(user, meta, reqPath, "") {
return fmt.Errorf("permission denied")
}
perm := common.MergeRolePermissions(user, reqPath)
if !user.IsAdmin() && !common.HasPermission(perm, common.PermMCPAccess) {
return fmt.Errorf("MCP access not permitted")
}
return nil
}
// checkManage checks if user can perform write operations via MCP.
func checkManage(user *model.User, reqPath string, permBit uint) error {
if err := checkAccess(user, reqPath); err != nil {
return err
}
perm := common.MergeRolePermissions(user, reqPath)
if !user.IsAdmin() && !common.HasPermission(perm, common.PermMCPManage) {
return fmt.Errorf("MCP manage not permitted")
}
if !user.IsAdmin() && !common.HasPermission(perm, permBit) {
return fmt.Errorf("permission denied for this operation")
}
return nil
}
// UserContextFunc returns an HTTPContextFunc that injects a specific user (for STDIO mode).
func userContextMiddleware(user *model.User) func(ctx context.Context) context.Context {
return func(ctx context.Context) context.Context {
return context.WithValue(ctx, userKey, user)
}
}
// resolveUserForStdio resolves a user by username for STDIO mode.
func resolveUserForStdio(username string) (*model.User, error) {
username = strings.TrimSpace(username)
if username == "" || username == "admin" {View on GitHub (pinned to 843d9dc814)
Solutions
- Grant the MCP manage permission to the role performing write operations
- Use separate read-only and read-write roles so the manage bit is deliberate
- Verify with the permission matrix in the admin UI before scripting writes
Defensive patterns
Strategy: validation
Validate before calling
// before scripting write operations, assert the role carries both mcp access and mcp manage
Prevention
- Separate read-only and read-write MCP roles
- Add the manage bit only to roles that perform mutations
When it happens
Trigger: A non-admin user with mcp access but not mcp manage calls a mutating MCP tool (write, rename, or delete flows) that routes through checkManage.
Common situations: Read-only MCP roles being reused for maintenance scripts; permission sets cloned from a read role and never given the manage bit.
Related errors
- MCP access not permitted
- permission denied for this operation
- user is not allowed to access via FTP
- permission denied
- failed to get download link
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/9fe5601664f1bf07.
Report an issue: GitHub.