List LaunchNotes Announcements
launchnotes_list_announcementsRetrieve announcements from a LaunchNotes project with options to filter by state, sort by date fields, and control output format.
Instructions
List all announcements in a LaunchNotes project with optional filtering and ordering.
Args:
project_id (string): The ID of the project
state ('draft' | 'scheduled' | 'published' | 'archived', optional): Filter by state
limit (number, optional): Number to return (max 100, default: 50)
order_by_field ('publishedAt' | 'createdAt' | 'updatedAt', optional): Field to sort by
order_by_direction ('ASC' | 'DESC', optional): Sort direction (ascending or descending)
response_format ('json' | 'markdown'): Output format (default: 'markdown')
Returns: List of announcements with id, headline, state, dates, and slug
Use Cases:
"List all announcements in my LaunchNotes project"
"Show me all published announcements ordered by published date"
"List draft announcements"
"Show scheduled announcements sorted by creation date descending"
Note: To use ordering, both order_by_field and order_by_direction must be specified. Default ordering (when not specified) is by updatedAt descending.
Error Handling:
Returns "Project not found" if project ID doesn't exist
Returns "Authentication failed" if API token is invalid
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | The ID of the LaunchNotes project | |
| state | No | Filter by announcement state | |
| limit | No | Number of announcements to return (max 100) | |
| order_by_field | No | Field to sort by | |
| order_by_direction | No | Sort direction: 'ASC' for ascending, 'DESC' for descending | |
| response_format | No | Output format: 'json' for structured data, 'markdown' for human-readable | markdown |
Implementation Reference
- src/announcements/tools.ts:80-130 (handler)Inline handler function that executes the launchnotes_list_announcements tool logic: fetches announcements using GraphQL, supports JSON or Markdown output formats, and handles errors.
async (params: ListAnnouncementsInput) => { try { const result = await listAnnouncements(client, params.project_id, { state: params.state, first: params.limit, orderByField: params.order_by_field, orderByDirection: params.order_by_direction, }); const announcements = result.project.announcements.nodes; if (params.response_format === RESPONSE_FORMAT.JSON) { return { content: [ { type: "text", text: JSON.stringify( { total: announcements.length, announcements, hasMore: result.project.announcements.pageInfo.hasNextPage, }, null, 2 ), }, ], }; } // Markdown format return { content: [ { type: "text", text: formatAnnouncementListMarkdown(announcements), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error listing announcements: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } - src/announcements/schemas.ts:43-61 (schema)Zod schema defining the input parameters for launchnotes_list_announcements: project_id (required), state, limit, ordering fields, and response_format.
export const ListAnnouncementsSchema = z .object({ project_id: z .string() .min(1, "Project ID is required") .describe("The ID of the LaunchNotes project"), state: announcementStateSchema, limit: z .number() .min(1) .max(100) .default(50) .optional() .describe("Number of announcements to return (max 100)"), order_by_field: orderByFieldSchema, order_by_direction: sortDirectionSchema, response_format: responseFormatSchema, }) .strict(); - src/announcements/tools.ts:43-131 (registration)MCP tool registration for launchnotes_list_announcements, including title, detailed description, input schema reference, annotations, and inline handler.
server.registerTool( "launchnotes_list_announcements", { title: "List LaunchNotes Announcements", description: `List all announcements in a LaunchNotes project with optional filtering and ordering. Args: - project_id (string): The ID of the project - state ('draft' | 'scheduled' | 'published' | 'archived', optional): Filter by state - limit (number, optional): Number to return (max 100, default: 50) - order_by_field ('publishedAt' | 'createdAt' | 'updatedAt', optional): Field to sort by - order_by_direction ('ASC' | 'DESC', optional): Sort direction (ascending or descending) - response_format ('json' | 'markdown'): Output format (default: 'markdown') Returns: List of announcements with id, headline, state, dates, and slug Use Cases: - "List all announcements in my LaunchNotes project" - "Show me all published announcements ordered by published date" - "List draft announcements" - "Show scheduled announcements sorted by creation date descending" Note: To use ordering, both order_by_field and order_by_direction must be specified. Default ordering (when not specified) is by updatedAt descending. Error Handling: - Returns "Project not found" if project ID doesn't exist - Returns "Authentication failed" if API token is invalid`, inputSchema: ListAnnouncementsSchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, }, async (params: ListAnnouncementsInput) => { try { const result = await listAnnouncements(client, params.project_id, { state: params.state, first: params.limit, orderByField: params.order_by_field, orderByDirection: params.order_by_direction, }); const announcements = result.project.announcements.nodes; if (params.response_format === RESPONSE_FORMAT.JSON) { return { content: [ { type: "text", text: JSON.stringify( { total: announcements.length, announcements, hasMore: result.project.announcements.pageInfo.hasNextPage, }, null, 2 ), }, ], }; } // Markdown format return { content: [ { type: "text", text: formatAnnouncementListMarkdown(announcements), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error listing announcements: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } ); - src/announcements/queries.ts:156-197 (helper)Core helper function that constructs and executes the GraphQL query to list announcements from the LaunchNotes API, applying filters and ordering.
export async function listAnnouncements( client: GraphQLClient, projectId: string, filters?: { state?: string; first?: number; after?: string; orderByField?: string; orderByDirection?: string; } ): Promise<{ project: { announcements: { nodes: LaunchNotesAnnouncementList[]; pageInfo: { hasNextPage: boolean; endCursor?: string; }; }; }; }> { const variables: Record<string, unknown> = { projectId, first: filters?.first || 50, after: filters?.after, }; // Add state filter if provided if (filters?.state) { variables.state = filters.state; } // Add orderBy if field and direction are provided if (filters?.orderByField && filters?.orderByDirection) { variables.orderBy = { field: filters.orderByField, sort: filters.orderByDirection, }; } return client.execute(LIST_ANNOUNCEMENTS_QUERY, variables); } - Helper utility to format the fetched announcements list into a human-readable Markdown table/list for the tool's markdown response format.
export function formatAnnouncementListMarkdown( announcements: LaunchNotesAnnouncementList[] ): string { if (announcements.length === 0) { return "No announcements found."; } const lines = [`# Announcements (${announcements.length})`, ""]; announcements.forEach((ann) => { lines.push(`## ${ann.headline}`); lines.push(`- **ID:** ${ann.id}`); lines.push(`- **State:** ${ann.state}`); lines.push(`- **Slug:** ${ann.slug}`); if (ann.publishedAt) { lines.push( `- **Published:** ${new Date(ann.publishedAt).toLocaleString()}` ); } if (ann.scheduledAt) { lines.push( `- **Scheduled:** ${new Date(ann.scheduledAt).toLocaleString()}` ); } lines.push(`- **Created:** ${new Date(ann.createdAt).toLocaleString()}`); lines.push(""); }); return lines.join("\n"); }