netlify-coding-rules
Apply coding rules to ensure proper implementation of Netlify serverless functions, edge functions, blobs, and other services before development.
Instructions
ALWAYS call when writing serverless or Netlify code. required step before creating or editing any type of functions, Netlify sdk/library usage, etc.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| creationType | Yes |
Implementation Reference
- netlify-mcp.ts:82-104 (registration)Registers the 'netlify-coding-rules' tool, including its input schema (creationType enum), description, and inline handler function that fetches and returns Netlify coding context.server.registerTool( "netlify-coding-rules", { description: "ALWAYS call when writing serverless or Netlify code. required step before creating or editing any type of functions, Netlify sdk/library usage, etc.", inputSchema:{ creationType: creationTypeEnum }, annotations: { readOnlyHint: true } }, async ({creationType}: {creationType: z.infer<typeof creationTypeEnum>}) => { checkCompatibility(); const context = await getNetlifyCodingContext(creationType); const text = context?.content || ''; return ({ content: [{type: "text", text}] }); } );
- netlify-mcp.ts:93-103 (handler)The core handler function for the tool, which calls getNetlifyCodingContext and returns the context content as text.async ({creationType}: {creationType: z.infer<typeof creationTypeEnum>}) => { checkCompatibility(); const context = await getNetlifyCodingContext(creationType); const text = context?.content || ''; return ({ content: [{type: "text", text}] }); }
- netlify-mcp.ts:84-92 (schema)Tool schema definition including input schema for creationType (dynamic enum from context scopes) and annotations.{ description: "ALWAYS call when writing serverless or Netlify code. required step before creating or editing any type of functions, Netlify sdk/library usage, etc.", inputSchema:{ creationType: creationTypeEnum }, annotations: { readOnlyHint: true } },
- src/context/coding-context.ts:79-124 (helper)Main helper function that implements the context fetching logic for the tool, including caching and fetching from remote endpoint based on consumer config.export async function getNetlifyCodingContext(contextKey: string): Promise<ContextFile | undefined> { const now = Date.now(); // Check if we have a cached version that's less than 10 minutes old // If so, return the cached version otherwise fetch fresh data if (contextCache[contextKey] && (now - contextCache[contextKey].timestamp) < TEN_MINUTES_MS) { return contextCache[contextKey]?.data; } const consumer = await getContextConsumerConfig(); if(!consumer || !consumer.contextScopes[contextKey]?.endpoint){ console.error('unable to find the context you are looking for. Check docs.netlify.com for more information.'); return; } const endpoint = new URL(consumer.contextScopes[contextKey].endpoint); endpoint.searchParams.set('consumer', getConsumer()); let data = ''; try { const response = await unauthenticatedFetch(endpoint.toString()) data = await response.text() as string; if(!data){ console.error('unable to find the context you are looking for. Check docs.netlify.com for more information.'); return; } const contextFile: ContextFile = { key: contextKey, config: consumer.contextScopes[contextKey], content: data }; contextCache[contextKey] = { data: contextFile, timestamp: Date.now() }; } catch (error) { console.error('Error fetching context:', error); } return contextCache[contextKey]?.data; }
- src/context/coding-context.ts:50-76 (helper)Helper function to load and cache the context consumer configuration, used to determine available context scopes and endpoints.export async function getContextConsumerConfig(){ const now = Date.now(); // Return cached consumer if it exists and is less than 10 minutes old if(contextConsumer && (now - contextConsumerTimestamp) < TEN_MINUTES_MS) { return contextConsumer; } try { const response = await unauthenticatedFetch(`https://docs.netlify.com/ai-context/context-consumers`) const data = await response.json() as ConsumersData; if(data?.consumers?.length > 0){ contextConsumer = data.consumers.find(c => c.key === getConsumer()); } } catch (error) { appendErrorToLog('Error fetching context consumers:', error); } // Update timestamp when we get fresh data if (contextConsumer) { contextConsumerTimestamp = Date.now(); } return contextConsumer; }