Deploy and publish TypeScript MCP servers on Smithery using Smithery CLI
Deploy TypeScript MCP servers using the official MCP SDK with two deployment options:
- Remote deployment: Automatic containerization and infrastructure managed by Smithery
- Local servers (Beta): Distribute your server as MCP bundle allowing users to run it locally and one-click install it
- 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)
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
Create a smithery.yaml file in your repository root (usually where the package.json is):
runtime: "typescript"runtime: "typescript"
target: "local"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": "npx smithery build",
"dev": "npx smithery dev"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.17.3",
"zod": "^3.25.46"
},
"devDependencies": {
"@smithery/cli": "^1.4.6"
}
}npm i -D @smithery/cliThe 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).
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 is designed only for **remote servers**. OAuth is not available for local servers (`target: "local"`).If your entry module exports oauth, Smithery CLI auto-mounts the required OAuth endpoints for you during remote deployment.
// 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() // [!code highlight]The CLI detects oauth and injects the auth routes automatically. For implementing OAuthServerProvider, see the official MCP SDK authorization guide.
Test your server locally using the Smithery CLI:
# Start development server with interactive playground
npm run devThis 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
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
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",
},
};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.
- Push your code (including
smithery.yaml) to GitHub - Connect your GitHub to Smithery (or claim your server if already listed)
- Navigate to the Deployments tab on your server page
- Click Deploy to build and host your server
- Clone your repository
- Parse your
smithery.yamlto detect TypeScript runtime - Install dependencies with
npm ci - Build your TypeScript code using the
moduleentry point from yourpackage.json - Package your server into a containerized HTTP service
- Deploy the container to our hosting infrastructure
- Send MCP
initializeandlist_toolsmessages with a dummy configuration to discover your server's capabilities - Make it available at
https://server.smithery.ai/your-server - Handle load balancing, scaling, and monitoring
Local Server (Beta): When you use target: "local":
- Your server runs locally on user's machine using
npm run dev - Smithery registers your server in the registry for discovery
- MCP clients can find and connect to your local server through Smithery
- Your server remains under your control while being accessible to others
Remote Deployment Issues:
- Missing module field: Ensure your
package.jsonhas themodulefield pointing to your entry point - Dependencies not found: All dependencies must be listed in
dependenciesordevDependencies - Server doesn't build locally: Before deploying, verify your server builds and runs locally:
If this fails, fix any TypeScript compilation errors or missing dependencies first
npm install npm run build
Local Server Issues (Beta):
- Server not discoverable: Ensure you have
target: "local"in yoursmithery.yaml - Local server won't start: Verify your server runs with
npm run devbefore expecting registry integration - Connection issues: Make sure your local development environment allows the necessary network connections
To find navigation and other pages in this documentation, fetch the llms.txt file at: https://smithery.ai/docs/llms.txt