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
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | The project ID |
Implementation Reference
- src/tools/list-secrets.ts:10-47 (handler)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") }] }; } - src/tools/list-secrets.ts:6-8 (schema)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), ); - src/errors.ts:18-85 (helper)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 }; } - src/keystore.ts:42-48 (helper)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]; }