stockmatrix-mcp 0.1.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 StockMatrix
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # stockmatrix-mcp
2
+
3
+ MCP server for Korean stock market theme lifecycle analysis. Provides real-time theme scores, lifecycle stages, related stocks, and news for 250+ KOSPI/KOSDAQ investment themes.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx -y stockmatrix-mcp
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ ### Claude Desktop
14
+
15
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "stockmatrix": {
21
+ "command": "npx",
22
+ "args": ["-y", "stockmatrix-mcp"]
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ ### Cursor
29
+
30
+ Add to `.cursor/mcp.json`:
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "stockmatrix": {
36
+ "command": "npx",
37
+ "args": ["-y", "stockmatrix-mcp"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### VS Code
44
+
45
+ Add to `.vscode/mcp.json`:
46
+
47
+ ```json
48
+ {
49
+ "servers": {
50
+ "stockmatrix": {
51
+ "command": "npx",
52
+ "args": ["-y", "stockmatrix-mcp"]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ## Available Tools
59
+
60
+ ### `get_theme_ranking`
61
+
62
+ 한국 주식시장 테마 생명주기 랭킹을 조회합니다. Retrieves theme lifecycle rankings by stage.
63
+
64
+ | Parameter | Type | Required | Description |
65
+ |-----------|------|----------|-------------|
66
+ | `stage` | string | No | Filter by stage: `emerging`, `growth`, `peak`, `decline`, `reigniting` |
67
+
68
+ ### `get_theme_detail`
69
+
70
+ 특정 테마의 상세 정보를 조회합니다. Gets detailed theme info including score, stage, related stocks, and news.
71
+
72
+ | Parameter | Type | Required | Description |
73
+ |-----------|------|----------|-------------|
74
+ | `theme_id` | string (UUID) | Yes | Theme UUID |
75
+
76
+ ### `get_theme_history`
77
+
78
+ 테마의 최근 30일 점수 이력을 조회합니다. Returns 30-day score history for a theme.
79
+
80
+ | Parameter | Type | Required | Description |
81
+ |-----------|------|----------|-------------|
82
+ | `theme_id` | string (UUID) | Yes | Theme UUID |
83
+
84
+ ### `search_themes`
85
+
86
+ 테마를 검색합니다. Searches themes by name in Korean or English.
87
+
88
+ | Parameter | Type | Required | Description |
89
+ |-----------|------|----------|-------------|
90
+ | `query` | string | Yes | Search query (e.g. `"AI"`, `"반도체"`, `"삼성전자"`) |
91
+
92
+ ### `get_stock_theme`
93
+
94
+ 특정 종목이 속한 테마를 조회합니다. Finds themes related to a specific stock code.
95
+
96
+ | Parameter | Type | Required | Description |
97
+ |-----------|------|----------|-------------|
98
+ | `symbol` | string | Yes | 6-digit Korean stock code (e.g. `"005930"` for Samsung) |
99
+
100
+ ## Environment Variables
101
+
102
+ | Variable | Default | Description |
103
+ |----------|---------|-------------|
104
+ | `STOCKMATRIX_API_URL` | `https://stockmatrix.co.kr` | API base URL |
105
+
106
+ ## Examples
107
+
108
+ **"What are the hottest stock themes in Korea right now?"**
109
+ → `get_theme_ranking` with `stage: "growth"`
110
+
111
+ **"Tell me about the semiconductor theme"**
112
+ → `search_themes` with `query: "반도체"` → `get_theme_detail` with the returned theme ID
113
+
114
+ **"What themes is Samsung Electronics part of?"**
115
+ → `get_stock_theme` with `symbol: "005930"`
116
+
117
+ ## Data Sources
118
+
119
+ - Naver DataLab search interest trends
120
+ - Naver Finance theme stock data
121
+ - Naver News article collection
122
+ - KRX (Korea Exchange) market data
123
+
124
+ ## License
125
+
126
+ MIT
127
+
128
+ ## Links
129
+
130
+ - [Website](https://stockmatrix.co.kr)
131
+ - [Developer Guide](https://stockmatrix.co.kr/developers)
132
+ - [GitHub](https://github.com/MongLong0214/stock-ai-newsletter)
133
+ - [llms.txt](https://stockmatrix.co.kr/llms.txt)
@@ -0,0 +1,3 @@
1
+ export declare const fetchApi: <T = unknown>(path: string, params?: Record<string, string>) => Promise<T>;
2
+ export declare const formatResult: (data: unknown) => string;
3
+ export declare const formatError: (error: unknown) => string;
@@ -0,0 +1,45 @@
1
+ const BASE_URL = process.env.STOCKMATRIX_API_URL || 'https://stockmatrix.co.kr';
2
+ // 시작 시 URL 유효성 검증
3
+ try {
4
+ new URL(BASE_URL);
5
+ }
6
+ catch {
7
+ throw new Error(`Invalid STOCKMATRIX_API_URL: "${BASE_URL}" is not a valid URL`);
8
+ }
9
+ export const fetchApi = async (path, params) => {
10
+ const url = new URL(path, BASE_URL);
11
+ if (params) {
12
+ for (const [key, value] of Object.entries(params)) {
13
+ url.searchParams.set(key, value);
14
+ }
15
+ }
16
+ const response = await fetch(url.toString(), {
17
+ headers: { Accept: 'application/json' },
18
+ });
19
+ if (!response.ok) {
20
+ const errorText = await response.text().catch(() => 'Unknown error');
21
+ throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
22
+ }
23
+ const contentType = response.headers.get('content-type') || '';
24
+ if (!contentType.includes('application/json')) {
25
+ const preview = await response.text().catch(() => '');
26
+ throw new Error(`Expected JSON response but got ${contentType || 'unknown'}: ${preview.slice(0, 200)}`);
27
+ }
28
+ const json = (await response.json());
29
+ if (json !== null &&
30
+ typeof json === 'object' &&
31
+ 'success' in json &&
32
+ 'data' in json) {
33
+ const wrapped = json;
34
+ if (!wrapped.success) {
35
+ throw new Error(wrapped.error?.message || 'API returned unsuccessful response');
36
+ }
37
+ return wrapped.data;
38
+ }
39
+ return json;
40
+ };
41
+ export const formatResult = (data) => JSON.stringify(data, null, 2);
42
+ export const formatError = (error) => {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ return `Error: ${message}`;
45
+ };
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { registerGetThemeRanking } from './tools/get-theme-ranking.js';
5
+ import { registerGetThemeDetail } from './tools/get-theme-detail.js';
6
+ import { registerGetThemeHistory } from './tools/get-theme-history.js';
7
+ import { registerSearchThemes } from './tools/search-themes.js';
8
+ import { registerGetStockTheme } from './tools/get-stock-theme.js';
9
+ const server = new McpServer({
10
+ name: 'stockmatrix-mcp',
11
+ version: '0.1.0',
12
+ });
13
+ registerGetThemeRanking(server);
14
+ registerGetThemeDetail(server);
15
+ registerGetThemeHistory(server);
16
+ registerSearchThemes(server);
17
+ registerGetStockTheme(server);
18
+ const main = async () => {
19
+ const transport = new StdioServerTransport();
20
+ await server.connect(transport);
21
+ console.error('StockMatrix MCP server running on stdio');
22
+ };
23
+ main().catch((error) => {
24
+ console.error('Fatal error in main():', error);
25
+ process.exit(1);
26
+ });
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare const registerGetStockTheme: (server: McpServer) => void;
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import { fetchApi, formatResult, formatError } from '../fetch-helper.js';
3
+ export const registerGetStockTheme = (server) => {
4
+ server.tool('get_stock_theme', '특정 종목이 속한 테마를 조회합니다. 종목 코드로 관련 테마 정보를 확인할 수 있습니다.', {
5
+ symbol: z
6
+ .string()
7
+ .regex(/^\d{6}$/, 'Korean stock code must be 6 digits')
8
+ .describe('Korean stock code (e.g. "005930" for Samsung Electronics, "000660" for SK Hynix)'),
9
+ }, async ({ symbol }) => {
10
+ try {
11
+ const data = await fetchApi(`/api/tli/stocks/${symbol}/theme`);
12
+ return {
13
+ content: [{ type: 'text', text: formatResult(data) }],
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ content: [{ type: 'text', text: formatError(error) }],
19
+ isError: true,
20
+ };
21
+ }
22
+ });
23
+ };
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare const registerGetThemeDetail: (server: McpServer) => void;
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import { fetchApi, formatResult, formatError } from '../fetch-helper.js';
3
+ export const registerGetThemeDetail = (server) => {
4
+ server.tool('get_theme_detail', '특정 테마의 상세 정보를 조회합니다. 테마 점수, 생명주기 단계, 관련 종목, 뉴스 등을 포함합니다.', {
5
+ theme_id: z
6
+ .string()
7
+ .uuid('Theme ID must be a valid UUID')
8
+ .describe('Theme UUID (e.g. "a1b2c3d4-e5f6-7890-abcd-ef1234567890")'),
9
+ }, async ({ theme_id }) => {
10
+ try {
11
+ const data = await fetchApi(`/api/tli/themes/${theme_id}`);
12
+ return {
13
+ content: [{ type: 'text', text: formatResult(data) }],
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ content: [{ type: 'text', text: formatError(error) }],
19
+ isError: true,
20
+ };
21
+ }
22
+ });
23
+ };
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare const registerGetThemeHistory: (server: McpServer) => void;
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import { fetchApi, formatResult, formatError } from '../fetch-helper.js';
3
+ export const registerGetThemeHistory = (server) => {
4
+ server.tool('get_theme_history', '테마의 최근 30일 점수 이력을 조회합니다. 생명주기 추이를 파악할 수 있습니다.', {
5
+ theme_id: z
6
+ .string()
7
+ .uuid('Theme ID must be a valid UUID')
8
+ .describe('Theme UUID (e.g. "a1b2c3d4-e5f6-7890-abcd-ef1234567890")'),
9
+ }, async ({ theme_id }) => {
10
+ try {
11
+ const data = await fetchApi(`/api/tli/themes/${theme_id}/history`);
12
+ return {
13
+ content: [{ type: 'text', text: formatResult(data) }],
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ content: [{ type: 'text', text: formatError(error) }],
19
+ isError: true,
20
+ };
21
+ }
22
+ });
23
+ };
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare const registerGetThemeRanking: (server: McpServer) => void;
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ import { fetchApi, formatResult, formatError } from '../fetch-helper.js';
3
+ const VALID_STAGES = [
4
+ 'emerging',
5
+ 'growth',
6
+ 'peak',
7
+ 'decline',
8
+ 'reigniting',
9
+ ];
10
+ export const registerGetThemeRanking = (server) => {
11
+ server.tool('get_theme_ranking', '한국 주식시장 테마 생명주기 랭킹을 조회합니다. 단계별(초기/성장/정점/쇠퇴/재점화) 테마 목록과 점수를 반환합니다.', {
12
+ stage: z
13
+ .enum(VALID_STAGES)
14
+ .optional()
15
+ .describe('Filter by lifecycle stage: emerging (초기), growth (성장), peak (정점), decline (쇠퇴), reigniting (재점화)'),
16
+ }, async ({ stage }) => {
17
+ try {
18
+ const data = await fetchApi('/api/tli/scores/ranking');
19
+ if (stage) {
20
+ const stageData = data[stage];
21
+ const summary = data.summary;
22
+ return {
23
+ content: [
24
+ {
25
+ type: 'text',
26
+ text: formatResult({ stage, themes: stageData, summary }),
27
+ },
28
+ ],
29
+ };
30
+ }
31
+ return {
32
+ content: [{ type: 'text', text: formatResult(data) }],
33
+ };
34
+ }
35
+ catch (error) {
36
+ return {
37
+ content: [{ type: 'text', text: formatError(error) }],
38
+ isError: true,
39
+ };
40
+ }
41
+ });
42
+ };
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare const registerSearchThemes: (server: McpServer) => void;
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import { fetchApi, formatResult, formatError } from '../fetch-helper.js';
3
+ export const registerSearchThemes = (server) => {
4
+ server.tool('search_themes', '테마를 검색합니다. 이름(한국어/영문)으로 필터링하여 일치하는 테마의 점수, 단계 정보를 반환합니다.', {
5
+ query: z
6
+ .string()
7
+ .min(1)
8
+ .describe('Search query (theme name or related stock name, e.g. "AI", "반도체", "삼성전자")'),
9
+ }, async ({ query }) => {
10
+ try {
11
+ const data = await fetchApi('/api/tli/themes', { q: query });
12
+ return {
13
+ content: [{ type: 'text', text: formatResult(data) }],
14
+ };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ content: [{ type: 'text', text: formatError(error) }],
19
+ isError: true,
20
+ };
21
+ }
22
+ });
23
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "stockmatrix-mcp",
3
+ "version": "0.1.0",
4
+ "description": "StockMatrix MCP Server - Korean stock market theme lifecycle analysis for AI agents",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "stockmatrix-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "keywords": [
19
+ "mcp",
20
+ "model-context-protocol",
21
+ "korean-stocks",
22
+ "theme-lifecycle",
23
+ "finance",
24
+ "kospi",
25
+ "kosdaq",
26
+ "ai-agent"
27
+ ],
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/MongLong0214/stock-ai-newsletter.git",
31
+ "directory": "mcp"
32
+ },
33
+ "homepage": "https://stockmatrix.co.kr/developers",
34
+ "bugs": {
35
+ "url": "https://github.com/MongLong0214/stock-ai-newsletter/issues"
36
+ },
37
+ "license": "MIT",
38
+ "author": "StockMatrix <aistockmatrix@gmail.com>",
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
42
+ "dependencies": {
43
+ "@modelcontextprotocol/sdk": "^1.0.0",
44
+ "zod": "^3.23.0"
45
+ },
46
+ "devDependencies": {
47
+ "typescript": "^5.6.0"
48
+ }
49
+ }