#
tokens: 6365/50000 8/8 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── .cursor
│   └── mcp.json
├── .gitignore
├── build
│   └── index.js
├── Dockerfile
├── LICENSE
├── package.json
├── README.md
├── smithery.yaml
├── src
│   └── index.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
/node_modules
/package-lock.json
.env
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# RunPod MCP Server
[![smithery badge](https://smithery.ai/badge/@runpod/runpod-mcp-ts)](https://smithery.ai/server/@runpod/runpod-mcp-ts)

This Model Context Protocol (MCP) server enables you to interact with the RunPod REST API through Claude or other MCP-compatible clients.

## Features

The server provides tools for managing:

- **Pods**: Create, list, get details, update, start, stop, and delete pods
- **Endpoints**: Create, list, get details, update, and delete serverless endpoints
- **Templates**: Create, list, get details, update, and delete templates
- **Network Volumes**: Create, list, get details, update, and delete network volumes
- **Container Registry Authentications**: Create, list, get details, and delete authentications

## Setup

### Prerequisites

- Node.js 18 or higher
- A RunPod account and API key
- Claude for Desktop or another MCP-compatible client

### Installing via Smithery

To install runpod-mcp-ts for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@runpod/runpod-mcp-ts):

```bash
npx -y @smithery/cli install @runpod/runpod-mcp-ts --client claude
```

### Installation

1. Clone the repository
2. Install dependencies:
   ```
   npm install
   ```
3. Build the server:
   ```
   npm run build
   ```

### Configuration

Set your RunPod API key as an environment variable:

```bash
# Linux/macOS
export RUNPOD_API_KEY=your_api_key_here

# Windows (Command Prompt)
set RUNPOD_API_KEY=your_api_key_here

# Windows (PowerShell)
$env:RUNPOD_API_KEY="your_api_key_here"
```

You can get your API key from the [RunPod console](https://www.runpod.io/console/user/settings).

### Running the Server

Start the server:

```bash
npm start
```

## Setting up with Claude for Desktop

1. Open Claude for Desktop
2. Edit the config file: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows)
3. Add the server configuration:

```json
{
  "mcpServers": {
    "runpod": {
      "command": "node",
      "args": ["/path/to/runpod-mcp-server/build/index.js"],
      "env": {
        "RUNPOD_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

Make sure to replace the `"args": ["/path/to/runpod-mcp-server/build/index.js"]` with the path to the build folder in the repository.

4. Restart Claude for Desktop

## Usage Examples

Here are some examples of how to use the server with Claude:

### List all pods

```
Can you list all my RunPod pods?
```

### Create a new pod

```
Create a new RunPod pod with the following specifications:
- Name: test-pod
- Image: runpod/pytorch:2.1.0-py3.10-cuda11.8.0-devel-ubuntu22.04
- GPU Type: NVIDIA GeForce RTX 4090
- GPU Count: 1
```

### Create a serverless endpoint

```
Create a RunPod serverless endpoint with the following configuration:
- Name: my-endpoint
- Template ID: 30zmvf89kd
- Minimum workers: 0
- Maximum workers: 3
```

## Security Considerations

This server requires your RunPod API key, which grants full access to your RunPod account. For security:

- Never share your API key
- Be cautious about what operations you perform
- Consider setting up a separate API key with limited permissions
- Don't use this in a production environment without proper security measures

## License

MIT

```

--------------------------------------------------------------------------------
/.cursor/mcp.json:
--------------------------------------------------------------------------------

```json
{
  "mcpServers": {
    "runpod": {
      "command": "node",
      "args": ["your/path/to/runpod-mcp-ts/build/index.js"],
      "env": {
        "RUNPOD_API_KEY": "your_api_key_here"
      }
    }
  }
}

```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
FROM node:lts-alpine

# Set working directory
WORKDIR /app

# Copy package.json and package-lock.json if available
COPY package*.json ./

# Install dependencies
RUN npm install --ignore-scripts

# Copy the rest of the application
COPY . .

# Build the project
RUN npm run build

# Expose any necessary port if required (not specified, so leaving out)

# Start the server
CMD ["npm", "start"]

```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "runpod-mcp-server",
  "version": "1.0.0",
  "description": "MCP server for interacting with RunPod API",
  "type": "module",
  "main": "build/index.js",
  "scripts": {
    "build": "tsc",
    "start": "node build/index.js",
    "dev": "tsx index.ts"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0",
    "node-fetch": "^3.3.2",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/node": "^20.10.5",
    "tsx": "^4.7.0",
    "typescript": "^5.3.3"
  }
}

```

--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------

```yaml
# Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml

startCommand:
  type: stdio
  configSchema:
    # JSON Schema defining the configuration options for the MCP.
    type: object
    required:
      - runpodApiKey
    properties:
      runpodApiKey:
        type: string
        description: Your RunPod API key
  commandFunction:
    # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
    |-
    (config) => ({
      command: 'node',
      args: ['build/index.js'],
      env: { RUNPOD_API_KEY: config.runpodApiKey }
    })
  exampleConfig:
    runpodApiKey: your_dummy_runpod_api_key_here

```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
import { z } from "zod"
import fetch from "node-fetch"

// Base URL for RunPod API
const API_BASE_URL = "https://rest.runpod.io/v1"

// Get API key from environment variable
const API_KEY = process.env.RUNPOD_API_KEY
if (!API_KEY) {
  console.error("RUNPOD_API_KEY environment variable is required")
  process.exit(1)
}

// Create an MCP server
const server = new McpServer({
  name: "RunPod API Server",
  version: "1.0.0",
  capabilities: {
    resources: {},
    tools: {},
  },
})

// Helper function to make authenticated API requests to RunPod
async function runpodRequest(
  endpoint: string,
  method: string = "GET",
  body?: any
) {
  const url = `${API_BASE_URL}${endpoint}`
  const headers = {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  }

  const options: any = {
    method,
    headers,
  }

  if (body && (method === "POST" || method === "PATCH")) {
    options.body = JSON.stringify(body)
  }

  try {
    const response = await fetch(url, options)

    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`RunPod API Error: ${response.status} - ${errorText}`)
    }

    // Some endpoints might not return JSON
    const contentType = response.headers.get("content-type")
    if (contentType && contentType.includes("application/json")) {
      return await response.json()
    }

    return { success: true, status: response.status }
  } catch (error) {
    console.error("Error calling RunPod API:", error)
    throw error
  }
}

