@j0nathan-ll0yd/mcp
Model Context Protocol server as a Lambda, plus a batteries-included catalogue of diagnostic tools.
An MCP server built with this package runs behind a Lambda Function URL. An AI assistant connects to it and can then read logs, inspect S3 objects, list EventBridge rules, and query the database of the deployed stage -- through IAM-scoped tools rather than ambient AWS credentials.
defineMcpHandler(options)
Create the Lambda handler for an MCP server.
import { defineMcpHandler, frameworkTools, McpAuthMode } from "@j0nathan-ll0yd/mcp";
import { getConnection } from "../db/client.js";
export const handler = defineMcpHandler({
serverName: "my-app-devtools",
auth: McpAuthMode.bearer,
tools: frameworkTools({ getConnection }),
});DefineMcpHandlerOptions
interface DefineMcpHandlerOptions {
serverName: string;
auth: McpAuthMode;
tools: McpToolDefinition[];
operationName?: string;
logging?: LoggingConfig;
timeout?: number;
memorySize?: number;
reservedConcurrency?: number;
ephemeralStorage?: number;
}The CLI reads these options at build time to generate the Function URL and the Lambda's IAM policy.
McpAuthMode
const McpAuthMode = { bearer: "bearer", none: "none" } as const;bearer validates Authorization: Bearer <token> against API_BEARER_TOKEN. none disables authentication and is intended for local development only -- never deploy it to a stage that holds real data.
frameworkTools(options?)
Return the framework tool catalogue, adapted to what the Lambda can actually reach.
frameworkTools(); // logs, credentials, S3, EventBridge, traces
frameworkTools({ getConnection }); // ...plus the two database tools
frameworkTools({ exclude: ["get_s3_object"] }); // drop tools by nameOptions:
| Option | Effect |
|---|---|
getConnection | Supplies a McpDatabaseConnection factory, which adds query_database and describe_database_schema. |
exclude | Tool names to omit from the returned array. |
dynamodb | Force the DynamoDB tools on or off. Defaults to auto-detection from any *_TABLE_NAME environment binding. |
Auto-detection matters: advertising a tool the Lambda has no IAM grant for would put an entry in tools/list that fails with AccessDenied when called. The *_TABLE_NAME signal is the same one the CLI's IAM renderer uses to grant dynamodb:Query, Scan, and DescribeTable.
Catalogue
| Tool | Purpose |
|---|---|
fetchLambdaLogsTool | Search a Lambda's CloudWatch log group. |
traceLambdaInvocationsTool | Correlate the log lines of a single invocation. |
verifyCredentialsTool | Report which role and account the Lambda is running as. |
listS3ObjectsTool | List objects under a prefix. |
getS3ObjectTool | Read one object's body. |
listEventBridgeRulesTool | List rules and their targets on the project's bus. |
queryDynamodbTool | Read-only DynamoDB access (Query and Scan only). |
describeDynamodbTableTool | Table schema, indexes, and throughput. |
queryDatabaseTool / describeDatabaseSchemaTool | Aurora DSQL query and schema inspection. Need getConnection. |
The DynamoDB tools are read-only by construction, which is what closes the C110 carve-out for raw aws dynamodb CLI use.
frameworkToolPermissions
The IAM permissions each framework tool needs, as McpToolPermissions[]. The CLI consumes this when generating the MCP Lambda's inline policy, so a tool and its grant can never drift apart.
import { frameworkToolPermissions } from "@j0nathan-ll0yd/mcp";
// [{ tool: 'fetch_lambda_logs', permissions: [{ service: 'logs', actions: ['logs:FilterLogEvents'] }] }, ...]Types: McpToolPermissions, McpToolIamPermission.
Custom tools
Add project-specific tools by appending McpToolDefinition objects.
import { z } from "zod";
import type { McpToolDefinition } from "@j0nathan-ll0yd/mcp";
const replayExport: McpToolDefinition = {
name: "replay_export",
description: "Re-run the nightly export for one user",
parameters: z.object({ userId: z.string() }),
handler: async ({ userId }) => ({ content: [{ type: "text", text: await replay(userId) }] }),
};
export const handler = defineMcpHandler({
serverName: "my-app-devtools",
auth: McpAuthMode.bearer,
tools: [...frameworkTools(), replayExport],
});Supporting types: McpToolDefinition, McpToolResult, McpToolContent, McpDatabaseConnection, LambdaFunctionURLEvent, LambdaFunctionURLResult.
Related
The framework's own MCP server, which answers questions about Mantle conventions rather than about a deployed stage, is a separate thing: see mantle mcp-server.