The AI ecosystem is evolving quickly, and Anthropic releasing the Mannequin Context Protocol on November twenty fifth, 2024 has actually formed how LLM’s join with knowledge. No extra constructing {custom} integrations for each knowledge supply: MCP offers one protocol to attach all of them. However right here’s the problem: constructing MCP servers from scratch might be advanced.
TL;DR: What’s MCP?
Consider MCP like a USB-C port for AI functions. Simply as USB-C offers a standardized option to join gadgets to numerous peripherals, MCP offers a standardized option to join AI fashions to totally different knowledge sources, instruments, and providers. It’s an open protocol that allows AI functions to securely and effectively entry exterior context – whether or not that’s your organization’s database, file methods, APIs, or {custom} enterprise logic.
Supply: https://modelcontextprotocol.io/docs/getting-started/intro
In observe, this implies you possibly can hook LLMs into the belongings you already work with daily. To call a number of examples, you might question databases to visualise traits, pull and resolve points from GitHub, fetch or replace content material to a CMS, and so forth. Past growth, the identical applies to broader workflows: buyer help brokers can lookup and resolve tickets, enterprise search can fetch and browse content material scattered throughout wikis and docs, operations can monitor infrastructure or management gadgets.
However there’s extra to it, and that’s while you actually unlock the facility of MCP. It’s not nearly single duties, however rethinking total workflows. All of the sudden, we’re shaping our option to work together with merchandise and even our personal computer systems: as an alternative of adapting ourselves to the constraints of software program, we will form the expertise round our personal wants.
That’s the place xmcp is available in: a TypeScript framework designed with DX in thoughts, for builders who wish to construct and ship MCP servers with out the standard friction. It removes the complexity and will get you up and operating in a matter of minutes.
Slightly backstory
xmcp was born out of necessity at Basement Studio, the place we wanted to construct inside instruments for our growth processes. As we dove deeper into the protocol, we rapidly found how fragmented the tooling panorama was and the way a lot time we had been spending on setup, configuration, and deployment quite than truly constructing the instruments our staff wanted.
That’s after we determined to consolidate the whole lot we’d discovered right into a framework. The philosophy was easy: builders shouldn’t should grow to be specialists simply to construct AI instruments. The main focus must be on creating worthwhile performance, not wrestling with boilerplate code and all kinds of complexities.
Key options & capabilities
xmcp shines in its simplicity. With only one command, you possibly can scaffold a whole MCP server:
npx create-xmcp-app@newest
The framework routinely discovers and registers instruments. No further setup wanted.
All you want is instruments/
xmcp abstracts the unique device syntax from the TypeScript SDK and follows a SOC precept, following a easy three-exports construction:
- Implementation: The precise device logic.
- Schema: Outline enter parameters utilizing Zod schemas with computerized validation
- Metadata: Specify device identification and conduct hints for AI fashions
// src/instruments/greet.ts
import { z } from "zod";
import { kind InferSchema } from "xmcp";
// Outline the schema for device parameters
export const schema = {
title: z.string().describe("The title of the consumer to greet"),
};
// Outline device metadata
export const metadata = {
title: "greet",
description: "Greet the consumer",
annotations: {
title: "Greet the consumer",
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
},
};
// Device implementation
export default async perform greet({ title }: InferSchema<typeof schema>) {
return `Hi there, ${title}!`;
}
Transport Choices
- HTTP: Excellent for server deployments, enabling instruments that fetch knowledge from databases or exterior APIs
- STDIO: Splendid for native operations, permitting LLMs to carry out duties instantly in your machine
You’ll be able to tweak the configuration to your wants by modifying the xmcp.config.ts
file within the root listing. Among the many choices you could find the transport kind, CORS setup, experimental options, instruments listing, and even the webpack config. Study extra about this file right here.
const config: XmcpConfig = {
http: {
port: 3000,
// The endpoint the place the MCP server will probably be obtainable
endpoint: "/my-custom-endpoint",
bodySizeLimit: 10 * 1024 * 1024,
cors: {
origin: "*",
strategies: ["GET", "POST"],
allowedHeaders: ["Content-Type"],
credentials: true,
exposedHeaders: ["Content-Type"],
maxAge: 600,
},
},
webpack: (config) => {
// Add uncooked loader for pictures to get them as base64
config.module?.guidelines?.push(svg);
return config;
},
};
Constructed-in Middleware & Authentication
For HTTP servers, xmcp offers native options so as to add Authentication (JWT, API Key, OAuth). You’ll be able to all the time leverage your utility by including {custom} middlewares, which might even be an array.
import { kind Middleware } from 'xmcp';
const middleware: Middleware = async (req, res, subsequent) => {
// Customized processing
subsequent();
};
export default middleware;
Integrations
Whilst you can bootstrap an utility from scratch, xmcp may work on high of your current Subsequent.js or Specific mission. To get began, run the next command:
npx init-xmcp@newest
in your initialized utility, and you’re good to go! You’ll discover a instruments listing with the identical discovery capabilities. For those who’re utilizing Subsequent.js the handler is ready up routinely. For those who’re utilizing Specific, you’ll should configure it manually.
From zero to prod
Let’s see this in motion by constructing and deploying an MCP server. We’ll create a Linear integration that fetches points out of your backlog and calculates completion charges, excellent for producing mission analytics and visualizations.
For this walkthrough, we’ll use Cursor as our MCP consumer to work together with the server.
Organising the mission
The quickest option to get began is by deploying the xmcp template instantly from Vercel. This routinely initializes the mission and creates an HTTP server deployment in a single click on.
Various setup: For those who want a special platform or transport technique, scaffold regionally with npx create-xmcp-app@newest
As soon as deployed, you’ll see this mission construction:

