Skip to main content
Glama

Netlify MCP Server

Official
by netlify
coding-context.ts3.41 kB
import { appendErrorToLog } from "../utils/logging.js" import { unauthenticatedFetch } from "../utils/api-networking.ts"; export interface ConsumersData { consumers: ConsumerConfig[] } export interface ContextConfig { scope: string glob?: string shared?: string[] endpoint?: string } export interface ContextFile { key: string config: ContextConfig content: string } // Cache wrapper interface to store timestamp with context file interface CachedContext { data: ContextFile; timestamp: number; } export interface ConsumerConfig { key: string presentedName: string consumerProcessCmd?: string path: string ext: string truncationLimit?: number contextScopes: Record<string, ContextConfig> hideFromCLI?: boolean consumerTrigger?: string } let contextConsumer: ConsumerConfig | undefined; const contextCache: Record<string, CachedContext> = {}; const TEN_MINUTES_MS = 10 * 60 * 1000; const getConsumer = () => 'netlify-mcp'; // when we last loaded the consumer config let contextConsumerTimestamp: number = 0; // load the consumer configuration for the MCP so // we can share all of the available context for the // client to select from. 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; } 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; }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/netlify/netlify-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server