@tigerdata/mcp-boilerplate 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ export declare class StatusError extends Error {
2
+ status: number;
3
+ constructor(message: string, status?: number);
4
+ }
@@ -0,0 +1 @@
1
+ export declare function cliEntrypoint(stdioEntrypoint: string, httpEntrypoint: string, instrumentation?: string): Promise<void>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * REST API alternative to MCP for direct use of the same tools.
3
+ */
4
+ import { ApiFactory, RouterFactoryResult } from '../types.js';
5
+ export declare const apiRouterFactory: <Context extends Record<string, unknown>>(context: Context, apiFactories: readonly ApiFactory<Context, any, any>[]) => RouterFactoryResult;
@@ -0,0 +1,8 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { RouterFactoryResult } from '../types.js';
3
+ export declare const mcpRouterFactory: <Context extends Record<string, unknown>>(context: Context, createServer: (context: Context) => {
4
+ server: McpServer;
5
+ }, { name, stateful, }?: {
6
+ name?: string;
7
+ stateful?: boolean;
8
+ }) => RouterFactoryResult;
package/dist/http/mcp.js CHANGED
@@ -4,7 +4,7 @@ import { Router } from 'express';
4
4
  import { randomUUID } from 'node:crypto';
5
5
  import getRawBody from 'raw-body';
6
6
  import { log } from '../logger.js';
