stockquotes-mcp 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +257 -0
- package/README.sample1.png +0 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +146 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +34 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +66 -0
- package/dist/server.js.map +1 -0
- package/dist/stockQuotesService.d.ts +39 -0
- package/dist/stockQuotesService.d.ts.map +1 -0
- package/dist/stockQuotesService.js +140 -0
- package/dist/stockQuotesService.js.map +1 -0
- package/dist/toolRegistration.d.ts +9 -0
- package/dist/toolRegistration.d.ts.map +1 -0
- package/dist/toolRegistration.js +81 -0
- package/dist/toolRegistration.js.map +1 -0
- package/dist/transports/HttpTransportStrategy.d.ts +52 -0
- package/dist/transports/HttpTransportStrategy.d.ts.map +1 -0
- package/dist/transports/HttpTransportStrategy.js +167 -0
- package/dist/transports/HttpTransportStrategy.js.map +1 -0
- package/dist/transports/StdioTransportStrategy.d.ts +37 -0
- package/dist/transports/StdioTransportStrategy.d.ts.map +1 -0
- package/dist/transports/StdioTransportStrategy.js +54 -0
- package/dist/transports/StdioTransportStrategy.js.map +1 -0
- package/dist/transports/TransportFactory.d.ts +16 -0
- package/dist/transports/TransportFactory.d.ts.map +1 -0
- package/dist/transports/TransportFactory.js +24 -0
- package/dist/transports/TransportFactory.js.map +1 -0
- package/dist/transports/TransportStrategy.d.ts +24 -0
- package/dist/transports/TransportStrategy.d.ts.map +1 -0
- package/dist/transports/TransportStrategy.js +2 -0
- package/dist/transports/TransportStrategy.js.map +1 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/yahooFinanceClient.d.ts +14 -0
- package/dist/yahooFinanceClient.d.ts.map +1 -0
- package/dist/yahooFinanceClient.js +20 -0
- package/dist/yahooFinanceClient.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { format } from 'date-fns';
|
|
2
|
+
/**
|
|
3
|
+
* Service for fetching stock quotes from Yahoo Finance
|
|
4
|
+
*/
|
|
5
|
+
export class StockQuotesService {
|
|
6
|
+
yahooClient;
|
|
7
|
+
/**
|
|
8
|
+
* Create a new instance of the StockQuotesService
|
|
9
|
+
*/
|
|
10
|
+
constructor(yahooClient) {
|
|
11
|
+
this.yahooClient = yahooClient;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Fetch a stock quote for the given ticker symbol
|
|
15
|
+
* @param input - The stock quote input containing the ticker and optional fields
|
|
16
|
+
* @returns Promise<StockQuoteResponse> - The stock quote data
|
|
17
|
+
*/
|
|
18
|
+
async getQuote(input) {
|
|
19
|
+
const { ticker, fields } = input;
|
|
20
|
+
try {
|
|
21
|
+
const validFields = fields ? fields.filter((field) => field.length > 0) : undefined;
|
|
22
|
+
const options = validFields ? { fields: validFields } : undefined;
|
|
23
|
+
const result = await this.yahooClient.quote(ticker, options);
|
|
24
|
+
if (!result) {
|
|
25
|
+
throw new Error(`Stock ticker '${ticker}' not found`);
|
|
26
|
+
}
|
|
27
|
+
const quote = Array.isArray(result) ? result[0] : result;
|
|
28
|
+
if (!quote) {
|
|
29
|
+
throw new Error(`Stock ticker '${ticker}' not found`);
|
|
30
|
+
}
|
|
31
|
+
const response = {
|
|
32
|
+
symbol: quote.symbol ?? ticker,
|
|
33
|
+
name: quote.shortName ?? quote.longName,
|
|
34
|
+
exchange: quote.exchange,
|
|
35
|
+
currency: quote.currency,
|
|
36
|
+
regularMarketPrice: quote.regularMarketPrice,
|
|
37
|
+
regularMarketChange: quote.regularMarketChange,
|
|
38
|
+
regularMarketChangePercent: quote.regularMarketChangePercent,
|
|
39
|
+
regularMarketVolume: quote.regularMarketVolume,
|
|
40
|
+
marketCap: quote.marketCap,
|
|
41
|
+
fiftyTwoWeekLow: quote.fiftyTwoWeekLow,
|
|
42
|
+
fiftyTwoWeekHigh: quote.fiftyTwoWeekHigh,
|
|
43
|
+
averageDailyVolume3Month: quote.averageDailyVolume3Month,
|
|
44
|
+
trailingPE: quote.trailingPE,
|
|
45
|
+
forwardPE: quote.forwardPE,
|
|
46
|
+
dividendYield: quote.dividendYield,
|
|
47
|
+
epsTrailingTwelveMonths: quote.epsTrailingTwelveMonths,
|
|
48
|
+
epsForward: quote.epsForward,
|
|
49
|
+
bookValue: quote.bookValue,
|
|
50
|
+
priceToBook: quote.priceToBook,
|
|
51
|
+
marketState: quote.marketState,
|
|
52
|
+
quoteType: quote.quoteType,
|
|
53
|
+
};
|
|
54
|
+
Object.keys(response).forEach((key) => response[key] === undefined &&
|
|
55
|
+
delete response[key]);
|
|
56
|
+
return response;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (error instanceof Error) {
|
|
60
|
+
if (error.message.includes('No definition') || error.message.includes('not found')) {
|
|
61
|
+
throw new Error(`Stock ticker '${ticker}' not found`);
|
|
62
|
+
}
|
|
63
|
+
if (error.message.includes('rate limit')) {
|
|
64
|
+
throw new Error('Rate limit exceeded. Please try again later');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Fetch multiple stock quotes at once
|
|
72
|
+
* @param tickers - Array of ticker symbols
|
|
73
|
+
* @returns Promise<Map<string, StockQuoteResponse>> - Map of ticker to stock quote data
|
|
74
|
+
*/
|
|
75
|
+
async getMultipleQuotes(tickers) {
|
|
76
|
+
const results = new Map();
|
|
77
|
+
for (const ticker of tickers) {
|
|
78
|
+
try {
|
|
79
|
+
const quote = await this.getQuote({ ticker });
|
|
80
|
+
results.set(ticker, quote);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error(`Failed to fetch quote for ${ticker}:`, error);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return results;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Search for a company by name or ticker
|
|
90
|
+
* @param query - Search query string
|
|
91
|
+
* @returns Promise<Array<{symbol: string, name: string, exchange: string}>> - Search results
|
|
92
|
+
*/
|
|
93
|
+
async search(query) {
|
|
94
|
+
const results = await this.yahooClient.search(query);
|
|
95
|
+
const quotes = results.quotes ?? [];
|
|
96
|
+
return quotes
|
|
97
|
+
.filter((quote) => typeof quote.symbol === 'string' &&
|
|
98
|
+
typeof quote.exchange === 'string' &&
|
|
99
|
+
(typeof quote.shortname === 'string' || typeof quote.longname === 'string'))
|
|
100
|
+
.map((result) => ({
|
|
101
|
+
symbol: result.symbol,
|
|
102
|
+
name: result.shortname ?? result.longname ?? '',
|
|
103
|
+
exchange: result.exchange,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Fetches historical stock data for a given ticker, from a start date to an end date.
|
|
108
|
+
* @param ticker - Stock ticker symbol (e.g., AAPL)
|
|
109
|
+
* @param fromDate - Start date in 'YYYY-MM-DD' format
|
|
110
|
+
* @param toDate - End date in 'YYYY-MM-DD' format
|
|
111
|
+
* @returns Promise<number[]> - An array of closing prices for each day.
|
|
112
|
+
*/
|
|
113
|
+
async getHistoricalData(ticker, fromDate, toDate) {
|
|
114
|
+
try {
|
|
115
|
+
const chart = await this.yahooClient.chart(ticker, {
|
|
116
|
+
period1: fromDate,
|
|
117
|
+
period2: toDate,
|
|
118
|
+
});
|
|
119
|
+
const historicalData = [];
|
|
120
|
+
const quotes = chart.quotes ?? [];
|
|
121
|
+
for (const quote of quotes) {
|
|
122
|
+
if (quote.date && quote.close && quote.high && quote.low && quote.volume) {
|
|
123
|
+
historicalData.push({
|
|
124
|
+
date: format(new Date(quote.date), 'yyyy-MM-dd'),
|
|
125
|
+
close: quote.close,
|
|
126
|
+
high: quote.high,
|
|
127
|
+
low: quote.low,
|
|
128
|
+
volume: quote.volume,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return historicalData;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error(`Error fetching historical data for ${ticker}:`, error);
|
|
136
|
+
throw new Error(`Could not fetch historical data for ${ticker}. Please check the ticker and date range.`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=stockQuotesService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stockQuotesService.js","sourceRoot":"","sources":["../src/stockQuotesService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { StockQuotesService } from './stockQuotesService.js';
|
|
3
|
+
/**
|
|
4
|
+
* Register all MCP tools on a server instance
|
|
5
|
+
* @param server - MCP server instance to register tools on
|
|
6
|
+
* @param stockService - Stock quotes service instance
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerToolsOnServer(server: McpServer, stockService: StockQuotesService): void;
|
|
9
|
+
//# sourceMappingURL=toolRegistration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolRegistration.d.ts","sourceRoot":"","sources":["../src/toolRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,GAAG,IAAI,CA4F/F"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Register all MCP tools on a server instance
|
|
4
|
+
* @param server - MCP server instance to register tools on
|
|
5
|
+
* @param stockService - Stock quotes service instance
|
|
6
|
+
*/
|
|
7
|
+
export function registerToolsOnServer(server, stockService) {
|
|
8
|
+
server.registerTool(`get_stock_quote`, {
|
|
9
|
+
title: 'Get Stock Quote',
|
|
10
|
+
description: 'Fetch current stock quote data from Yahoo Finance for a given ticker symbol. ' +
|
|
11
|
+
'Returns price, volume, market cap, P/E ratio, 52-week range, and other key metrics. ' +
|
|
12
|
+
'Supports stocks, ETFs, cryptocurrencies, and other financial instruments.',
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
ticker: z.string().min(1).max(10).describe('Stock ticker symbol (e.g., AAPL, GOOGL, MSFT)'),
|
|
15
|
+
fields: z
|
|
16
|
+
.array(z.string())
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Optional list of specific fields to return'),
|
|
19
|
+
}),
|
|
20
|
+
}, async ({ ticker, fields }) => {
|
|
21
|
+
console.log(`Fetching stock quote for ticker: ${ticker}`);
|
|
22
|
+
const quote = await stockService.getQuote({ ticker, fields });
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: JSON.stringify(quote, null, 2),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
structuredContent: quote,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
server.registerTool('search_stocks', {
|
|
34
|
+
title: 'Search Stocks',
|
|
35
|
+
description: 'Search for stocks by company name or ticker symbol. ' +
|
|
36
|
+
'Returns matching results with symbol, name, and exchange information.',
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
query: z.string().min(1).describe('Search query (company name or ticker)'),
|
|
39
|
+
}),
|
|
40
|
+
}, async ({ query }) => {
|
|
41
|
+
console.log(`Searching stocks with query: ${query}`);
|
|
42
|
+
const results = await stockService.search(query);
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: JSON.stringify(results, null, 2),
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
structuredContent: { results },
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
server.registerTool(`get_historical_data`, {
|
|
54
|
+
title: 'Get Historical Data for a TICKER',
|
|
55
|
+
description: 'Fetch historical stock data for a given ticker, from a start date to an end date. Returns an array of closing prices for each day.',
|
|
56
|
+
inputSchema: z.object({
|
|
57
|
+
ticker: z.string().min(1).max(10).describe('Stock ticker symbol (e.g., AAPL)'),
|
|
58
|
+
fromDate: z
|
|
59
|
+
.string()
|
|
60
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
61
|
+
.describe('Start date in YYYY-MM-DD format'),
|
|
62
|
+
toDate: z
|
|
63
|
+
.string()
|
|
64
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
65
|
+
.describe('End date in YYYY-MM-DD format'),
|
|
66
|
+
}),
|
|
67
|
+
}, async ({ ticker, fromDate, toDate }) => {
|
|
68
|
+
console.log(`Fetching historical data for ${ticker} from ${fromDate} to ${toDate}`);
|
|
69
|
+
const closingPrices = await stockService.getHistoricalData(ticker, fromDate, toDate);
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: 'text',
|
|
74
|
+
text: JSON.stringify({ closingPrices }, null, 2),
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
structuredContent: { closingPrices },
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=toolRegistration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolRegistration.js","sourceRoot":"","sources":["../src/toolRegistration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type express from 'express';
|
|
3
|
+
import type { StockQuotesService } from '../stockQuotesService.js';
|
|
4
|
+
import type { TransportStrategy } from './TransportStrategy.js';
|
|
5
|
+
/**
|
|
6
|
+
* HTTP Transport Strategy
|
|
7
|
+
* Handles connection via HTTP transport
|
|
8
|
+
*/
|
|
9
|
+
export declare class HttpTransportStrategy implements TransportStrategy {
|
|
10
|
+
private server;
|
|
11
|
+
private stockService;
|
|
12
|
+
private serverName;
|
|
13
|
+
private serverVersion;
|
|
14
|
+
private expressApp?;
|
|
15
|
+
private httpPort;
|
|
16
|
+
private httpHost;
|
|
17
|
+
private httpServer?;
|
|
18
|
+
/**
|
|
19
|
+
* Create a new HttpTransportStrategy instance
|
|
20
|
+
* @param serverName - Name of the server
|
|
21
|
+
* @param serverVersion - Version of the server
|
|
22
|
+
* @param stockService - Stock quotes service instance
|
|
23
|
+
* @param httpPort - HTTP port to listen on
|
|
24
|
+
* @param httpHost - HTTP host to bind to (default: '0.0.0.0')
|
|
25
|
+
*/
|
|
26
|
+
constructor(serverName: string, serverVersion: string, stockService: StockQuotesService, httpPort: number, httpHost?: string);
|
|
27
|
+
/**
|
|
28
|
+
* Connect using HTTP transport
|
|
29
|
+
*/
|
|
30
|
+
connect(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Setup Express routes for stateless Streamable HTTP transport
|
|
33
|
+
*/
|
|
34
|
+
private setupExpressRoutes;
|
|
35
|
+
/**
|
|
36
|
+
* Get the transport type
|
|
37
|
+
*/
|
|
38
|
+
getType(): string;
|
|
39
|
+
/**
|
|
40
|
+
* Get the server instance for tool registration
|
|
41
|
+
*/
|
|
42
|
+
getServer(): McpServer;
|
|
43
|
+
/**
|
|
44
|
+
* Get the Express app instance (for testing or custom transport setups)
|
|
45
|
+
*/
|
|
46
|
+
getApp(): express.Application;
|
|
47
|
+
/**
|
|
48
|
+
* Close the server and cleanup resources
|
|
49
|
+
*/
|
|
50
|
+
close(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=HttpTransportStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpTransportStrategy.d.ts","sourceRoot":"","sources":["../../src/transports/HttpTransportStrategy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,UAAU,CAAC,CAAsB;IACzC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAC,CAA4C;IAE/D;;;;;;;OAOG;gBAED,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,kBAAkB,EAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAkB;IAa9B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA2E1B;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,SAAS,IAAI,SAAS;IAItB;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,WAAW;IAO7B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js';
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
4
|
+
import { registerToolsOnServer } from '../toolRegistration.js';
|
|
5
|
+
/**
|
|
6
|
+
* HTTP Transport Strategy
|
|
7
|
+
* Handles connection via HTTP transport
|
|
8
|
+
*/
|
|
9
|
+
export class HttpTransportStrategy {
|
|
10
|
+
server;
|
|
11
|
+
stockService;
|
|
12
|
+
serverName;
|
|
13
|
+
serverVersion;
|
|
14
|
+
expressApp;
|
|
15
|
+
httpPort;
|
|
16
|
+
httpHost;
|
|
17
|
+
httpServer;
|
|
18
|
+
/**
|
|
19
|
+
* Create a new HttpTransportStrategy instance
|
|
20
|
+
* @param serverName - Name of the server
|
|
21
|
+
* @param serverVersion - Version of the server
|
|
22
|
+
* @param stockService - Stock quotes service instance
|
|
23
|
+
* @param httpPort - HTTP port to listen on
|
|
24
|
+
* @param httpHost - HTTP host to bind to (default: '0.0.0.0')
|
|
25
|
+
*/
|
|
26
|
+
constructor(serverName, serverVersion, stockService, httpPort, httpHost = '0.0.0.0') {
|
|
27
|
+
this.serverName = serverName;
|
|
28
|
+
this.serverVersion = serverVersion;
|
|
29
|
+
this.stockService = stockService;
|
|
30
|
+
this.httpPort = httpPort;
|
|
31
|
+
this.httpHost = httpHost;
|
|
32
|
+
this.server = new McpServer({
|
|
33
|
+
name: serverName,
|
|
34
|
+
version: serverVersion,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Connect using HTTP transport
|
|
39
|
+
*/
|
|
40
|
+
async connect() {
|
|
41
|
+
this.setupExpressRoutes();
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
this.httpServer = this.expressApp?.listen(this.httpPort);
|
|
44
|
+
if (!this.httpServer) {
|
|
45
|
+
reject(new Error('Failed to create HTTP server'));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.httpServer.on('listening', () => {
|
|
49
|
+
console.log(`MCP Server running on http://localhost:${this.httpPort}/mcp`);
|
|
50
|
+
resolve();
|
|
51
|
+
});
|
|
52
|
+
this.httpServer.on('error', (error) => {
|
|
53
|
+
if (error.code === 'EADDRINUSE') {
|
|
54
|
+
console.error(`Error: Port ${this.httpPort} is already in use. Please check if another process is using this port or specify a different port using --http-port.`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error(`Error starting HTTP server: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
reject(new Error(`Failed to start HTTP server: ${error.message}`));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Setup Express routes for stateless Streamable HTTP transport
|
|
65
|
+
*/
|
|
66
|
+
setupExpressRoutes() {
|
|
67
|
+
this.expressApp ??= createMcpExpressApp({ host: this.httpHost });
|
|
68
|
+
// Main MCP endpoint for stateless Streamable HTTP
|
|
69
|
+
this.expressApp.post('/mcp', async (req, res) => {
|
|
70
|
+
try {
|
|
71
|
+
// Create a new MCP server instance for each request (stateless)
|
|
72
|
+
const server = new McpServer({
|
|
73
|
+
name: this.serverName,
|
|
74
|
+
version: this.serverVersion,
|
|
75
|
+
});
|
|
76
|
+
// Register tools on the new server instance
|
|
77
|
+
registerToolsOnServer(server, this.stockService);
|
|
78
|
+
// Create stateless transport (no session tracking)
|
|
79
|
+
const transport = new StreamableHTTPServerTransport({
|
|
80
|
+
sessionIdGenerator: undefined, // Stateless - no session tracking
|
|
81
|
+
});
|
|
82
|
+
// Connect server to transport
|
|
83
|
+
await server.connect(transport);
|
|
84
|
+
// Handle the request
|
|
85
|
+
await transport.handleRequest(req, res, req.body);
|
|
86
|
+
// Clean up when request is closed
|
|
87
|
+
res.on('close', async () => {
|
|
88
|
+
await transport.close();
|
|
89
|
+
await server.close();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('Error handling MCP request:', error);
|
|
94
|
+
if (!res.headersSent) {
|
|
95
|
+
res.status(500).json({
|
|
96
|
+
jsonrpc: '2.0',
|
|
97
|
+
error: {
|
|
98
|
+
code: -32603,
|
|
99
|
+
message: 'Internal server error',
|
|
100
|
+
},
|
|
101
|
+
id: null,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
// Health check endpoint
|
|
107
|
+
this.expressApp.get('/health', (req, res) => {
|
|
108
|
+
res.json({ status: 'healthy', name: this.serverName, version: this.serverVersion });
|
|
109
|
+
});
|
|
110
|
+
// Disallow GET and DELETE methods on /mcp endpoint
|
|
111
|
+
this.expressApp.get('/mcp', (req, res) => {
|
|
112
|
+
res.status(405).json({
|
|
113
|
+
jsonrpc: '2.0',
|
|
114
|
+
error: {
|
|
115
|
+
code: -32000,
|
|
116
|
+
message: 'Method not allowed.',
|
|
117
|
+
},
|
|
118
|
+
id: null,
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
this.expressApp.delete('/mcp', (req, res) => {
|
|
122
|
+
res.status(405).json({
|
|
123
|
+
jsonrpc: '2.0',
|
|
124
|
+
error: {
|
|
125
|
+
code: -32000,
|
|
126
|
+
message: 'Method not allowed.',
|
|
127
|
+
},
|
|
128
|
+
id: null,
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get the transport type
|
|
134
|
+
*/
|
|
135
|
+
getType() {
|
|
136
|
+
return 'http';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get the server instance for tool registration
|
|
140
|
+
*/
|
|
141
|
+
getServer() {
|
|
142
|
+
return this.server;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get the Express app instance (for testing or custom transport setups)
|
|
146
|
+
*/
|
|
147
|
+
getApp() {
|
|
148
|
+
if (!this.expressApp) {
|
|
149
|
+
this.setupExpressRoutes();
|
|
150
|
+
}
|
|
151
|
+
return this.expressApp;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Close the server and cleanup resources
|
|
155
|
+
*/
|
|
156
|
+
async close() {
|
|
157
|
+
await this.server.close();
|
|
158
|
+
if (this.httpServer) {
|
|
159
|
+
await new Promise((resolve) => {
|
|
160
|
+
this.httpServer.close(() => {
|
|
161
|
+
resolve();
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=HttpTransportStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpTransportStrategy.js","sourceRoot":"","sources":["../../src/transports/HttpTransportStrategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { StockQuotesService } from '../stockQuotesService.js';
|
|
3
|
+
import type { TransportStrategy } from './TransportStrategy.js';
|
|
4
|
+
/**
|
|
5
|
+
* Stdio Transport Strategy
|
|
6
|
+
* Handles connection via stdio transport
|
|
7
|
+
*/
|
|
8
|
+
export declare class StdioTransportStrategy implements TransportStrategy {
|
|
9
|
+
private server;
|
|
10
|
+
private stockService;
|
|
11
|
+
private serverName;
|
|
12
|
+
private serverVersion;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new StdioTransportStrategy instance
|
|
15
|
+
* @param serverName - Name of the server
|
|
16
|
+
* @param serverVersion - Version of the server
|
|
17
|
+
* @param stockService - Stock quotes service instance
|
|
18
|
+
*/
|
|
19
|
+
constructor(serverName: string, serverVersion: string, stockService: StockQuotesService);
|
|
20
|
+
/**
|
|
21
|
+
* Connect using stdio transport
|
|
22
|
+
*/
|
|
23
|
+
connect(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Get the transport type
|
|
26
|
+
*/
|
|
27
|
+
getType(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Get the server instance for tool registration
|
|
30
|
+
*/
|
|
31
|
+
getServer(): McpServer;
|
|
32
|
+
/**
|
|
33
|
+
* Close the server and cleanup resources
|
|
34
|
+
*/
|
|
35
|
+
close(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=StdioTransportStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioTransportStrategy.d.ts","sourceRoot":"","sources":["../../src/transports/StdioTransportStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;OAKG;gBACS,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB;IAUvF;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,SAAS,IAAI,SAAS;IAItB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
/**
|
|
4
|
+
* Stdio Transport Strategy
|
|
5
|
+
* Handles connection via stdio transport
|
|
6
|
+
*/
|
|
7
|
+
export class StdioTransportStrategy {
|
|
8
|
+
server;
|
|
9
|
+
stockService;
|
|
10
|
+
serverName;
|
|
11
|
+
serverVersion;
|
|
12
|
+
/**
|
|
13
|
+
* Create a new StdioTransportStrategy instance
|
|
14
|
+
* @param serverName - Name of the server
|
|
15
|
+
* @param serverVersion - Version of the server
|
|
16
|
+
* @param stockService - Stock quotes service instance
|
|
17
|
+
*/
|
|
18
|
+
constructor(serverName, serverVersion, stockService) {
|
|
19
|
+
this.serverName = serverName;
|
|
20
|
+
this.serverVersion = serverVersion;
|
|
21
|
+
this.stockService = stockService;
|
|
22
|
+
this.server = new McpServer({
|
|
23
|
+
name: serverName,
|
|
24
|
+
version: serverVersion,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Connect using stdio transport
|
|
29
|
+
*/
|
|
30
|
+
async connect() {
|
|
31
|
+
const transport = new StdioServerTransport();
|
|
32
|
+
await this.server.connect(transport);
|
|
33
|
+
console.log('MCP Server connected via stdio transport');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the transport type
|
|
37
|
+
*/
|
|
38
|
+
getType() {
|
|
39
|
+
return 'stdio';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the server instance for tool registration
|
|
43
|
+
*/
|
|
44
|
+
getServer() {
|
|
45
|
+
return this.server;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Close the server and cleanup resources
|
|
49
|
+
*/
|
|
50
|
+
async close() {
|
|
51
|
+
await this.server.close();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=StdioTransportStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioTransportStrategy.js","sourceRoot":"","sources":["../../src/transports/StdioTransportStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAIjF;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IACzB,MAAM,CAAY;IAClB,YAAY,CAAqB;IACjC,UAAU,CAAS;IACnB,aAAa,CAAS;IAE9B;;;;;OAKG;IACH,YAAY,UAAkB,EAAE,aAAqB,EAAE,YAAgC;QACrF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC;YAC1B,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,aAAa;SACvB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StockQuotesService } from '../stockQuotesService.js';
|
|
2
|
+
import type { ServerConfig } from '../types.js';
|
|
3
|
+
import type { TransportStrategy } from './TransportStrategy.js';
|
|
4
|
+
/**
|
|
5
|
+
* Transport Factory
|
|
6
|
+
* Creates appropriate transport strategy based on configuration
|
|
7
|
+
*/
|
|
8
|
+
export declare class TransportFactory {
|
|
9
|
+
/**
|
|
10
|
+
* Create a transport strategy based on configuration
|
|
11
|
+
* @param config - Server configuration
|
|
12
|
+
* @param stockService - Stock quotes service instance
|
|
13
|
+
*/
|
|
14
|
+
static createTransport(config: ServerConfig, stockService: StockQuotesService): TransportStrategy;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=TransportFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransportFactory.d.ts","sourceRoot":"","sources":["../../src/transports/TransportFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B;;;;OAIG;IACH,MAAM,CAAC,eAAe,CACpB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,kBAAkB,GAC/B,iBAAiB;CAgBrB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HttpTransportStrategy } from './HttpTransportStrategy.js';
|
|
2
|
+
import { StdioTransportStrategy } from './StdioTransportStrategy.js';
|
|
3
|
+
/**
|
|
4
|
+
* Transport Factory
|
|
5
|
+
* Creates appropriate transport strategy based on configuration
|
|
6
|
+
*/
|
|
7
|
+
export class TransportFactory {
|
|
8
|
+
/**
|
|
9
|
+
* Create a transport strategy based on configuration
|
|
10
|
+
* @param config - Server configuration
|
|
11
|
+
* @param stockService - Stock quotes service instance
|
|
12
|
+
*/
|
|
13
|
+
static createTransport(config, stockService) {
|
|
14
|
+
switch (config.transport) {
|
|
15
|
+
case 'stdio':
|
|
16
|
+
return new StdioTransportStrategy(config.name, config.version, stockService);
|
|
17
|
+
case 'http':
|
|
18
|
+
return new HttpTransportStrategy(config.name, config.version, stockService, config.httpPort ?? 3000, config.httpHost ?? '0.0.0.0');
|
|
19
|
+
default:
|
|
20
|
+
throw new Error(`Unsupported transport type: ${config.transport}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=TransportFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransportFactory.js","sourceRoot":"","sources":["../../src/transports/TransportFactory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IAC3B;;;;OAIG;IACH,MAAM,CAAC,eAAe,CACpB,MAAoB,EACpB,YAAgC;QAEhC,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;YACzB,KAAK,OAAO;gBACV,OAAO,IAAI,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/E,KAAK,MAAM;gBACT,OAAO,IAAI,qBAAqB,CAC9B,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,OAAO,EACd,YAAY,EACZ,MAAM,CAAC,QAAQ,IAAI,IAAI,EACvB,MAAM,CAAC,QAAQ,IAAI,SAAS,CAC7B,CAAC;YACJ;gBACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,SAAmB,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;CACF"}
|