Skip to main content
Glama

manage_keys

Control Tailscale authentication keys by listing, creating, or deleting them, with options to set expiry, capabilities, and device-specific configurations for secure network access.

Instructions

Manage Tailscale authentication keys

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keyConfigNoKey configuration (for create operation)
keyIdNoAuthentication key ID (for delete operation)
operationYesKey management operation

Implementation Reference

  • The handler function that implements the logic for the 'manage_keys' tool. It supports 'list', 'create', and 'delete' operations on Tailscale authentication keys using the Tailscale API.
    async function manageKeys(
      args: z.infer<typeof KeyManagementSchema>,
      context: ToolContext,
    ): Promise<CallToolResult> {
      try {
        logger.debug("Managing authentication keys:", args);
    
        switch (args.operation) {
          case "list": {
            const result = await context.api.listAuthKeys();
            if (!result.success) {
              return returnToolError(result.error);
            }
    
            const keys = result.data?.keys || [];
            if (keys.length === 0) {
              return returnToolSuccess("No authentication keys found");
            }
    
            const keyList = keys
              .map((key, index: number) => {
                return `**Key ${index + 1}**
      - ID: ${key.id}
      - Description: ${key.description || "No description"}
      - Created: ${key.created}
      - Expires: ${key.expires}
      - Revoked: ${key.revoked ? "Yes" : "No"}
      - Reusable: ${key.capabilities?.devices?.create?.reusable ? "Yes" : "No"}
      - Preauthorized: ${
        key.capabilities?.devices?.create?.preauthorized ? "Yes" : "No"
      }`;
              })
              .join("\n\n");
    
            return returnToolSuccess(
              `Found ${keys.length} authentication keys:\n\n${keyList}`,
            );
          }
    
          case "create": {
            if (!args.keyConfig) {
              return returnToolError(
                "Key configuration is required for create operation",
              );
            }
    
            const keyConfig = {
              ...args.keyConfig,
              capabilities: {
                devices: {
                  create: {
                    ...args.keyConfig.capabilities?.devices?.create,
                  },
                },
              },
            };
            const result = await context.api.createAuthKey(keyConfig);
            if (!result.success) {
              return returnToolError(result.error);
            }
    
            return returnToolSuccess(
              `Authentication key created successfully:
      - ID: ${result.data?.id}
      - Key: ${result.data?.key}
      - Description: ${result.data?.description || "No description"}`,
            );
          }
    
          case "delete": {
            if (!args.keyId) {
              return returnToolError("Key ID is required for delete operation");
            }
    
            const result = await context.api.deleteAuthKey(args.keyId);
            if (!result.success) {
              return returnToolError(result.error);
            }
    
            return returnToolSuccess(
              `Authentication key ${args.keyId} deleted successfully`,
            );
          }
    
          default:
            return returnToolError(
              "Invalid key operation. Use: list, create, or delete",
            );
        }
      } catch (error: unknown) {
        logger.error("Error managing keys:", error);
        return returnToolError(error);
      }
    }
  • Zod schema defining the input parameters for the 'manage_keys' tool, including operation type and optional configurations for key creation or deletion.
    const KeyManagementSchema = z.object({
      operation: z
        .enum(["list", "create", "delete"])
        .describe("Key management operation"),
      keyConfig: z
        .object({
          description: z.string().optional(),
          expirySeconds: z.number().optional(),
          capabilities: z
            .object({
              devices: z
                .object({
                  create: z
                    .object({
                      reusable: z.boolean().optional(),
                      ephemeral: z.boolean().optional(),
                      preauthorized: z.boolean().optional(),
                      tags: z.array(z.string()).optional(),
                    })
                    .optional(),
                })
                .optional(),
            })
            .optional(),
        })
        .optional()
        .describe("Key configuration (for create operation)"),
      keyId: z
        .string()
        .optional()
        .describe("Authentication key ID (for delete operation)"),
    });
  • Registration of the 'manage_keys' tool within the aclTools module, linking the name, description, input schema, and handler function.
    {
      name: "manage_keys",
      description: "Manage Tailscale authentication keys",
      inputSchema: KeyManagementSchema,
      handler: manageKeys,
    },
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. 'Manage' implies mutation capabilities, but the description doesn't specify what operations are available (list, create, delete), what permissions are required, whether operations are destructive, or what the response format looks like. For a tool with mutation capabilities and no annotation coverage, this is a significant gap in transparency.

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?

The description is extremely concise at just 4 words with no wasted language. It's front-loaded with the core purpose. While it's arguably too brief for a tool with mutation capabilities, it earns full marks for conciseness as every word contributes to the core message.

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?

For a tool with mutation capabilities (create, delete operations), no annotations, no output schema, and complex nested parameters, the description is inadequate. It doesn't explain the available operations, their effects, return values, or error conditions. The agent would need to rely entirely on the input schema to understand how to use this tool, which is insufficient for safe operation.

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 description coverage is 100%, so the schema already documents all 3 parameters (operation, keyConfig, keyId) with their purposes. The description adds no additional parameter semantics beyond what's in the schema. According to the rules, when schema coverage is high (>80%), the baseline is 3 even with no param info in the description.

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

Purpose3/5

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

The description 'Manage Tailscale authentication keys' states the resource (authentication keys) but uses the vague verb 'manage' without specifying what operations are available. It doesn't differentiate from sibling tools like manage_acl or manage_device_tags, which also 'manage' different resources. The purpose is understandable but lacks specificity about the CRUD operations involved.

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?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites, dependencies, or scenarios where this tool is appropriate. Given the sibling tools include various management functions, there's no indication of how this tool fits into the broader context of Tailscale administration.

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

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/HexSleeves/tailscale-mcp'

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