// ============== POD MANAGEMENT TOOLS ==============

// List Pods
server.tool(
  "list-pods",
  {
    computeType: z
      .enum(["GPU", "CPU"])
      .optional()
      .describe("Filter to only GPU or only CPU Pods"),
    gpuTypeId: z
      .array(z.string())
      .optional()
      .describe("Filter to Pods with any of the listed GPU types"),
    dataCenterId: z
      .array(z.string())
      .optional()
      .describe("Filter to Pods in any of the provided data centers"),
    name: z
      .string()
      .optional()
      .describe("Filter to Pods with the provided name"),
    includeMachine: z
      .boolean()
      .optional()
      .describe("Include information about the machine"),
    includeNetworkVolume: z
      .boolean()
      .optional()
      .describe("Include information about attached network volumes"),
  },
  async (params) => {
    // Construct query parameters
    const queryParams = new URLSearchParams()

    if (params.computeType)
      queryParams.append("computeType", params.computeType)
    if (params.gpuTypeId)
      params.gpuTypeId.forEach((type) => queryParams.append("gpuTypeId", type))
    if (params.dataCenterId)
      params.dataCenterId.forEach((dc) =>
        queryParams.append("dataCenterId", dc)
      )
    if (params.name) queryParams.append("name", params.name)
    if (params.includeMachine)
      queryParams.append("includeMachine", params.includeMachine.toString())
    if (params.includeNetworkVolume)
      queryParams.append(
        "includeNetworkVolume",
        params.includeNetworkVolume.toString()
      )

    const queryString = queryParams.toString()
      ? `?${queryParams.toString()}`
      : ""
    const result = await runpodRequest(`/pods${queryString}`)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Get Pod Details
server.tool(
  "get-pod",
  {
    podId: z.string().describe("ID of the pod to retrieve"),
    includeMachine: z
      .boolean()
      .optional()
      .describe("Include information about the machine"),
    includeNetworkVolume: z
      .boolean()
      .optional()
      .describe("Include information about attached network volumes"),
  },
  async (params) => {
    // Construct query parameters
    const queryParams = new URLSearchParams()

    if (params.includeMachine)
      queryParams.append("includeMachine", params.includeMachine.toString())
    if (params.includeNetworkVolume)
      queryParams.append(
        "includeNetworkVolume",
        params.includeNetworkVolume.toString()
      )

    const queryString = queryParams.toString()
      ? `?${queryParams.toString()}`
      : ""
    const result = await runpodRequest(`/pods/${params.podId}${queryString}`)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Create Pod
server.tool(
  "create-pod",
  {
    name: z.string().optional().describe("Name for the pod"),
    imageName: z.string().describe("Docker image to use"),
    cloudType: z
      .enum(["SECURE", "COMMUNITY"])
      .optional()
      .describe("SECURE or COMMUNITY cloud"),
    gpuTypeIds: z
      .array(z.string())
      .optional()
      .describe("List of acceptable GPU types"),
    gpuCount: z.number().optional().describe("Number of GPUs"),
    containerDiskInGb: z
      .number()
      .optional()
      .describe("Container disk size in GB"),
    volumeInGb: z.number().optional().describe("Volume size in GB"),
    volumeMountPath: z.string().optional().describe("Path to mount the volume"),
    ports: z
      .array(z.string())
      .optional()
      .describe("Ports to expose (e.g., '8888/http', '22/tcp')"),
    env: z.record(z.string()).optional().describe("Environment variables"),
    dataCenterIds: z
      .array(z.string())
      .optional()
      .describe("List of data centers"),
  },
  async (params) => {
    const result = await runpodRequest("/pods", "POST", params)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Update Pod
server.tool(
  "update-pod",
  {
    podId: z.string().describe("ID of the pod to update"),
    name: z.string().optional().describe("New name for the pod"),
    imageName: z.string().optional().describe("New Docker image"),
    containerDiskInGb: z
      .number()
      .optional()
      .describe("New container disk size in GB"),
    volumeInGb: z.number().optional().describe("New volume size in GB"),
    volumeMountPath: z
      .string()
      .optional()
      .describe("New path to mount the volume"),
    ports: z.array(z.string()).optional().describe("New ports to expose"),
    env: z.record(z.string()).optional().describe("New environment variables"),
  },
  async (params) => {
    const { podId, ...updateParams } = params
    const result = await runpodRequest(`/pods/${podId}`, "PATCH", updateParams)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Start Pod
server.tool(
  "start-pod",
  {
    podId: z.string().describe("ID of the pod to start"),
  },
  async (params) => {
    const result = await runpodRequest(`/pods/${params.podId}/start`, "POST")

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Stop Pod
server.tool(
  "stop-pod",
  {
    podId: z.string().describe("ID of the pod to stop"),
  },
  async (params) => {
    const result = await runpodRequest(`/pods/${params.podId}/stop`, "POST")

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Delete Pod
server.tool(
  "delete-pod",
  {
    podId: z.string().describe("ID of the pod to delete"),
  },
  async (params) => {
    const result = await runpodRequest(`/pods/${params.podId}`, "DELETE")

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// ============== ENDPOINT MANAGEMENT TOOLS ==============

// List Endpoints
server.tool(
  "list-endpoints",
  {
    includeTemplate: z
      .boolean()
      .optional()
      .describe("Include template information"),
    includeWorkers: z
      .boolean()
      .optional()
      .describe("Include information about workers"),
  },
  async (params) => {
    // Construct query parameters
    const queryParams = new URLSearchParams()

    if (params.includeTemplate)
      queryParams.append("includeTemplate", params.includeTemplate.toString())
    if (params.includeWorkers)
      queryParams.append("includeWorkers", params.includeWorkers.toString())

    const queryString = queryParams.toString()
      ? `?${queryParams.toString()}`
      : ""
    const result = await runpodRequest(`/endpoints${queryString}`)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Get Endpoint Details
server.tool(
  "get-endpoint",
  {
    endpointId: z.string().describe("ID of the endpoint to retrieve"),
    includeTemplate: z
      .boolean()
      .optional()
      .describe("Include template information"),
    includeWorkers: z
      .boolean()
      .optional()
      .describe("Include information about workers"),
  },
  async (params) => {
    // Construct query parameters
    const queryParams = new URLSearchParams()

    if (params.includeTemplate)
      queryParams.append("includeTemplate", params.includeTemplate.toString())
    if (params.includeWorkers)
      queryParams.append("includeWorkers", params.includeWorkers.toString())

    const queryString = queryParams.toString()
      ? `?${queryParams.toString()}`
      : ""
    const result = await runpodRequest(
      `/endpoints/${params.endpointId}${queryString}`
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Create Endpoint
server.tool(
  "create-endpoint",
  {
    name: z.string().optional().describe("Name for the endpoint"),
    templateId: z.string().describe("Template ID to use"),
    computeType: z
      .enum(["GPU", "CPU"])
      .optional()
      .describe("GPU or CPU endpoint"),
    gpuTypeIds: z
      .array(z.string())
      .optional()
      .describe("List of acceptable GPU types"),
    gpuCount: z.number().optional().describe("Number of GPUs per worker"),
    workersMin: z.number().optional().describe("Minimum number of workers"),
    workersMax: z.number().optional().describe("Maximum number of workers"),
    dataCenterIds: z
      .array(z.string())
      .optional()
      .describe("List of data centers"),
  },
  async (params) => {
    const result = await runpodRequest("/endpoints", "POST", params)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Update Endpoint
server.tool(
  "update-endpoint",
  {
    endpointId: z.string().describe("ID of the endpoint to update"),
    name: z.string().optional().describe("New name for the endpoint"),
    workersMin: z.number().optional().describe("New minimum number of workers"),
    workersMax: z.number().optional().describe("New maximum number of workers"),
    idleTimeout: z.number().optional().describe("New idle timeout in seconds"),
    scalerType: z
      .enum(["QUEUE_DELAY", "REQUEST_COUNT"])
      .optional()
      .describe("Scaler type"),
    scalerValue: z.number().optional().describe("Scaler value"),
  },
  async (params) => {
    const { endpointId, ...updateParams } = params
    const result = await runpodRequest(
      `/endpoints/${endpointId}`,
      "PATCH",
      updateParams
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Delete Endpoint
server.tool(
  "delete-endpoint",
  {
    endpointId: z.string().describe("ID of the endpoint to delete"),
  },
  async (params) => {
    const result = await runpodRequest(
      `/endpoints/${params.endpointId}`,
      "DELETE"
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// ============== TEMPLATE MANAGEMENT TOOLS ==============

// List Templates
server.tool("list-templates", {}, async () => {
  const result = await runpodRequest("/templates")

  return {
    content: [
      {
        type: "text",
        text: JSON.stringify(result, null, 2),
      },
    ],
  }
})

// Get Template Details
server.tool(
  "get-template",
  {
    templateId: z.string().describe("ID of the template to retrieve"),
  },
  async (params) => {
    const result = await runpodRequest(`/templates/${params.templateId}`)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Create Template
server.tool(
  "create-template",
  {
    name: z.string().describe("Name for the template"),
    imageName: z.string().describe("Docker image to use"),
    isServerless: z
      .boolean()
      .optional()
      .describe("Is this a serverless template"),
    ports: z.array(z.string()).optional().describe("Ports to expose"),
    dockerEntrypoint: z
      .array(z.string())
      .optional()
      .describe("Docker entrypoint commands"),
    dockerStartCmd: z
      .array(z.string())
      .optional()
      .describe("Docker start commands"),
    env: z.record(z.string()).optional().describe("Environment variables"),
    containerDiskInGb: z
      .number()
      .optional()
      .describe("Container disk size in GB"),
    volumeInGb: z.number().optional().describe("Volume size in GB"),
    volumeMountPath: z.string().optional().describe("Path to mount the volume"),
    readme: z.string().optional().describe("README content in markdown format"),
  },
  async (params) => {
    const result = await runpodRequest("/templates", "POST", params)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Update Template
server.tool(
  "update-template",
  {
    templateId: z.string().describe("ID of the template to update"),
    name: z.string().optional().describe("New name for the template"),
    imageName: z.string().optional().describe("New Docker image"),
    ports: z.array(z.string()).optional().describe("New ports to expose"),
    env: z.record(z.string()).optional().describe("New environment variables"),
    readme: z
      .string()
      .optional()
      .describe("New README content in markdown format"),
  },
  async (params) => {
    const { templateId, ...updateParams } = params
    const result = await runpodRequest(
      `/templates/${templateId}`,
      "PATCH",
      updateParams
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Delete Template
server.tool(
  "delete-template",
  {
    templateId: z.string().describe("ID of the template to delete"),
  },
  async (params) => {
    const result = await runpodRequest(
      `/templates/${params.templateId}`,
      "DELETE"
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// ============== NETWORK VOLUME MANAGEMENT TOOLS ==============

// List Network Volumes
server.tool("list-network-volumes", {}, async () => {
  const result = await runpodRequest("/networkvolumes")

  return {
    content: [
      {
        type: "text",
        text: JSON.stringify(result, null, 2),
      },
    ],
  }
})

// Get Network Volume Details
server.tool(
  "get-network-volume",
  {
    networkVolumeId: z
      .string()
      .describe("ID of the network volume to retrieve"),
  },
  async (params) => {
    const result = await runpodRequest(
      `/networkvolumes/${params.networkVolumeId}`
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Create Network Volume
server.tool(
  "create-network-volume",
  {
    name: z.string().describe("Name for the network volume"),
    size: z.number().describe("Size in GB (1-4000)"),
    dataCenterId: z.string().describe("Data center ID"),
  },
  async (params) => {
    const result = await runpodRequest("/networkvolumes", "POST", params)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Update Network Volume
server.tool(
  "update-network-volume",
  {
    networkVolumeId: z.string().describe("ID of the network volume to update"),
    name: z.string().optional().describe("New name for the network volume"),
    size: z
      .number()
      .optional()
      .describe("New size in GB (must be larger than current)"),
  },
  async (params) => {
    const { networkVolumeId, ...updateParams } = params
    const result = await runpodRequest(
      `/networkvolumes/${networkVolumeId}`,
      "PATCH",
      updateParams
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Delete Network Volume
server.tool(
  "delete-network-volume",
  {
    networkVolumeId: z.string().describe("ID of the network volume to delete"),
  },
  async (params) => {
    const result = await runpodRequest(
      `/networkvolumes/${params.networkVolumeId}`,
      "DELETE"
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// ============== CONTAINER REGISTRY AUTH TOOLS ==============

// List Container Registry Auths
server.tool("list-container-registry-auths", {}, async () => {
  const result = await runpodRequest("/containerregistryauth")

  return {
    content: [
      {
        type: "text",
        text: JSON.stringify(result, null, 2),
      },
    ],
  }
})

// Get Container Registry Auth Details
server.tool(
  "get-container-registry-auth",
  {
    containerRegistryAuthId: z
      .string()
      .describe("ID of the container registry auth to retrieve"),
  },
  async (params) => {
    const result = await runpodRequest(
      `/containerregistryauth/${params.containerRegistryAuthId}`
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Create Container Registry Auth
server.tool(
  "create-container-registry-auth",
  {
    name: z.string().describe("Name for the container registry auth"),
    username: z.string().describe("Registry username"),
    password: z.string().describe("Registry password"),
  },
  async (params) => {
    const result = await runpodRequest("/containerregistryauth", "POST", params)

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Delete Container Registry Auth
server.tool(
  "delete-container-registry-auth",
  {
    containerRegistryAuthId: z
      .string()
      .describe("ID of the container registry auth to delete"),
  },
  async (params) => {
    const result = await runpodRequest(
      `/containerregistryauth/${params.containerRegistryAuthId}`,
      "DELETE"
    )

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(result, null, 2),
        },
      ],
    }
  }
)

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport()
server.connect(transport)

```