Get LaunchNotes Project
launchnotes_get_projectRetrieve complete project details including customization settings, colors, custom code, and feature flags from LaunchNotes.
Instructions
Retrieve complete details for a LaunchNotes project, including all customization settings, colors, custom code, and feature flags.
Args:
project_id (string): The ID of the project to retrieve
response_format ('json' | 'markdown'): Output format (default: 'markdown')
Returns: For JSON format: Complete project object with all fields For Markdown format: Formatted project details with sections for colors, custom code, and features
Use Cases:
"Show me my project's current custom CSS"
"What are the color values for project X?"
"Get all settings for my LaunchNotes project"
Error Handling:
Returns "Project not found" if the project ID doesn't exist
Returns "Authentication failed" if the API token is invalid
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | The ID of the LaunchNotes project to retrieve | |
| response_format | No | Output format: 'json' for structured data, 'markdown' for human-readable | markdown |
Implementation Reference
- src/projects/tools.ts:60-96 (handler)The main handler function that executes the launchnotes_get_project tool logic: fetches the project data using GraphQL query, handles JSON or Markdown response formats, and manages errors.
async (params: GetProjectInput) => { try { const result = await getProject(client, params.project_id); const project = result.project; if (params.response_format === RESPONSE_FORMAT.JSON) { return { content: [ { type: "text", text: JSON.stringify(project, null, 2), }, ], }; } // Markdown format return { content: [ { type: "text", text: formatProjectMarkdown(project), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error retrieving project: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } - src/projects/schemas.ts:24-36 (schema)Zod input schema for the tool, validating project_id (required string) and response_format (optional 'json' or 'markdown').
/** * Schema for launchnotes_get_project */ export const GetProjectSchema = z .object({ project_id: z .string() .min(1, "Project ID is required") .describe("The ID of the LaunchNotes project to retrieve"), response_format: responseFormatSchema, }) .strict(); - src/projects/tools.ts:30-97 (registration)Registers the launchnotes_get_project tool with the MCP server, defining title, description, input schema, annotations, and attaching the handler function.
server.registerTool( "launchnotes_get_project", { title: "Get LaunchNotes Project", description: `Retrieve complete details for a LaunchNotes project, including all customization settings, colors, custom code, and feature flags. Args: - project_id (string): The ID of the project to retrieve - response_format ('json' | 'markdown'): Output format (default: 'markdown') Returns: For JSON format: Complete project object with all fields For Markdown format: Formatted project details with sections for colors, custom code, and features Use Cases: - "Show me my project's current custom CSS" - "What are the color values for project X?" - "Get all settings for my LaunchNotes project" Error Handling: - Returns "Project not found" if the project ID doesn't exist - Returns "Authentication failed" if the API token is invalid`, inputSchema: GetProjectSchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, }, async (params: GetProjectInput) => { try { const result = await getProject(client, params.project_id); const project = result.project; if (params.response_format === RESPONSE_FORMAT.JSON) { return { content: [ { type: "text", text: JSON.stringify(project, null, 2), }, ], }; } // Markdown format return { content: [ { type: "text", text: formatProjectMarkdown(project), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error retrieving project: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } ); - src/projects/queries.ts:80-87 (helper)Helper function that executes the GraphQL query to retrieve detailed project information by ID.
export async function getProject( client: GraphQLClient, projectId: string ): Promise<{ project: LaunchNotesProject; }> { return client.execute(GET_PROJECT_QUERY, { id: projectId }); } - src/projects/formatters.ts:10-84 (helper)Helper function that formats the retrieved project data into a structured Markdown report with sections for project info, colors, custom code, and feature flags.
export function formatProjectMarkdown(project: LaunchNotesProject): string { const sections: string[] = []; // Basic info sections.push(`# Project: ${project.name}`); sections.push(`**ID:** ${project.id}`); sections.push(`**Title:** ${project.title}`); sections.push(`**Slug:** ${project.slug}`); sections.push(`**URL:** ${project.publicPageUrl}`); if (project.description) { sections.push(`**Description:** ${project.description}`); } if (project.heading) { sections.push(`**Heading:** ${project.heading}`); } if (project.subheading) { sections.push(`**Subheading:** ${project.subheading}`); } // Colors const colors: string[] = []; if (project.primaryColor) colors.push(`- Primary: ${project.primaryColor}`); if (project.secondaryColor) colors.push(`- Secondary: ${project.secondaryColor}`); if (project.primaryTextColor) colors.push(`- Primary Text: ${project.primaryTextColor}`); if (project.secondaryTextColor) colors.push(`- Secondary Text: ${project.secondaryTextColor}`); if (project.grayColor) colors.push(`- Gray: ${project.grayColor}`); if (project.lightGrayColor) colors.push(`- Light Gray: ${project.lightGrayColor}`); if (project.offWhiteColor) colors.push(`- Off White: ${project.offWhiteColor}`); if (project.whiteColor) colors.push(`- White: ${project.whiteColor}`); if (project.colorTheme) colors.push(`- Theme: ${project.colorTheme}`); if (colors.length > 0) { sections.push(`\n## Colors\n${colors.join("\n")}`); } // Custom code const customCode: string[] = []; if (project.customCss) { customCode.push(`### Custom CSS\n\`\`\`css\n${project.customCss.substring(0, 500)}${project.customCss.length > 500 ? "..." : ""}\n\`\`\``); } if (project.customHead) { customCode.push(`### Custom Head\n\`\`\`html\n${project.customHead.substring(0, 500)}${project.customHead.length > 500 ? "..." : ""}\n\`\`\``); } if (project.customHeader) { customCode.push(`### Custom Header\n\`\`\`html\n${project.customHeader.substring(0, 500)}${project.customHeader.length > 500 ? "..." : ""}\n\`\`\``); } if (project.customFooter) { customCode.push(`### Custom Footer\n\`\`\`html\n${project.customFooter.substring(0, 500)}${project.customFooter.length > 500 ? "..." : ""}\n\`\`\``); } if (project.customIndexHero) { customCode.push(`### Custom Index Hero\n\`\`\`html\n${project.customIndexHero.substring(0, 500)}${project.customIndexHero.length > 500 ? "..." : ""}\n\`\`\``); } if (customCode.length > 0) { sections.push(`\n## Custom Code\n${customCode.join("\n\n")}`); } // Features sections.push("\n## Features"); sections.push(`- Feedback: ${project.feedbackEnabled ? "✓ Enabled" : "✗ Disabled"}`); sections.push(`- Roadmap: ${project.roadmapEnabled ? "✓ Enabled" : "✗ Disabled"}`); sections.push(`- Ideas: ${project.ideasEnabled ? "✓ Enabled" : "✗ Disabled"}`); sections.push(`- RSS Feed: ${project.rssFeedEnabled ? "✓ Enabled" : "✗ Disabled"}`); sections.push(`- Voting: ${project.votingEnabled ? "✓ Enabled" : "✗ Disabled"}`); sections.push(`- SEO Indexing: ${project.noindex ? "✗ Disabled (noindex)" : "✓ Enabled"}`); if (project.rssFeedUrl) { sections.push(`\n**RSS Feed URL:** ${project.rssFeedUrl}`); } sections.push(`\n*Last updated: ${new Date(project.updatedAt).toLocaleString()}*`); return sections.join("\n"); }