In this tutorial, we’ll walk through building a simple Model Context Protocol (MCP) server in Dart using the mcp_dart package. We’ll then connect it to an MCP client like Cursor and explore how you can extend it for real-world use cases.
The Basics: What is MCP?
Model Context Protocol (MCP) is an open standard that allows seamless integration between LLM applications and external data sources or tools.
Think of MCP as the USB-C of AI integrations. Instead of building one-off integrations for every assistant, MCP provides a standardized way to connect tools and data.
Why does this matter?
Decoupling: Separates the “AI brain” (LLM) from your business logic.
Security: Provides controlled, local access to data and tools.
Reusability: Build an integration once and use it across multiple teams, clients, or products.
What We’ll Build
In this guide, we’ll create:
A Dart MCP server that communicates over stdio.
A sample tool that returns stock information.
An integration with Cursor, configured through mcp.json.
Prerequisites
Dart SDK installed
Cursor installed
Step 1: Create the Dart Project
Start by creating a new Dart console project and adding the mcp_dart package.
# Create a new console application
dart create -t console mcp_dart_server
cd mcp_dart_server
# Add dependencies
dart pub add mcp_dart
Step 2: Create the MCP Server
Create bin/mcp_server.dart with the following boilerplate code:
import ‘package:mcp_dart/mcp_dart.dart’;
void main() async {
McpServer server = McpServer(
Implementation(name: "mcp-dart-server", version: "1.0.0"),
options: ServerOptions(
capabilities: ServerCapabilities(
resources: ServerCapabilitiesResources(),
tools: ServerCapabilitiesTools(),
),
),
);
server.connect(StdioServerTransport());
}
Run it to confirm everything works:
dart run bin/mcp_server.dart
The server will start and wait for a client connection.
Step 3: Define a Stock Tool
To make this useful, let’s define a tool that provides stock information. For now, we’ll use a hardcoded list.
Project Structure
├── lib
│ ├── models
│ │ ├── models.dart
│ │ └── stock.dart
│ ├── repositories
│ │ └── stock_repository.dart
│ └── mcp_library.dart
└── bin
└── mcp_server.dart
Create the Model (lib/models/stock.dart)
typedef Ticker = String;
/// A Stock object which contains information of a Stock.
class Stock {
const Stock({
required this.ticker,
required this.name,
required this.price,
});
final Ticker ticker;
final String name;
final double price;
Map<String, dynamic> toJson() => {
'ticker': ticker,
'name': name,
'price': price,
};
}
Create the Repository (lib/repositories/stock_repository.dart
import 'package:mcp_dart_server/models/models.dart';
abstract class StockRepository {
Future<List<Stock>> getAllStocks();
}
class InMemoryStockRepository implements StockRepository {
final _stocks = [
Stock(ticker: 'AAPL', name: 'Apple Inc.', price: 228.86),
Stock(ticker: 'GOOG', name: 'Alphabet Inc.', price: 202.02),
Stock(ticker: 'META', name: 'Meta Platforms Inc.', price: 772.12),
];
@override
Future<List<Stock>> getAllStocks() async => _stocks;
}
Register the Tool in the Server (bin/mcp_server.dart)
import 'dart:convert';
import 'package:mcp_dart/mcp_dart.dart';
import 'package:mcp_dart_server/repositories/stock_repository.dart';
void main() async {
final server = McpServer(
Implementation(name: "mcp-dart-server", version: "1.0.0"),
options: ServerOptions(
capabilities: ServerCapabilities(
resources: ServerCapabilitiesResources(),
tools: ServerCapabilitiesTools(),
),
),
);
// Register stock tool
server.tool(
"get_stocks_information",
description: '''
MCP tool to get stock price information for Nasdaq tickers
like AAPL, GOOG, and META (Apple, Google, Meta).
''',
callback: ({args, extra}) async {
final stockRepository = InMemoryStockRepository();
final stocks = await stockRepository.getAllStocks();
return CallToolResult.fromContent(
content: [
TextContent(
text: jsonEncode(stocks.map((s) => s.toJson()).toList()),
),
],
);
},
);
server.connect(StdioServerTransport());
}
Step 4: Connect to Cursor
1. Compile the Server
dart compile exe bin/mcp_server.dart -o ./mcp_stocks_server
This generates an executable (mcp_stocks_server) in your project root.
2. Configure Cursor
Create or edit ~/.cursor/mcp.json:
{
"mcpServers": {
"stocks": {
"command": "/absolute/path/to/mcp_stocks_server"
}
}
}
Restart Cursor, and your new stocks tool will be available. The AI agent will automatically call it when asked for stock prices.
Next Steps
You now have a working MCP server in Dart that:
Registers tools with descriptive metadata
Exposes structured data
Integrates seamlessly with Cursor
From here, you can:
Replace the in-memory stock list with a real API (e.g., Yahoo Finance, Alpha Vantage).
Add more tools (e.g., “get_stock_history”).
Use MCP as a secure bridge between your AI assistant and internal systems.
Congratulations! You’ve built your first Dart MCP server. This foundation opens up endless possibilities for AI-driven integrations.

