Skip to main content
Glama

update_space_role

Update a space role's name, permissions, allowed paths, and other settings in Storyblok.

Instructions

Updates a space role's configuration via the Storyblok Management API.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
space_role_idYesID of the space role to update
role_nameNoNew name for the role
permissionsNoArray of permission strings
allowed_pathsNoArray of allowed path IDs
field_permissionsNoArray of field permission strings
readonly_field_permissionsNoArray of readonly field permission strings
subtitleNoSubtitle for the role
datasource_idsNoArray of allowed datasource IDs
component_idsNoArray of allowed component IDs
branch_idsNoArray of allowed branch IDs
allowed_languagesNoArray of allowed language codes
asset_folder_idsNoArray of allowed asset folder IDs

Implementation Reference

  • Main handler for the update_space_role tool. Builds a space_role payload from optional input fields and sends a PUT request to /space_roles/{space_role_id}.
    // Tool: update_space_role
    server.tool(
      'update_space_role',
      "Updates a space role's configuration via the Storyblok Management API.",
      {
        space_role_id: z.number().describe('ID of the space role to update'),
        role_name: z.string().optional().describe('New name for the role'),
        permissions: z.array(z.string()).optional().describe('Array of permission strings'),
        allowed_paths: z.array(z.number()).optional().describe('Array of allowed path IDs'),
        field_permissions: z.array(z.string()).optional().describe('Array of field permission strings'),
        readonly_field_permissions: z
          .array(z.string())
          .optional()
          .describe('Array of readonly field permission strings'),
        subtitle: z.string().optional().describe('Subtitle for the role'),
        datasource_ids: z.array(z.number()).optional().describe('Array of allowed datasource IDs'),
        component_ids: z.array(z.number()).optional().describe('Array of allowed component IDs'),
        branch_ids: z.array(z.number()).optional().describe('Array of allowed branch IDs'),
        allowed_languages: z.array(z.string()).optional().describe('Array of allowed language codes'),
        asset_folder_ids: z.array(z.number()).optional().describe('Array of allowed asset folder IDs'),
      },
      async ({
        space_role_id,
        role_name,
        permissions,
        allowed_paths,
        field_permissions,
        readonly_field_permissions,
        subtitle,
        datasource_ids,
        component_ids,
        branch_ids,
        allowed_languages,
        asset_folder_ids,
      }) => {
        try {
          const spaceRoleData: Record<string, unknown> = {};
    
          if (allowed_paths !== undefined) spaceRoleData.allowed_paths = allowed_paths;
          if (field_permissions !== undefined) spaceRoleData.field_permissions = field_permissions;
          if (readonly_field_permissions !== undefined)
            spaceRoleData.readonly_field_permissions = readonly_field_permissions;
          if (permissions !== undefined) spaceRoleData.permissions = permissions;
          if (role_name !== undefined) spaceRoleData.role = role_name;
          if (subtitle !== undefined) spaceRoleData.subtitle = subtitle;
          if (datasource_ids !== undefined) spaceRoleData.datasource_ids = datasource_ids;
          if (component_ids !== undefined) spaceRoleData.component_ids = component_ids;
          if (branch_ids !== undefined) spaceRoleData.branch_ids = branch_ids;
          if (allowed_languages !== undefined) spaceRoleData.allowed_languages = allowed_languages;
          if (asset_folder_ids !== undefined) spaceRoleData.asset_folder_ids = asset_folder_ids;
    
          const payload = { space_role: spaceRoleData };
          const data = await apiPut(`/space_roles/${space_role_id}`, payload);
          return createJsonResponse(data);
        } catch (error) {
          if (error instanceof APIError) {
            return createErrorResponse(error);
          }
          throw error;
        }
      }
    );
  • Type definition for SpaceRole, which is the domain model used/schematized by the update_space_role tool.
    export interface SpaceRole {
      id: number;
      role: string;
      subtitle: string | null;
      allowed_paths: number[];
      field_permissions: string[];
      permissions: string[];
      datasource_ids: number[];
      component_ids: number[];
      branch_ids: number[];
      allowed_languages: string[];
      asset_folder_ids: number[];
      readonly_field_permissions: string[];
    }
  • Registration call that adds all space role tools (including update_space_role) to the MCP server.
    registerSpaceRoles(server);
  • Helper function apiPut used by update_space_role to make the PUT HTTP request to the Storyblok Management API.
    export async function apiPut<T = unknown>(
      path: string,
      body: unknown
    ): Promise<T> {
      const url = buildManagementUrl(path);
      const response = await fetch(url, {
        method: 'PUT',
        headers: getManagementHeaders(),
        body: JSON.stringify(body),
      });
      return handleResponse<T>(response, url);
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It states it updates configuration via the API, but does not disclose side effects, auth requirements, or idempotency. Adequate but minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, no wasted words, directly to the point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, no annotations, and 12 parameters. The description is too short to address the tool's complexity; it lacks details on success/failure behavior or parameter effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the input schema already describes all 12 parameters. The description adds no extra parameter information beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb (updates) and the resource (space role's configuration), and distinguishes from sibling tools like create_space_role and delete_space_role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives (e.g., create_space_role), nor any prerequisites or exclusions. The description is too generic.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hypescale/storyblok-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server