Skip to main content
Glama

build-toolset

Create and customize a personalized toolset by selecting specific tools for your workflow. Define names and include tools by their identifiers to streamline tasks and improve efficiency on the hypertool-mcp server.

Instructions

Build and save a custom toolset by selecting specific tools. Like assembling tools from a workshop - pick the exact tools you need for a specific task or workflow. You must specify which tools to include. Each tool must specify either namespacedName or refId for identification. Example: {name: 'dev-essentials', tools: [{namespacedName: 'git.status'}, {namespacedName: 'docker.ps'}], autoEquip: true} creates and immediately equips a development toolset.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
autoEquipNoAutomatically equip this toolset after creation (default: false)
descriptionNoOptional description of what this toolset is for (e.g., 'Essential tools for web development')
nameYesName for the new toolset. Use lowercase with hyphens (e.g., 'dev-essentials', 'git-workflow', 'debug-kit')
toolsYesArray of tools to include in the toolset. Each tool must specify either namespacedName or refId for identification. Use list-available-tools to see available options.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
metaYesOperation metadata
toolsetNoToolset information (only present if successful)

Implementation Reference

  • The main handler function for the 'build-toolset' MCP tool. It receives input arguments, calls toolsetManager.buildToolset to perform the actual creation, handles auto-equip, and returns the result.
    handler: async (args: any) => {
      if (deps.discoveryEngine) {
        const result = await deps.toolsetManager.buildToolset(
          args?.name || "",
          args?.tools || [],
          {
            description: args?.description,
            autoEquip: args?.autoEquip,
          }
        );
    
        // Auto-exit to normal mode if autoEquip succeeded
        if (args?.autoEquip && result.meta?.success && onModeChangeRequest) {
          onModeChangeRequest();
        }
    
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify(result),
            },
          ],
          structuredContent: result,
        };
      } else {
        return {
          content: [
            {
              type: "text",
              text: "❌ **Tool discovery not available**\n\nDiscovery engine is not initialized. Server may not be fully started.",
            },
          ],
        };
      }
  • Tool definition including input schema for validation and output schema reference. Defines the structure expected for input parameters like name, tools array, description, and autoEquip.
    export const buildToolsetDefinition: Tool = {
      name: "build-toolset",
      description:
        "Build and save a custom toolset by selecting specific tools. Like assembling tools from a workshop - pick the exact tools you need for a specific task or workflow. You must specify which tools to include. Each tool must specify either namespacedName or refId for identification. Example: {name: 'dev-essentials', tools: [{namespacedName: 'git.status'}, {namespacedName: 'docker.ps'}], autoEquip: true} creates and immediately equips a development toolset.",
      inputSchema: {
        type: "object" as const,
        properties: {
          name: {
            type: "string",
            description:
              "Name for the new toolset. Use lowercase with hyphens (e.g., 'dev-essentials', 'git-workflow', 'debug-kit')",
            pattern: "^[a-z0-9-]+$",
            minLength: 2,
            maxLength: 50,
          },
          tools: {
            type: "array",
            description:
              "Array of tools to include in the toolset. Each tool must specify either namespacedName or refId for identification. Use list-available-tools to see available options.",
            minItems: 1,
            maxItems: 100,
            items: {
              type: "object",
              properties: {
                namespacedName: {
                  type: "string",
                  description:
                    "Tool reference by namespaced name (e.g., 'git.status', 'docker.ps')",
                },
                refId: {
                  type: "string",
                  description:
                    "Tool reference by unique hash identifier (e.g., 'abc123def456...')",
                },
              },
              oneOf: [{ required: ["namespacedName"] }, { required: ["refId"] }],
              additionalProperties: false,
            },
          },
          description: {
            type: "string",
            description:
              "Optional description of what this toolset is for (e.g., 'Essential tools for web development')",
            maxLength: 200,
          },
          autoEquip: {
            type: "boolean",
            description:
              "Automatically equip this toolset after creation (default: false)",
          },
        },
        required: ["name", "tools"],
        additionalProperties: false,
      },
      outputSchema: buildToolsetResponseSchema as any,
    };
  • Zod schema and JSON schema for the build-toolset response, defining the output structure including meta (success, error) and toolset info.
    export const buildToolsetResponseZodSchema = z.object({
      meta: z
        .object({
          success: z
            .boolean()
            .describe("Whether the toolset was successfully created"),
          toolsetName: z
            .string()
            .optional()
            .describe("Name of the created toolset"),
          autoEquipped: z
            .boolean()
            .optional()
            .describe(
              "Whether the toolset was automatically equipped after creation"
            ),
          error: z
            .string()
            .optional()
            .describe("Error message if the operation failed"),
        })
        .describe("Operation metadata"),
      toolset: toolsetInfoZodSchema
        .optional()
        .describe("Toolset information (only present if successful)"),
    });
    
    /**
     * Zod schema for equip toolset response
     */
    export const equipToolsetResponseZodSchema = z.object({
      success: z
        .boolean()
        .describe("Whether the toolset was successfully equipped"),
      error: z
        .string()
        .optional()
        .describe("Error message if the operation failed"),
      toolset: toolsetInfoZodSchema
        .optional()
        .describe("Equipped toolset information (only present if successful)"),
    });
    
    /**
     * Zod schema for get active toolset response
     */
    export const getActiveToolsetResponseZodSchema = z.object({
      equipped: z.boolean().describe("Whether a toolset is currently equipped"),
      toolset: toolsetInfoZodSchema
        .optional()
        .describe("Toolset information (only present if equipped)"),
      serverStatus: z
        .object({
          totalConfigured: z
            .number()
            .describe("Total number of configured servers"),
          enabled: z.number().describe("Number of enabled servers"),
          available: z.number().describe("Number of available servers"),
          unavailable: z.number().describe("Number of unavailable servers"),
          disabled: z.number().describe("Number of disabled servers"),
        })
        .optional()
        .describe("Server status summary"),
      toolSummary: z
        .object({
          currentlyExposed: z
            .number()
            .describe("Number of tools currently exposed"),
          totalDiscovered: z.number().describe("Total number of discovered tools"),
          filteredOut: z.number().describe("Number of tools filtered out"),
        })
        .optional()
        .describe("Tool summary information"),
      exposedTools: z
        .record(z.array(toolInfoResponseZodSchema))
        .describe("Tools grouped by server with full details"),
      unavailableServers: z
        .array(z.string())
        .describe("List of unavailable server names"),
      warnings: z.array(z.string()).describe("List of warnings"),
      context: contextInfoZodSchema
        .optional()
        .describe("Context usage information for the exposed tools"),
    });
    
    /**
     * TypeScript types inferred from Zod schemas
     */
    export type ContextInfo = z.infer<typeof contextInfoZodSchema>;
    export type ToolInfoResponse = z.infer<typeof toolInfoResponseZodSchema>;
    export type ListSavedToolsetsResponse = z.infer<
      typeof listSavedToolsetsResponseZodSchema
    >;
    export type BuildToolsetResponse = z.infer<
      typeof buildToolsetResponseZodSchema
    >;
    export type EquipToolsetResponse = z.infer<
      typeof equipToolsetResponseZodSchema
    >;
    export type GetActiveToolsetResponse = z.infer<
      typeof getActiveToolsetResponseZodSchema
    >;
    
    /**
     * JSON Schemas generated from Zod schemas using zod-to-json-schema
     * Note: Using $refStrategy: 'none' to avoid $ref definitions for MCP compatibility
     */
    export const serverConfigSchema = zodToJsonSchema(serverConfigZodSchema, {
      $refStrategy: "none",
    });
    
    export const toolsetInfoSchema = zodToJsonSchema(toolsetInfoZodSchema, {
      $refStrategy: "none",
    });
    
    export const listSavedToolsetsResponseSchema = zodToJsonSchema(
      listSavedToolsetsResponseZodSchema,
      {
        $refStrategy: "none",
      }
    );
    
    export const buildToolsetResponseSchema = zodToJsonSchema(
      buildToolsetResponseZodSchema,
      {
        $refStrategy: "none",
      }
    );
  • Registration of the build-toolset tool factory in the configuration tools factories array.
    export const CONFIG_TOOL_FACTORIES: ToolModuleFactory[] = [
      createListAvailableToolsModule,
      createBuildToolsetModule,
      createListSavedToolsetsModule,
      createEquipToolsetModule,
      createDeleteToolsetModule,
      createUnequipToolsetModule,
      createGetActiveToolsetModule,
      createAddToolAnnotationModule,
      createListPersonasModule, // Persona management tool
      createExitConfigurationModeModule,
    ];
  • Core helper method in ToolsetManager that implements the toolset building logic: validates inputs, resolves tools, saves to user preferences, generates detailed info, and handles auto-equip.
    async buildToolset(
      name: string,
      tools: DynamicToolReference[],
      options: {
        description?: string;
        autoEquip?: boolean;
      } = {}
    ): Promise<BuildToolsetResponse> {
      try {
        // Validate toolset name format
        const namePattern = /^[a-z0-9-]+$/;
        if (!namePattern.test(name)) {
          return {
            meta: {
              success: false,
              error:
                "Invalid toolset name format. Use only lowercase letters, numbers, and hyphens (a-z, 0-9, -)",
            },
          };
        }
    
        if (name.length < 2 || name.length > 50) {
          return {
            meta: {
              success: false,
              error: "Toolset name must be between 2 and 50 characters",
            },
          };
        }
    
        if (!tools || tools.length === 0) {
          return {
            meta: {
              success: false,
              error: "Toolset must include at least one tool",
            },
          };
        }
    
        // Validate tool references if discovery engine is available
        if (this.discoveryEngine) {
          const validationResult = this.validateToolReferences(tools);
          if (!validationResult.valid) {
            return {
              meta: {
                success: false,
                error: `Invalid tool references: ${validationResult.invalidReferences.join(", ")}`,
              },
            };
          }
        }
    
        // Check if toolset already exists
        const preferences = await import("../../../config/preferenceStore.js");
        const loadToolsetsFromPreferences = preferences.loadStoredToolsets;
        const saveToolsetsToPreferences = preferences.saveStoredToolsets;
        const stored = await loadToolsetsFromPreferences();
    
        if (stored[name]) {
          return {
            meta: {
              success: false,
              error: `Toolset "${name}" already exists. Use a different name or delete the existing toolset first.`,
            },
          };
        }
    
        // Create toolset configuration
        const config: ToolsetConfig = {
          name,
          description: options.description,
          version: "1.0.0",
          createdAt: new Date(),
          tools,
        };
    
        // Validate configuration
        const validation = validateToolsetConfig(config);
        if (!validation.valid) {
          return {
            meta: {
              success: false,
              error: `Invalid toolset configuration: ${validation.errors.join(", ")}`,
            },
          };
        }
    
        // Save toolset
        stored[name] = config;
        await saveToolsetsToPreferences(stored);
    
        // Generate detailed toolset information
        const toolsetInfo = await this.generateToolsetInfo(config);
    
        const result = {
          meta: {
            success: true,
            toolsetName: name,
            autoEquipped: false,
          },
          toolset: toolsetInfo,
        };
    
        // Auto-equip if requested
        if (options.autoEquip) {
          const equipResult = await this.equipToolset(name);
          if (equipResult.success) {
            result.meta.autoEquipped = true;
            result.toolset.active = true;
          }
        }
    
        return result;
      } catch (error) {
        return {
          meta: {
            success: false,
            error: `Failed to create toolset: ${error instanceof Error ? error.message : String(error)}`,
          },
        };
      }
    }

Tool Definition Quality

Score is being calculated. Check back soon.

Install Server

Other Tools

Related 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/toolprint/hypertool-mcp'

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