Constructing our essential device
Our device will settle for three parameters: staff title, begin date, and finish date. It’ll then calculate the completion price for points inside that timeframe.
Head to the instruments listing, create a file referred to as get-completion-rate.ts
and export the three essential parts that assemble the syntax:
import { z } from "zod";
import { kind InferSchema, kind ToolMetadata } from "xmcp";
export const schema = {
staff: z
.string()
.min(1, "Staff title is required")
.describe("The staff to get completion price for"),
startDate: z
.string()
.min(1, "Begin date is required")
.describe("Begin date for the evaluation interval (YYYY-MM-DD)"),
endDate: z
.string()
.min(1, "Finish date is required")
.describe("Finish date for the evaluation interval (YYYY-MM-DD)"),
};
export const metadata: ToolMetadata = {
title: "get-completion-rate",
description: "Get completion price analytics for a particular staff over a date vary",
};
export default async perform getCompletionRate({
staff,
startDate,
endDate,
}: InferSchema<typeof schema>) {
// device implementation we'll cowl within the subsequent step
};
Our fundamental construction is ready. We now have so as to add the consumer performance to truly talk with Linear and get the information we want.
We’ll be utilizing Linear’s private API Key, so we’ll must instantiate the consumer utilizing @linear/sdk
. We’ll concentrate on the device implementation now:
export default async perform getCompletionRate({
staff,
startDate,
endDate,
}: InferSchema<typeof schema>) {
const linear = new LinearClient({
apiKey: // our api key
});
};
As an alternative of hardcoding API keys, we’ll use the native headers utilities to simply accept the Linear API key securely from every request:
export default async perform getCompletionRate({
staff,
startDate,
endDate,
}: InferSchema<typeof schema>) {
// API Key from headers
const apiKey = headers()["linear-api-key"] as string;
if (!apiKey) {
return "No linear-api-key header supplied";
}
const linear = new LinearClient({
apiKey: apiKey,
});
// remainder of the implementation
}
This strategy permits a number of customers to attach with their very own credentials. Your MCP configuration will appear like:
"xmcp-local": {
"url": "http://127.0.0.1:3001/mcp",
"headers": {
"linear-api-key": "your api key"
}
}
Transferring ahead with the implementation, that is what our full device file will appear like:
import { z } from "zod";
import { kind InferSchema, kind ToolMetadata } from "xmcp";
import { headers } from "xmcp/dist/runtime/headers";
import { LinearClient } from "@linear/sdk";
export const schema = {
staff: z
.string()
.min(1, "Staff title is required")
.describe("The staff to get completion price for"),
startDate: z
.string()
.min(1, "Begin date is required")
.describe("Begin date for the evaluation interval (YYYY-MM-DD)"),
endDate: z
.string()
.min(1, "Finish date is required")
.describe("Finish date for the evaluation interval (YYYY-MM-DD)"),
};
export const metadata: ToolMetadata = {
title: "get-completion-rate",
description: "Get completion price analytics for a particular staff over a date vary",
};
export default async perform getCompletionRate({
staff,
startDate,
endDate,
}: InferSchema<typeof schema>) {
// API Key from headers
const apiKey = headers()["linear-api-key"] as string;
if (!apiKey) {
return "No linear-api-key header supplied";
}
const linear = new LinearClient({
apiKey: apiKey,
});
// Get the staff by title
const groups = await linear.groups();
const targetTeam = groups.nodes.discover(t => t.title.toLowerCase().consists of(staff.toLowerCase()));
if (!targetTeam) {
return `Staff "${staff}" not discovered`
}
// Get points created within the date vary for the staff
const createdIssues = await linear.points({
filter: {
staff: { id: { eq: targetTeam.id } },
createdAt: {
gte: startDate,
lte: endDate,
},
},
});
// Get points accomplished within the date vary for the staff (for reporting functions)
const completedIssues = await linear.points({
filter: {
staff: { id: { eq: targetTeam.id } },
completedAt: {
gte: startDate,
lte: endDate,
},
},
});
// Calculate completion price: share of created points that had been accomplished
const totalCreated = createdIssues.nodes.size;
const createdAndCompleted = createdIssues.nodes.filter(concern =>
concern.completedAt !== undefined &&
concern.completedAt >= new Date(startDate) &&
concern.completedAt <= new Date(endDate)
).size;
const completionRate = totalCreated > 0 ? (createdAndCompleted / totalCreated * 100).toFixed(1) : "0.0";
// Construction knowledge for the response
const analytics = {
staff: targetTeam.title,
interval: `${startDate} to ${endDate}`,
totalCreated,
totalCompletedFromCreated: createdAndCompleted,
completionRate: `${completionRate}%`,
createdIssues: createdIssues.nodes.map(concern => ({
title: concern.title,
createdAt: concern.createdAt,
precedence: concern.precedence,
accomplished: concern.completedAt !== null,
completedAt: concern.completedAt,
})),
allCompletedInPeriod: completedIssues.nodes.map(concern => ({
title: concern.title,
completedAt: concern.completedAt,
precedence: concern.precedence,
})),
};
return JSON.stringify(analytics, null, 2);
}
Let’s check it out!
Begin your growth server by operating pnpm dev
(or the bundle supervisor you’ve arrange)
The server will routinely restart everytime you make adjustments to your instruments, supplying you with on the spot suggestions throughout growth. Then, head to Cursor Settings → Instruments & Integrations and toggle the server on. You must see it’s discovering one device file, which is our solely file within the listing.

