Skip to main content
Glama

list_secrets

Retrieve configured secret keys for a project to verify which secrets are available without exposing their values.

Instructions

List secret keys for a project (values are not shown). Useful for checking which secrets are configured.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesThe project ID

Implementation Reference

  • Main handler function that lists secret keys for a project. Validates the project exists in keystore, makes API request to /admin/v1/projects/{project_id}/secrets, and formats the response as a markdown list (without showing secret values for security).
    export async function handleListSecrets(args: {
      project_id: string;
    }): Promise<{ content: Array<{ type: "text"; text: string }>; isError?: boolean }> {
      const project = getProject(args.project_id);
      if (!project) return projectNotFound(args.project_id);
    
      const res = await apiRequest(`/admin/v1/projects/${args.project_id}/secrets`, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${project.service_key}`,
        },
      });
    
      if (!res.ok) return formatApiError(res, "listing secrets");
    
      const body = res.body as { secrets: Array<{ key: string }> };
    
      if (body.secrets.length === 0) {
        return {
          content: [
            {
              type: "text",
              text: `## Secrets\n\n_No secrets set. Use \`set_secret\` to add one._`,
            },
          ],
        };
      }
    
      const lines = [
        `## Secrets (${body.secrets.length})`,
        ``,
        ...body.secrets.map((s) => `- \`${s.key}\``),
        ``,
        `_Values are not shown for security._`,
      ];
    
      return { content: [{ type: "text", text: lines.join("\n") }] };
    }
  • Input schema definition using Zod. Defines the required 'project_id' parameter as a string with description.
    export const listSecretsSchema = {
      project_id: z.string().describe("The project ID"),
    };
  • src/index.ts:183-188 (registration)
    Tool registration with MCP server. Registers 'list_secrets' tool with description 'List secret keys for a project (values are not shown)', binds the schema and handler.
    server.tool(
      "list_secrets",
      "List secret keys for a project (values are not shown). Useful for checking which secrets are configured.",
      listSecretsSchema,
      async (args) => handleListSecrets(args),
    );
  • Helper function that formats API error responses into user-friendly MCP tool results. Includes HTTP status, error message, hints, and actionable next steps based on status codes.
    export function formatApiError(
      res: { status: number; body: unknown },
      context: string,
    ): ToolResult {
      const body =
        res.body && typeof res.body === "object"
          ? (res.body as Record<string, unknown>)
          : null;
    
      // Primary message — try message (PostgREST), then error, then fallback
      const primary = body
        ? (body.message as string) || (body.error as string) || "Unknown error"
        : typeof res.body === "string"
          ? (res.body as string)
          : "Unknown error";
    
      const lines: string[] = [
        `Error ${context}: ${primary} (HTTP ${res.status})`,
      ];
    
      // Supplementary fields from the API response
      if (body) {
        if (body.hint) lines.push(`Hint: ${body.hint}`);
        if (body.retry_after)
          lines.push(`Retry after: ${body.retry_after} seconds`);
        if (body.expires_at) lines.push(`Expires: ${body.expires_at}`);
        if (body.renew_url) lines.push(`Renew URL: ${body.renew_url}`);
        if (body.usage) {
          const u = body.usage as Record<string, unknown>;
          const parts: string[] = [];
          if (u.api_calls !== undefined)
            parts.push(`API calls: ${u.api_calls}/${u.limit || "?"}`);
          if (u.storage_bytes !== undefined)
            parts.push(
              `Storage: ${u.storage_bytes}/${u.storage_limit || "?"} bytes`,
            );
          if (parts.length > 0) lines.push(`Usage: ${parts.join(", ")}`);
        }
      }
    
      // Actionable guidance based on HTTP status
      switch (res.status) {
        case 401:
          lines.push(
            `\nNext step: Re-provision the project with \`provision_postgres_project\`, or check that your service key is correct.`,
          );
          break;
        case 403:
          lines.push(
            `\nNext step: The project lease may have expired. Use \`get_usage\` to check status, or \`renew_project\` to extend the lease.`,
          );
          break;
        case 404:
          lines.push(
            `\nNext step: Check that the resource name and project ID are correct.`,
          );
          break;
        case 429:
          lines.push(`\nNext step: Rate limit hit. Wait and retry.`);
          break;
        default:
          if (res.status >= 500) {
            lines.push(`\nNext step: Server error. Try again in a moment.`);
          }
      }
    
      return { content: [{ type: "text", text: lines.join("\n") }], isError: true };
    }
  • Helper function that retrieves a stored project from the local keystore by project ID. Returns project credentials including service_key needed for API authentication.
    export function getProject(
      projectId: string,
      path?: string,
    ): StoredProject | undefined {
      const store = loadKeyStore(path);
      return store.projects[projectId];
    }

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/kychee-com/run402'

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