# Publishing an MCP server

This example guides you through setting up a basic Mastra MCPServer using the stdio transport, building it, and preparing it for publishing to NPM.

## Install dependencies

Install the necessary packages:

**npm**:

```bash
npm install @mastra/mcp @mastra/core tsup
```

**pnpm**:

```bash
pnpm add @mastra/mcp @mastra/core tsup
```

**Yarn**:

```bash
yarn add @mastra/mcp @mastra/core tsup
```

**Bun**:

```bash
bun add @mastra/mcp @mastra/core tsup
```

## Setting up an MCP server

1. Create a file for your stdio server, for example, `src/mastra/stdio.ts`.

2. Add the following code to the file. Remember to import your actual Mastra tools and name the server appropriately.

   ```typescript
   #!/usr/bin/env node
   import { MCPServer } from '@mastra/mcp'
   import { weatherTool } from './tools'

   const server = new MCPServer({
     name: 'my-mcp-server',
     version: '1.0.0',
     tools: { weatherTool },
   })

   server.startStdio().catch(error => {
     console.error('Error running MCP server:', error)
     process.exit(1)
   })
   ```

3. Update your `package.json` to include the `bin` entry pointing to your built server file and a script to build the server with both ESM and CJS outputs.

   ```json
   {
     "bin": "dist/stdio.mjs",
     "scripts": {
       "build:mcp": "tsup src/mastra/stdio.ts --format esm,cjs --no-splitting --dts && echo '#!/usr/bin/env node' | cat - dist/stdio.mjs > temp && mv temp dist/stdio.mjs && chmod +x dist/stdio.mjs"
     }
   }
   ```

   The build command generates both ESM (`.mjs`) and CJS (`.cjs`) outputs for maximum compatibility. The shebang (`#!/usr/bin/env node`) is prepended to the ESM artifact to make it directly executable, and the `bin` entry points to this file.

4. Run the build command:

   **npm**:

   ```bash
   npm run build:mcp
   ```

   **pnpm**:

   ```bash
   pnpm run build:mcp
   ```

   **Yarn**:

   ```bash
   yarn build:mcp
   ```

   **Bun**:

   ```bash
   bun run build:mcp
   ```

   This will compile your server code into both ESM and CJS formats and make the ESM output file executable. On Unix-like systems, the `chmod +x` step makes the file directly executable. Windows users may need to use WSL or handle execution through Node.js directly.

## Publishing to NPM

To make your MCP server available for others (or yourself) to use via `npx` or as a dependency, you can publish it to NPM.

1. Ensure you have an NPM account and are logged in (`npm login`).

2. Make sure your package name in `package.json` is unique and available.

3. Run the publish command from your project root after building:

   ```bash
   npm publish --access public
   ```

   For more details on publishing packages, refer to the [NPM documentation](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages).

## Using a published MCP server

Once published, your MCP server can be used by an `MCPClient` by specifying the command to run your package. You can also use any other MCP client like Claude desktop, Cursor, or Windsurf.

```typescript
import { MCPClient } from '@mastra/mcp'

const mcp = new MCPClient({
  servers: {
    // Give this MCP server instance a name
    yourServerName: {
      command: 'npx',
      args: ['-y', '@your-org-name/your-package-name@latest'], // Replace with your package name
    },
  },
})

// You can then get tools or toolsets from this configuration to use in your agent
const tools = await mcp.listTools()
const toolsets = await mcp.listToolsets()
```

Note: If you published without an organization scope, the `args` might be `["-y", "your-package-name@latest"]`.