Let’s now use the device by querying to “Get the completion price of the xmcp mission between August 1st 2025 and August twentieth 2025”.

Let’s attempt utilizing this device in a extra complete manner: we wish to perceive the mission’s completion price in three separate months, June, July and August, and visualize the tendency. So we’ll ask Cursor to retrieve the knowledge for these months, and generate a bent chart and a month-to-month concern overview:

As soon as we’re proud of the implementation, we’ll push our adjustments and deploy a brand new model of our server.
Professional tip: use Vercel’s department deployments to check new instruments safely earlier than merging to manufacturing.
Subsequent steps
Good! We’ve constructed the muse, however there’s a lot extra you are able to do with it.
- Develop your MCP toolkit with a whole workflow automation. Take this MCP server as a place to begin and add instruments that generate weekly dash studies and routinely save them to Notion, or construct integrations that join a number of mission administration platforms.
- Leverage the appliance by including authentication. You should utilize the OAuth native supplier so as to add Linear’s authentication as an alternative of utilizing API Keys, or use the Higher Auth integration to deal with {custom} authentication paths that suit your group’s safety necessities.
- For manufacturing workloads, it’s possible you’ll want so as to add {custom} middlewares, like price limiting, request logging, and error monitoring. This may be simply arrange by making a
middleware.ts
file within the supply listing. You’ll be able to be taught extra about middlewares right here.
Closing ideas
The most effective a part of what you’ve constructed right here is that xmcp dealt with all of the protocol complexity for you. You didn’t should be taught the intricacies of the Mannequin Context Protocol specification or determine transport layers: you simply targeted on fixing your precise enterprise drawback. That’s precisely the way it must be.
Wanting forward, xmcp’s roadmap consists of full MCP specification compliance, bringing help for sources, prompts and elicitation. Extra importantly, the framework is evolving to bridge the hole between prototype and manufacturing, with enterprise-grade options for authentication, monitoring, and scalability.
For those who want to be taught extra in regards to the framework, go to xmcp.dev, learn the documentation and take a look at the examples!