Skip to main content

Overview

Deploy TypeScript MCP servers using the official MCP SDK with automatic containerization and infrastructure managed by Smithery.

Prerequisites

  • TypeScript MCP server using the official MCP SDK that exports the MCP server object at entry point
  • Node.js 18+ and npm installed locally
  • Smithery CLI installed as a dev dependency (npm i -D @smithery/cli)
New to MCP servers? See the Getting Started guide to learn how to build TypeScript MCP servers from scratch using the official SDK.

Project Structure

Your TypeScript project should look like this:
my-mcp-server/
  smithery.yaml          # Smithery configuration
  package.json           # Node.js dependencies and scripts
  tsconfig.json          # TypeScript configuration
  src/
    index.ts             # Your MCP server code with exported createServer function

Setup

1. Configure smithery.yaml

Create a smithery.yaml file in your repository root (usually where the package.json is):
runtime: "typescript"
That’s it! This minimal configuration is intentional - Smithery handles containerization, and deployment automatically for TypeScript projects.

2. Configure package.json

Your package.json must include the module field pointing to your server entry point:
{
  "name": "my-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "module": "src/index.ts",  // Points to your server entry point
  "scripts": {
    "build": "smithery build",
    "dev": "smithery dev"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.17.3",
    "zod": "^3.25.46"
  },
  "devDependencies": {
    "@smithery/cli": "^1.4.2"
  }
}
Install the CLI locally with:
npm i -D @smithery/cli
The Smithery CLI externalizes your SDKs during bundling so your runtime uses the versions you install. If you see a warning about missing SDKs, add them to your dependencies (most servers need @modelcontextprotocol/sdk and @smithery/sdk).

3. Ensure Proper Server Structure

Your TypeScript MCP server must export a default createServer function that returns the MCP server object. If you built your server following the Getting Started guide, it should already have this structure.
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

// Required: Export default createServer function
export default function createServer({ config }) {
  // config contains user-provided settings (see configSchema below)
  const server = new McpServer({
    name: "Your Server Name",
    version: "1.0.0",
  });

  // Register your tools here...
  
  return server.server; // Must return the MCP server object
}
Optional Configuration Schema: If your server needs user configuration (API keys, settings, etc.), export a configSchema:
// Optional: If your server doesn't need configuration, omit this
export const configSchema = z.object({
  apiKey: z.string().describe("Your API key"),
  timeout: z.number().default(5000).describe("Request timeout in milliseconds"),
});
Where it goes: Export configSchema from the same file as your createServer function (typically src/index.ts). What it does: Automatically generates session configuration forms for users connecting to your server.

OAuth

OAuth support in the TypeScript SDK and CLI is in beta and may change.
If your entry module exports oauth, Smithery CLI auto-mounts the required OAuth endpoints for you.

Export an OAuth provider

// src/index.ts
import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js"
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
import type { OAuthProvider } from "@smithery/sdk"
import { MyProvider } from "./provider.js"

export default function createServer({ auth }: { auth: AuthInfo }) {
  const server = new McpServer({ name: "My MCP", version: "1.0.0" })
  // register tools...
  return server.server
}

export const oauth: OAuthProvider = new MyProvider() 
The CLI detects oauth and injects the auth routes automatically.

Local Development

Test your server locally using the Smithery CLI:
# Start development server with interactive playground
npm run dev
This opens the Smithery interactive playground where you can:
  • Test your MCP server tools in real-time
  • See tool responses and debug issues
  • Validate your configuration schema
  • Experiment with different inputs

Advanced Build Configuration

For advanced use cases, you can customize the build process using a smithery.config.js file. This is useful for:
  • Marking packages as external (to avoid bundling issues)
  • Configuring minification, targets, and other build options
  • Adding custom esbuild plugins

Configuration File

Create smithery.config.js in your project root:
export default {
  esbuild: {
    // Mark problematic packages as external
    external: ["playwright-core", "puppeteer-core"],

    // Enable minification for production
    minify: true,

    // Set Node.js target version
    target: "node18",
  },
};

Common Use Cases

External Dependencies: If you encounter bundling issues with packages like Playwright or native modules:
export default {
  esbuild: {
    external: ["playwright-core", "sharp", "@grpc/grpc-js"],
  },
};
Configuration applies to both build and dev commands.

Deploy

  1. Push your code (including smithery.yaml) to GitHub
  2. Connect your GitHub to Smithery (or claim your server if already listed)
  3. Navigate to the Deployments tab on your server page
  4. Click Deploy to build and host your server

Good to Know

When you deploy, Smithery will:
  1. Clone your repository
  2. Parse your smithery.yaml to detect TypeScript runtime
  3. Install dependencies with npm ci
  4. Build your TypeScript code using the module entry point from your package.json
  5. Package your server into a containerized HTTP service
  6. Deploy the container to our hosting infrastructure
  7. Send MCP initialize and list_tools messages with a dummy configuration to discover your server’s capabilities
  8. Make it available at https://server.smithery.ai/your-server/mcp
  9. Handle load balancing, scaling, and monitoring

Troubleshooting

Common deployment failures and solutions:
  • Missing module field: Ensure your package.json has the module field pointing to your entry point
  • Dependencies not found: All dependencies must be listed in dependencies or devDependencies
  • Server doesn’t build locally: Before deploying, verify your server builds and runs locally:
    npm install
    npm run build
    
    If this fails, fix any TypeScript compilation errors or missing dependencies first
I