
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
netlify-function-mcp
Advanced tools
A TypeScript package for building Model Context Protocol (MCP) servers as Netlify Functions
A TypeScript package for building Model Context Protocol (MCP) servers as Netlify Functions. Provides a clean wrapper around the standard Netlify Handler pattern while handling all MCP protocol complexity.
Perfect for creating multiple organized MCP servers on a single domain (like mcp.yoursite.com) with full access to Netlify's event and context objects.
Handler interface with full event/context accessnetlify-function-mcp/
├── packages/
│ └── netlify-function-mcp/ # reusable NPM package
│ └── src/
│ ├── index.ts
│ ├── types.ts
│ ├── buildTools.ts
│ ├── mcp-server.ts # MCP protocol implementation
│ ├── mcp-wrapper.ts # Main wrapper function
│ ├── jsonrpc.ts # JSON-RPC 2.0 handling
│ └── errors.ts # Error handling
├── examples/
│ └── netlify-site/ # demo Netlify site with 3 server examples
│ └── netlify/functions/
│ ├── hello-world/ # Basic tools (9 lines)
│ │ ├── hello-world.ts # Simple wrapper usage
│ │ └── tools/
│ │ ├── helloWorld.ts
│ │ ├── calculator.ts
│ │ └── index.ts
│ ├── api-tools/ # API integrations (44 lines)
│ │ ├── api-tools.ts # Custom logging example
│ │ └── tools/
│ │ ├── jsonPlaceholder.ts
│ │ ├── weatherApi.ts
│ │ └── index.ts
│ └── advanced-example/ # Full customization (99 lines)
│ ├── advanced-example.ts # Auth, logging, headers
│ └── tools/
│ ├── requestInfo.ts
│ └── index.ts
└── package.json # monorepo root
npm install netlify-function-mcp @netlify/functions
Create netlify/functions/my-server/my-server.ts:
Simple Usage (default MCP behavior):
import type { Handler } from "@netlify/functions";
import * as toolModules from "./tools";
import { withMcpHandler } from "netlify-function-mcp";
export const handler: Handler = withMcpHandler({
name: "my-mcp-server",
version: "1.0.0",
toolModules
});
Advanced Usage (with access to event and context):
import type { Handler } from "@netlify/functions";
import * as toolModules from "./tools";
import { withMcpHandler, defaultMcpHandler } from "netlify-function-mcp";
export const handler: Handler = withMcpHandler(
{
name: "my-mcp-server",
version: "1.0.0",
toolModules
},
// Custom handler with full access to Netlify event and context
async ({ event, context, mcpServer }) => {
// Custom logging
console.log(`MCP Request: ${event.httpMethod} ${event.path}`, {
userAgent: event.headers['user-agent'],
awsRequestId: context.awsRequestId
});
// Custom authentication, rate limiting, etc.
// const authHeader = event.headers.authorization;
// if (!isValidAuth(authHeader)) {
// return { statusCode: 401, body: 'Unauthorized' };
// }
// Use default MCP behavior with your customizations
return await defaultMcpHandler({ event, context, mcpServer });
}
);
Example tool (netlify/functions/my-server/tools/helloWorld.ts):
import { ToolHandler, ToolMetadata } from "netlify-function-mcp";
export const metadata: ToolMetadata = {
description: "Returns a friendly greeting",
inputSchema: {
type: "object",
properties: { name: { type: "string" } },
required: ["name"]
}
};
export const handler: ToolHandler = async (params: { name: string }) => {
return { message: `Hello, ${params.name}!` };
};
API integration tool (netlify/functions/my-server/tools/weatherApi.ts):
import { ToolHandler, ToolMetadata } from "netlify-function-mcp";
export const metadata: ToolMetadata = {
description: "Fetches current weather for a city",
inputSchema: {
type: "object",
properties: {
city: {
type: "string",
description: "City name (e.g., 'London', 'Tokyo')"
}
},
required: ["city"]
}
};
export const handler: ToolHandler = async (params: { city: string }) => {
// Simple example using Open-Meteo API
const response = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.1¤t_weather=true`);
const data = await response.json() as any;
return {
success: true,
location: params.city,
temperature: data.current_weather.temperature,
description: "Current weather data",
timestamp: new Date().toISOString()
};
};
Export tools from tools/index.ts:
export * as helloWorld from "./helloWorld";
export * as weatherApi from "./weatherApi";
The withMcpHandler() approach preserves the familiar Netlify Handler interface while eliminating all MCP boilerplate:
export const handler: Handler = async (event, context) => {
// 90+ lines of JSON-RPC parsing, CORS handling, error management...
if (event.httpMethod === "OPTIONS") { /* CORS logic */ }
if (event.httpMethod !== "POST") { /* Error handling */ }
const request = parseJsonRpcMessage(event.body);
// More protocol handling...
};
export const handler: Handler = withMcpHandler({
name: "my-server", version: "1.0.0", toolModules
});
// That's it! 9 lines vs 90+
export const handler: Handler = withMcpHandler(config,
async ({ event, context, mcpServer }) => {
console.log(`${event.httpMethod} ${event.path}`, {
userAgent: event.headers['user-agent'],
requestId: context.awsRequestId
});
// Custom auth, rate limiting, etc.
if (!event.headers.authorization) {
return { statusCode: 401, body: 'Unauthorized' };
}
return await defaultMcpHandler({ event, context, mcpServer });
}
);
Handler interfaceAdd to netlify.toml:
[functions]
directory = "netlify/functions"
[[redirects]]
from = "/my-server"
to = "/.netlify/functions/my-server"
status = 200
Start local development:
netlify dev
Open MCP Inspector (v0.16.5+)
Configure connection:
http://localhost:8888/hello-world (basic tools)http://localhost:8888/api-tools (API integrations)http://localhost:8888/advanced-example (custom logging/auth)Click Connect
The inspector will show available tools and allow you to test them.
Deploy multiple specialized MCP servers on a single domain:
mcp.yoursite.com/
├── /hello-world → Basic demonstration tools
├── /api-tools → External API integrations
├── /data-processing → Database & analytics tools
├── /auth-services → Authentication & user management
└── /file-operations → File upload, processing, storage
| Server | Purpose | Lines of Code | Features |
|---|---|---|---|
/hello-world | Basic tools demo | 9 lines | Simple wrapper usage |
/api-tools | API integrations | 44 lines | Custom request logging |
/advanced-example | Full customization | 99 lines | Auth, headers, error handling |
Basic Tools (/hello-world):
helloWorld - Greeting demonstrationcalculator - Math operationsAPI Integrations (/api-tools):
jsonPlaceholder - Blog post fetchingweatherApi - Real weather dataAdvanced Examples (/advanced-example):
requestInfo - Request context demonstrationnetlify/functions/new-server/new-server.tstools/index.tsnetlify.tomlimport type { Handler } from "@netlify/functions";
import * as toolModules from "./tools";
import { withMcpHandler } from "netlify-function-mcp";
export const handler: Handler = withMcpHandler({
name: "new-server",
version: "1.0.0",
toolModules
});
This package implements the Model Context Protocol with:
initialize - Protocol handshake and capability exchangeinitialized - Confirmation notificationtools/list - Returns available tools with schemastools/call - Executes a tool with parametersAll communication uses JSON-RPC 2.0:
// Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
// Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [...]
}
}
git clone https://github.com/yourname/netlify-function-mcp.git
cd netlify-function-mcp
npm install
cd packages/netlify-function-mcp
npm run build
cd examples/netlify-site
npm install
netlify dev
# Deploy to your custom domain
netlify deploy --prod
# Your MCP servers will be available at:
# https://mcp.yoursite.com/hello-world
# https://mcp.yoursite.com/api-tools
# https://mcp.yoursite.com/advanced-example
The implementation uses regular Netlify functions (not background functions) because:
For operations that need more than 10 seconds, consider:
MIT
FAQs
A TypeScript package for building Model Context Protocol (MCP) servers as Netlify Functions
We found that netlify-function-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.