MCP Server Boilerplate: A Minimal, Testable Starting Point

A minimal MCP server template with tool schemas, error handling, and permission boundaries — and when to use an existing MCP connection like fenbs instead of building one.

Updated 4 min read

An MCP server boilerplate is a minimal, working starting point that you can extend into a real server without spending time on protocol plumbing. It handles the transport, the request routing, and the error responses so you can focus on writing tool handlers. If what you need is a shared record of project context — tasks, decisions, where you left off — tools like fenbs already connect over MCP and do that work without any code.

A good boilerplate has three properties: it works out of the box, it fails clearly when something is wrong, and it is small enough to read in one sitting. The goal is not to be clever; it is to give you a clean starting point that you understand completely before you add anything to it.

When to use a boilerplate versus an existing server

Before starting from a boilerplate, decide whether you actually need a custom server. If you want to give an AI assistant access to a specific external service, check the MCP server directory first — an official or community server may already exist. If you want to share project context, rules, and task state across AI sessions, a purpose-built tool is a better starting point than a custom server you maintain yourself.

Build a custom server when you need to expose something specific to your organization that no existing server covers: an internal API, a proprietary database, or a workflow system unique to your team. That is when the boilerplate earns its place.

The minimal structure

A working MCP server needs four things: a server instance, one or more tool definitions, a transport connection, and a process entry point. Everything else is optional at the start. The boilerplate below is in TypeScript using the official SDK, but the same structure applies in any language with an MCP SDK. See the MCP server development guide for language-specific variants. Keep the boilerplate as small as possible: a shorter starting point is easier to understand completely before you add logic.

Minimal MCP server boilerplate (TypeScript)
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

const server = new McpServer({ name: 'my-server', version: '1.0.0' });

server.tool(
  'hello',
  'Returns a greeting for a given name.',
  { name: z.string().describe('Name to greet') },
  async ({ name }) => ({
    content: [{ type: 'text', text: `Hello, ${name}!` }],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);

Add error handling from the start

Every handler should return a structured error when something goes wrong rather than throwing an exception that crashes the server. Return an isError: true content block with a clear message. This lets the AI client read the error and explain it to the user rather than treating the call as a protocol failure.

Handler with structured error response
server.tool(
  'get_record',
  'Retrieves a record by ID.',
  { id: z.string() },
  async ({ id }) => {
    try {
      const record = await fetchRecord(id);
      return { content: [{ type: 'text', text: JSON.stringify(record) }] };
    } catch (err) {
      return {
        isError: true,
        content: [{ type: 'text', text: `Could not fetch record ${id}: ${err.message}` }],
      };
    }
  }
);

Set permission boundaries in the tool design

Decide what each tool may and may not do before you write the handler. Tools that read data should not be able to write it. Tools that call an external API should use credentials with the minimum necessary scope. Tools that accept user-supplied strings should validate them before using them in a query or a file path. Bake these constraints into the handler, not into a comment.

  • Use a read-only connection for any tool that only needs to retrieve data.
  • Validate path arguments to prevent directory traversal in file-system tools.
  • Log the arguments and outcome of any tool that modifies state so the change is auditable.
  • Name tools to reflect their scope: read_order makes the boundary clearer than get_order.

Handle the process lifecycle correctly

A common problem with stdio MCP servers is that they exit unexpectedly or hang when the client disconnects. Make sure your server listens for the close event on the transport and exits cleanly when it fires. Unhandled promise rejections are another frequent cause of unexpected exits — add a top-level rejection handler during development so you see the error rather than a silent process crash. For production servers, a process manager such as systemd or PM2 can restart the server if it exits unexpectedly.

Test the boilerplate before extending it

Run the MCP Inspector against the boilerplate before adding any real logic. Confirm the tool appears, call it with valid input, call it with invalid input, and confirm the server handles both correctly. Then commit this tested starting point to version control before extending it. A known-good baseline is worth more than a more complete server you have never fully tested.

How to use this boilerplate with fenbs

Keep the design decisions for the server in fenbs from the start. The boilerplate is the code; the decisions about what it does and who may use it belong in a place your team can read.

  1. Create a free account and add a project for the MCP server. Describe what it will connect to and who will use it.
  2. Write the first Decisions and rules before writing any handlers: what the server may read, what it may write, and what is out of scope.
  3. Add tasks for each tool you plan to build. Include the tool description text so it can be reviewed and updated as the server evolves.
  4. Connect your AI assistant via Integrations and ask it to read the project rules before making changes to the server.
  5. After each session, save progress and record any new decisions about the tool API so the next session starts from the current agreed design.
How fenbs helps

Keep the server's design decisions where every assistant reads them

fenbs stores the tool API decisions, permission boundaries, and maintenance context for your MCP server as AI context and Decisions and rules. When you connect your coding assistant, it reads those decisions before the session, so it does not propose tool changes that violate agreed scope. Create a free account and add the first decision before you add the first real handler.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

Questions people ask.

Do I need the official MCP SDK to use this boilerplate?

The boilerplate uses the official TypeScript SDK because it is the most widely used starting point. Equivalent SDKs exist for Python, Java, Go, and other languages. The structure is the same regardless of language.

Should I use the boilerplate for a production server?

The boilerplate is a starting point, not a production-ready template. A production server needs logging, monitoring, graceful error handling, authentication for remote transports, and tests for each handler.

Can I use the boilerplate to expose an existing REST API?

Yes. Write a tool handler that calls your REST API and returns the result. The MCP client gets a structured result; the underlying HTTP call is invisible to it.

How do I share the boilerplate across multiple servers in a team?

Extract the common transport and error-handling setup into a shared module or package. Each server imports the shared setup and adds its own tool definitions.

When is fenbs a better choice than a custom MCP server?

Use fenbs when your goal is shared project context across AI sessions: current tasks, decisions, rules, and where the work stands. fenbs already connects over MCP and handles that job without any code you need to write or maintain.

More in Connect your AI tools

All Connect your AI tools articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.