lb_projects_list
List Amazon organic ranking projects with optional filters by region and active status. Returns ASIN, keyword, and service volumes.
Instructions
List Listing Bureau Amazon projects with optional filters. Returns ASIN, keyword, active status, and current service volumes.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| region | No | Filter by Amazon region code (GB accepted as alias for UK) | |
| active | No | Filter by active status |
Implementation Reference
- src/tools/projects.tools.ts:20-38 (handler)The handler function for 'lb_projects_list'. Builds a query object with optional region/active filters, makes a GET request to /api/v1/projects, and returns the formatted result. Catches errors and formats them as error results.
async (params) => { try { const query: Record<string, string> = { marketplace: "amazon" }; if (params.region !== undefined) query.region = normalizeRegion(params.region); if (params.active !== undefined) query.active = String(params.active); const res = await client.request<ProjectListItem[]>( "GET", "/api/v1/projects", undefined, query, "lb_projects_list", ); return formatResult(res.data); } catch (e) { return formatErrorResult(e); } }, ); - src/tools/projects.tools.ts:12-18 (schema)Input schema for lb_projects_list tool. Accepts optional 'region' parameter (validated against ACCEPTED_REGIONS enum, GB alias for UK) and optional 'active' boolean filter.
{ region: z .enum(ACCEPTED_REGIONS) .optional() .describe("Filter by Amazon region code (GB accepted as alias for UK)"), active: z.boolean().optional().describe("Filter by active status"), }, - src/tools/projects.tools.ts:8-38 (registration)Registration of the 'lb_projects_list' tool on the MCP server via server.tool() inside registerProjectsTools(). Called from src/index.ts line 58.
export function registerProjectsTools(server: McpServer, client: LBClient) { server.tool( "lb_projects_list", "List Listing Bureau Amazon projects with optional filters. Returns ASIN, keyword, active status, and current service volumes.", { region: z .enum(ACCEPTED_REGIONS) .optional() .describe("Filter by Amazon region code (GB accepted as alias for UK)"), active: z.boolean().optional().describe("Filter by active status"), }, { readOnlyHint: true }, async (params) => { try { const query: Record<string, string> = { marketplace: "amazon" }; if (params.region !== undefined) query.region = normalizeRegion(params.region); if (params.active !== undefined) query.active = String(params.active); const res = await client.request<ProjectListItem[]>( "GET", "/api/v1/projects", undefined, query, "lb_projects_list", ); return formatResult(res.data); } catch (e) { return formatErrorResult(e); } }, ); - src/utils/regions.ts:29-32 (helper)normalizeRegion helper: maps 'GB' to 'UK', passthrough for all others. Used by the handler to normalize the region parameter.
/** Normalize user-supplied region code: GB -> UK, all others passthrough. */ export function normalizeRegion(region: string): string { return region === "GB" ? "UK" : region; } - src/utils/response.ts:10-54 (helper)formatResult helper: formats a successful API response as an MCP CallToolResult, extracting warnings and balance_warning from the response data.
export function formatResult(data: unknown): CallToolResult { const warnings: string[] = []; let cleaned: Record<string, unknown> | unknown = data; if (data && typeof data === "object") { const obj = { ...(data as Record<string, unknown>) }; // Top-level warning string if ("warning" in obj && typeof obj.warning === "string") { warnings.push(obj.warning); delete obj.warning; } // balance_warning object (independent of warning) if ("balance_warning" in obj && obj.balance_warning && typeof obj.balance_warning === "object") { const bw = obj.balance_warning as Record<string, unknown>; const parts: string[] = []; if (typeof bw.warning === "string" && bw.warning.trim()) parts.push(bw.warning); if (typeof bw.daily_cost_estimate === "number") parts.push(`Daily cost estimate: $${bw.daily_cost_estimate.toFixed(2)}`); if (typeof bw.balance === "number") parts.push(`Balance: $${bw.balance.toFixed(2)}`); if (typeof bw.days_remaining === "number") parts.push(`Days remaining: ${bw.days_remaining.toFixed(1)}`); if (parts.length > 0) warnings.push(parts.join(" | ")); delete obj.balance_warning; } cleaned = obj; } let text = JSON.stringify(cleaned, null, 2); for (const w of warnings) { text += `\n\n⚠️ Warning: ${w}`; } const notice = getUpdateNotice(); if (notice) { text += `\n\n${notice}`; } return { content: [{ type: "text", text }], }; }