Intro
Everybody is talking about MCP servers and clients these days.
However, the majority of tutorials only give you the weather MCP, which is fine, but i wanted to try it on a different topic, stock trading news.
The Model Context Protocol (MCP) provides a standard way for AI assistants to interact with external tools and data sources.
This tutorial walks through creating a functional MCP server from scratch, using a real-world example that fetches trading news from Alpha Vantage API.
What You Will Build
By the end of this guide, you will have a working MCP server that exposes tools AI assistants can use to fetch real-time trading news.
The server connects to the Alpha Vantage API and provides structured responses that AI models can process and present to users.
Now, does Alpha Vantage have an MCP? Yes, they do: https://mcp.alphavantage.co/
Was it fun building my own? Also yes.
Prerequisites
Before starting, ensure you have the following installed on your system:
- Java Development Kit (JDK) 21 or higher
- Maven 3.8 or higher
- A text editor or IDE (IntelliJ IDEA, VS Code, or Eclipse)
- An Alpha Vantage API key (free tier available at alphavantage.co)
Or, checkout the code: https://github.com/adrianprecub/blog/tree/main/mcp-server-trading-news
Step 1: Project Setup
Create a new directory for your project and navigate to it:
mkdir mcp-server-trading-news
cd mcp-server-trading-news
Create the Maven project structure:
mkdir -p src/main/java/com/trading/news
mkdir -p src/main/java/com/trading/news/model
mkdir -p src/main/resources
mkdir -p src/test/java
Step 2: Configure the Build File
Create a pom.xml file in the project root with the following configuration: https://github.com/adrianprecub/blog/blob/main/mcp-server-trading-news/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.trading.news</groupId>
<artifactId>mcp-server-trading-news</artifactId>
<name>Trading News MCP Server</name>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.14.0</compiler-plugin.version>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<quarkus.platform.version>3.26.3</quarkus.platform.version>
</properties>
.....
</project>
This configuration sets up Quarkus with the MCP server extension, which handles the protocol implementation details for you.
Step 3: Create the Data Models
Create model classes to represent the news data. You can see the full classes in the github repo.
First, create src/main/java/com/trading/news/model/NewsArticle.java:
package com.trading.news.model;
public class NewsArticle {
private String title;
private String url;
private String summary;
....
}
Next, create src/main/java/com/trading/news/model/NewsResponse.java:
package com.trading.news.model;
public class NewsResponse {
@JsonProperty("items")
private String items;
@JsonProperty("sentiment_score_definition")
private String sentimentScoreDefinition;
@JsonProperty("relevance_score_definition")
private String relevanceScoreDefinition;
@JsonProperty("feed")
private List feed;
....
}
Step 4: Create the REST Client
The REST client interfaces with the external API. Create src/main/java/com/trading/news/AlphaVantageNewsClient.java:
package com.trading.news;
@Path("/query")
@RegisterRestClient(configKey="alphavantagenews")
@Produces(MediaType.APPLICATION_JSON)
public interface AlphaVantageNewsClient {
@GET
NewsResponse getNewsByCategory(
@QueryParam("function") String function,
@QueryParam("topics") String topics,
@QueryParam("apikey") String apiKey
);
@GET
NewsResponse getNewsByTickers(
@QueryParam("function") String function,
@QueryParam("tickers") String tickers,
@QueryParam("apikey") String apiKey
);
}
Step 5: Implement MCP Tools
MCP tools are the functions that AI assistants can call. Create src/main/java/com/trading/news/AlphaVantageTools.java:
package com.trading.news;
public class AlphaVantageTools {
public static final String NEWS_SENTIMENT_FUNCTION = "NEWS_SENTIMENT";
public static final String CATEGORY = "general";
private final AlphaVantageNewsClient newsClient;
private final String apiKey;
public AlphaVantageTools(@RestClient AlphaVantageNewsClient newsClient,
@ConfigProperty(name = "alphaVantage.api.key") String apiKey) {
this.newsClient = newsClient;
this.apiKey = apiKey;
}
@Tool(description = "Get general trading news.")
NewsResponse get_trading_news() {
return newsClient.getNewsByCategory(NEWS_SENTIMENT_FUNCTION, CATEGORY, apiKey);
}
@Tool(description = "Get trading news by comma-separated tickers.")
NewsResponse get_trading_news_by_tickers(@ToolArg(description = "Tickers for which to get the trading news.", required = true) String tickers) {
return newsClient.getNewsByTickers(NEWS_SENTIMENT_FUNCTION, tickers, apiKey);
}
}
The @Tool annotation marks methods as MCP tools. The @ToolArg annotation documents parameters that AI assistants will provide.
Step 6: Configure the Application
Create src/main/resources/application.properties:
# Run the MCP server on port 8082
quarkus.http.port=8082
# Configure MCP server
quarkus.mcp.server.server-info.name=Trading News Service
quarkus.mcp.server.traffic-logging.enabled=true
quarkus.mcp.server.traffic-logging.text-limit=100
# Configure the Rest Client
quarkus.rest-client.logging.scope=request-response
quarkus.rest-client.follow-redirects=true
quarkus.rest-client.logging.body-limit=150
quarkus.rest-client."alphavantagenews".uri=https://www.alphavantage.co/
alphaVantage.api.key=${ALPHAVANTAGE_API_KEY: demo}
# Package as an uber-jar
quarkus.package.jar.type=uber-jar
The configuration uses environment variables for the API key, falling back to "demo" if not set.
Step 7: Build and Test the Server
First, set your Alpha Vantage API key as an environment variable:
export ALPHAVANTAGE_API_KEY=your_actual_api_key_here
Build the project:
./mvnw clean compile
Run the server in development mode with hot reload:
./mvnw quarkus:dev
The server will start on port 8082. You should see output indicating the MCP server is running.
Step 8: Test the MCP Server
To verify your server works correctly, test it using Postman. The MCP protocol uses Server-Sent Events (SSE) for communication.
Setting up Postman for SSE testing:
1.First create a new request and change the protocol to MCP
2. You will then have two options: HTTP(i know, confusing) and STDIO. Choose HTTP:
3. In the Headers tab, add: Accept: text/event-stream
4. Click Connect on the right side and you should see the following:
Testing tool invocation:
If you select get_trading_news and click on Run you should see something like below:
Step 9: Connect to an AI Assistant
To use your MCP server with Claude or another AI assistant that supports MCP, you need to configure the assistant to connect to your server. The exact configuration depends on your client, but typically involves:
- Adding your server URL (http://localhost:8082) to the MCP server list
- Specifying the server type as SSE (Server-Sent Events)
- Restarting the AI assistant client
Once connected, the AI assistant will discover your tools automatically and can call them when users ask for trading news.
Step 10: Packaging as a docker image
Build a standalone JAR file:
./mvnw clean package
This creates an uber-jar in the target directory containing all dependencies. Run it with:
java -jar target/mcp-server-trading-news-1.0.0-SNAPSHOT-runner.jar
For production deployment, consider containerizing the application using Docker:
# Create a Dockerfile
FROM eclipse-temurin:21-jre
COPY target/*-runner.jar app.jar
EXPOSE 8082
ENTRYPOINT ["java", "-jar", "/app.jar"]
Understanding the Architecture
The MCP server architecture consists of several layers working together:
Protocol Layer: The Quarkus MCP extension handles the SSE protocol, message formatting, and communication with AI clients. You don't need to implement protocol details.
Tool Layer: Your tool methods define what capabilities the AI assistant gains. Each tool should have a clear purpose and return structured data the AI can interpret.
Integration Layer: REST clients and other integrations connect your tools to external services. This separation keeps your tools focused on their interface to the AI.
Configuration Layer: Application properties control server behavior, API endpoints, and security settings. Use environment variables for sensitive configuration.
Best Practices for MCP Server Development
Tool Design: Keep tools focused on single responsibilities. A tool that fetches news should only fetch news, not also analyze or format it. Let the AI assistant handle presentation.
Error Handling: Return meaningful error messages that help the AI understand what went wrong. Avoid exposing internal implementation details or stack traces.
Documentation: Use descriptive tool and argument annotations. The AI assistant relies on these descriptions to understand when and how to use your tools.
Performance: Consider caching responses for expensive operations. The Alpha Vantage API has rate limits, so cache recent responses to avoid hitting limits during development.
Security: Never expose sensitive credentials through tool responses. Use proper authentication and validate all inputs, even though they come from the AI assistant.
Extending Your Server
Once your basic server works, consider adding these features:
Additional Tools: Add tools for technical analysis, historical data, or market statistics. Each new capability makes your server more useful.
Response Caching: Implement a simple cache to store recent API responses. This improves performance and helps stay within API rate limits.
Data Enrichment: Process raw API responses to add calculated fields, summaries, or derived insights before returning them to the AI.
Monitoring: Add health checks and metrics to monitor your server's performance and usage patterns in production.
Troubleshooting Common Issues
Server won't start: Check that port 8082 is available and no other process is using it. Verify your Java version meets the minimum requirement.
API calls fail: Confirm your API key is valid and properly set in the environment. Check the Alpha Vantage API status and your rate limits.
Tools don't appear in the AI assistant: Ensure your tool methods have the correct annotations and return types. Check the server logs for registration errors.
Connection drops: SSE connections can timeout. Configure your server and any proxies to maintain long-lived connections.
Conclusion
You now have a working MCP server that provides trading news to AI assistants. This foundation can be extended with additional tools, data sources, and capabilities based on your specific needs.
The MCP protocol abstracts the complexity of AI-tool communication, letting you focus on building useful capabilities. As the ecosystem grows, your server can integrate with more AI assistants and automation platforms that support the protocol.
Remember to keep your tools simple, well-documented, and focused on providing value to the AI assistant's users. Good MCP servers enhance AI capabilities without adding complexity for end users.