7
- export const mcpRouterFactory = (context, createServer, stateful = true) => {
7
+ export const mcpRouterFactory = (context, createServer, { name, stateful = true, } = {}) => {
8
8
  const router = Router();
9
9
  const transports = new Map();
10
10
  const handleStatelessRequest = async (req, res) => {
@@ -99,12 +99,12 @@ export const mcpRouterFactory = (context, createServer, stateful = true) => {
99
99
  const sessionId = req.headers['mcp-session-id'];
100
100
  if (!stateful) {
101
101
  res.status(405).json({
102
- jsonrpc: "2.0",
102
+ jsonrpc: '2.0',
103
103
  error: {
104
104
  code: -32000,
105
- message: "Method not allowed."
105
+ message: 'Method not allowed.',
106
106
  },
107
- id: null
107
+ id: null,
108
108
  });
109
109
  return;
110
110
  }
@@ -133,7 +133,33 @@ export const mcpRouterFactory = (context, createServer, stateful = true) => {
133
133
  await transports.get(sessionId).handleRequest(req, res);
134
134
  };
135
135
  // Handle GET requests for server-to-client notifications via SSE
136
- router.get('/', handleSessionRequest);
136
+ router.get('/', (req, res) => {
137
+ if (req.accepts('html')) {
138
+ const proto = req.headers['x-forwarded-proto'] || req.protocol;
139
+ const host = req.headers['x-forwarded-host'] || req.get('host');
140
+ const path = req.headers['x-original-request-uri'] ||
141
+ req.headers['x-original-uri'] ||
142
+ req.originalUrl;
143
+ const fullUrl = `${proto}://${host}${path}`;
144
+ res.send(`<!DOCTYPE html>
145
+ <html>
146
+ <head>
147
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
148
+ </head>
149
+ <body>
150
+ <h1>${name}</h1>
151
+ <h2>Model Context Protocol (MCP) Server</h2>
152
+ <p>This endpoint is used for MCP communication. Please use an MCP-compatible client to interact with this server.</p>
153
+
154
+ <h3>Claude Code</h3>
155
+ <p>To connect to this MCP server using Claude Code, run the following command in your terminal:</p>
156
+ <pre><code>claude mcp add --transport http ${name || req.get('host')} ${fullUrl}</code></pre>
157
+ </body>
158
+ </html>`);
159
+ return;
160
+ }
161
+ handleSessionRequest(req, res);
162
+ });
137
163
  // Handle DELETE requests for session termination
138
164
  router.delete('/', handleSessionRequest);
139
165
  const cleanup = async () => {
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import express from 'express';
3
+ import { ApiFactory, PromptFactory } from './types.js';
4
+ import { AdditionalSetupArgs } from './mcpServer.js';
5
+ import { Server } from 'node:http';
6
+ export declare const httpServerFactory: <Context extends Record<string, unknown>>({ name, version, context, apiFactories, promptFactories, additionalSetup, cleanupFn, stateful, }: {
7
+ name: string;
8
+ version?: string;
9
+ context: Context;
10
+ apiFactories?: readonly ApiFactory<Context, any, any>[];
11
+ promptFactories?: readonly PromptFactory<Context, any>[];
12
+ additionalSetup?: (args: AdditionalSetupArgs<Context>) => void;
13
+ cleanupFn?: () => void | Promise<void>;
14
+ stateful?: boolean;
15
+ }) => {
16
+ app: express.Express;
17
+ server: Server;
18
+ apiRouter: express.Router;
19
+ mcpRouter: express.Router;
20
+ registerCleanupFn: (fn: () => Promise<void>) => void;
21
+ };
@@ -13,6 +13,7 @@ export const httpServerFactory = ({ name, version, context, apiFactories = [], p
13
13
  const exitHandler = registerExitHandlers(cleanupFns);
14
14
  log.info('Starting HTTP server...');
15
15
  const app = express();
16
+ app.enable('trust proxy');
16
17
  const [mcpRouter, mcpCleanup] = mcpRouterFactory(context, () => mcpServerFactory({
17
18
  name,
18
19
  version,
@@ -20,7 +21,7 @@ export const httpServerFactory = ({ name, version, context, apiFactories = [], p
20
21
  apiFactories,
21
22
  promptFactories,
22
23
  additionalSetup,
23
- }), stateful);
24
+ }), { name, stateful });
24
25
  cleanupFns.push(mcpCleanup);
25
26
  app.use('/mcp', mcpRouter);
26
27
  const [apiRouter, apiCleanup] = apiRouterFactory(context, apiFactories);
@@ -0,0 +1,3 @@
1
+ import { NodeSDK } from '@opentelemetry/sdk-node';
2
+ export declare const sdk: NodeSDK;
3
+ export declare const cleanup: () => Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { LogAttributes } from '@opentelemetry/api-logs';
2
+ interface LogInterface {
3
+ debug: (body: string, attributes?: LogAttributes) => void;
4
+ info: (body: string, attributes?: LogAttributes) => void;
5
+ warn: (body: string, attributes?: LogAttributes) => void;
6
+ error: (body: string, error?: Error | null, attributes?: LogAttributes) => void;
7
+ }
8
+ export declare const log: LogInterface;
9
+ export {};
@@ -0,0 +1,16 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ApiFactory, PromptFactory } from './types.js';
3
+ export interface AdditionalSetupArgs<Context extends Record<string, unknown>> {
4
+ context: Context;
5
+ server: McpServer;
6
+ }
7
+ export declare const mcpServerFactory: <Context extends Record<string, unknown>>({ name, version, context, apiFactories, promptFactories, additionalSetup, }: {
8
+ name: string;
9
+ version?: string;
10
+ context: Context;
11
+ apiFactories: readonly ApiFactory<Context, any, any>[];
12
+ promptFactories?: readonly PromptFactory<Context, any>[];
13
+ additionalSetup?: (args: AdditionalSetupArgs<Context>) => void;
14
+ }) => {
15
+ server: McpServer;
16
+ };
package/dist/mcpServer.js CHANGED
@@ -21,6 +21,8 @@ export const mcpServerFactory = ({ name, version = '1.0.0', context, apiFactorie
21
21
  });
22
22
  for (const factory of apiFactories) {
23
23
  const tool = factory(context);
24
+ if (tool.disabled)
25
+ continue;
24
26
  if (enabledTools && !enabledTools.has(tool.name)) {
25
27
  continue;
26
28
  }
@@ -0,0 +1 @@
1
+ export declare const registerExitHandlers: (cleanupFns: (() => void | Promise<void>)[]) => ((code?: number) => void);
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import { ApiFactory, PromptFactory } from './types.js';
3
+ import { AdditionalSetupArgs } from './mcpServer.js';
4
+ export declare const stdioServerFactory: <Context extends Record<string, unknown>>({ name, version, context, apiFactories, promptFactories, additionalSetup, cleanupFn, }: {
5
+ name: string;
6
+ version?: string;
7
+ context: Context;
8
+ apiFactories: readonly ApiFactory<Context, any, any>[];
9
+ promptFactories?: readonly PromptFactory<Context, any>[];
10
+ additionalSetup?: (args: AdditionalSetupArgs<Context>) => void;
11
+ cleanupFn?: () => Promise<void>;
12
+ }) => Promise<void>;
@@ -0,0 +1,4 @@
1
+ import type { Span, Tracer } from '@opentelemetry/api';
2
+ import type { GenerateTextResult, ModelMessage } from 'ai';
3
+ export declare const withSpan: <T>(tracer: Tracer, name: string, fn: (span: Span) => Promise<T>) => Promise<T>;
4
+ export declare const addAiResultToSpan: (span: Span, aiResult: GenerateTextResult<any, unknown>, inputMessages: ModelMessage[]) => void;
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ import type { ZodRawShape, ZodTypeAny } from 'zod';
3
+ import type { ToolAnnotations, GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
4
+ import { Router } from 'express';
5
+ export type ToolConfig<InputArgs extends ZodRawShape, OutputArgs extends ZodRawShape> = {
6
+ title?: string;
7
+ description?: string;
8
+ inputSchema: InputArgs;
9
+ outputSchema: OutputArgs;
10
+ annotations?: ToolAnnotations;
11
+ };
12
+ export interface ApiDefinition<InputArgs extends ZodRawShape, OutputArgs extends ZodRawShape, SimplifiedOutputArgs = OutputArgs> {
13
+ name: string;
14
+ method?: 'get' | 'post' | 'put' | 'delete';
15
+ route?: string | string[];
16
+ config: ToolConfig<InputArgs, OutputArgs>;
17
+ disabled?: boolean;
18
+ fn: (args: z.objectOutputType<InputArgs, ZodTypeAny>) => Promise<z.objectOutputType<OutputArgs, ZodTypeAny>>;
19
+ pickResult?: (result: z.objectOutputType<OutputArgs, ZodTypeAny>) => SimplifiedOutputArgs;
20
+ }
21
+ export type ApiFactory<Context extends Record<string, unknown>, Input extends ZodRawShape, Output extends ZodRawShape, RestOutput = Output> = (ctx: Context) => ApiDefinition<Input, Output, RestOutput>;
22
+ export type RouterFactoryResult = [Router, () => void | Promise<void>];
23
+ export type PromptConfig<InputArgs extends ZodRawShape> = {
24
+ title?: string;
25
+ description?: string;
26
+ inputSchema: InputArgs;
27
+ };
28
+ export interface PromptDefinition<InputArgs extends ZodRawShape> {
29
+ name: string;
30
+ config: PromptConfig<InputArgs>;
31
+ fn: (args: z.objectOutputType<InputArgs, ZodTypeAny>) => Promise<GetPromptResult>;
32
+ }
33
+ export type PromptFactory<Context extends Record<string, unknown>, Input extends ZodRawShape> = (ctx: Context) => PromptDefinition<Input>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tigerdata/mcp-boilerplate",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "MCP boilerplate code for Node.js",
5
5
  "license": "Apache-2.0",
6
6
  "author": "TigerData",