Skip to content

@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.

typescript
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 ​

typescript
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 ​

typescript
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.

typescript
frameworkTools(); // logs, credentials, S3, EventBridge, traces
frameworkTools({ getConnection }); // ...plus the two database tools
frameworkTools({ exclude: ["get_s3_object"] }); // drop tools by name

Options:

OptionEffect
getConnectionSupplies a McpDatabaseConnection factory, which adds query_database and describe_database_schema.
excludeTool names to omit from the returned array.
dynamodbForce 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 ​

ToolPurpose
fetchLambdaLogsToolSearch a Lambda's CloudWatch log group.
traceLambdaInvocationsToolCorrelate the log lines of a single invocation.
verifyCredentialsToolReport which role and account the Lambda is running as.
listS3ObjectsToolList objects under a prefix.
getS3ObjectToolRead one object's body.
listEventBridgeRulesToolList rules and their targets on the project's bus.
queryDynamodbToolRead-only DynamoDB access (Query and Scan only).
describeDynamodbTableToolTable schema, indexes, and throughput.
queryDatabaseTool / describeDatabaseSchemaToolAurora 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.

typescript
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.

typescript
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.

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.