burkut-mcp 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -1,14 +1,25 @@
1
- # burkut-mcp 🦅
1
+ <p align="center">
2
+ <img src="../assets/logo.png" alt="Bürküt Logo" width="100" />
3
+ </p>
2
4
 
3
- > **Model Context Protocol (MCP) Server for Turkish Financial Markets (BIST, TEFAS, KAP, IPOs, Macro) powered by Bürküt API.**
5
+ <h1 align="center">Bürküt MCP Server</h1>
4
6
 
5
- `burkut-mcp`, Türkiye finans piyasası verilerini (Borsa İstanbul hisseleri, TEFAS yatırım fonları, KAP bildirimleri, halka arzlar, temettüler ve makroekonomik veriler) doğrudan **Claude Desktop**, **Cursor**, **Windsurf** ve diğer LLM tabanlı yapay zeka ajanlarına bağlayan resmi olmayan/açık kaynak bir MCP sunucusudur.
7
+ <p align="center">
8
+ <b>Claude Desktop, Cursor ve LLM tabanlı yapay zeka ajanları için Türkiye finans piyasası veri köprüsü.</b><br />
9
+ Borsa İstanbul (BIST), TEFAS Yatırım Fonları, KAP Bildirimleri, Halka Arzlar, Temettüler ve Makro Veriler.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/burkut-mcp"><img src="https://img.shields.io/npm/v/burkut-mcp?color=purple&style=flat-square&logo=npm&logoColor=white" alt="npm version" /></a>
14
+ <a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/Protokol-MCP%20Standard%C4%B1-blueviolet?style=flat-square&logo=anthropic&logoColor=white" alt="MCP Protocol" /></a>
15
+ <a href="../LICENSE"><img src="https://img.shields.io/badge/Lisans-MIT-gray.svg?style=flat-square" alt="Lisans" /></a>
16
+ </p>
6
17
 
7
18
  ---
8
19
 
9
- ## ⚡ Hızlı Başlangıç (Quickstart)
20
+ ## Hızlı Başlangıç
10
21
 
11
- Kurulum yapmanıza gerek yoktur, `npx` ile anında çalıştırılabilir:
22
+ Herhangi bir kurulum veya indirme gerektirmez. `npx` ile doğrudan çalıştırılır:
12
23
 
13
24
  ```bash
14
25
  npx -y burkut-mcp
@@ -17,10 +28,10 @@ npx -y burkut-mcp
17
28
  ### 1. Claude Desktop ile Kullanım
18
29
 
19
30
  Claude Desktop yapılandırma dosyanızı açın:
20
- * **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
21
31
  * **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
32
+ * **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
22
33
 
23
- Aşağıdaki yapılandırmayı ekleyin:
34
+ Aşağıdaki tanımı ekleyin:
24
35
 
25
36
  ```json
26
37
  {
@@ -29,54 +40,65 @@ Aşağıdaki yapılandırmayı ekleyin:
29
40
  "command": "npx",
30
41
  "args": ["-y", "burkut-mcp"],
31
42
  "env": {
32
- "BURKUT_API_KEY": "YOUR_API_KEY_HERE"
43
+ "BURKUT_API_KEY": "BURKUT_API_ANAHTARINIZ"
33
44
  }
34
45
  }
35
46
  }
36
47
  }
37
48
  ```
38
49
 
39
- > **Not:** `BURKUT_API_KEY` opsiyoneldir. Anahtar girmeden de temel halka açık modda çalışır. Ancak daha yüksek kota ve kesintisiz erişim için [burkut.com/developers](https://burkut.com/developers) adresinden ücretsiz API Key alabilirsiniz.
50
+ > **Önemli:** `BURKUT_API_KEY` zorunludur. Kotanızı takip etmek ve servisi kullanabilmek için [burkutportfoy.com/developer](https://burkutportfoy.com/developer) adresinden saniyeler içinde **ücretsiz API anahtarınızı** oluşturup buraya ekleyin.
40
51
 
41
52
  ---
42
53
 
43
54
  ### 2. Cursor IDE ile Kullanım
44
55
 
45
- Cursor Ayarları (`Settings`) -> `Features` -> `MCP Servers` -> `Add New MCP Server`:
46
- * **Name:** `burkut`
47
- * **Type:** `command`
48
- * **Command:** `npx -y burkut-mcp`
56
+ 1. **Cursor Settings** &rarr; **Features** &rarr; **MCP Servers** yolunu izleyin.
57
+ 2. **Add New MCP Server** butonuna tıklayın:
58
+ * **Name:** `burkut`
59
+ * **Type:** `command`
60
+ * **Command:** `npx -y burkut-mcp`
61
+ * **Env:** `BURKUT_API_KEY=BURKUT_API_ANAHTARINIZ`
49
62
 
50
63
  ---
51
64
 
52
- ## 🛠️ Desteklenen Araçlar (MCP Tools)
65
+ ## Desteklenen MCP Araçları (Tools)
53
66
 
54
- | Tool | Açıklama |
55
- | :--- | :--- |
56
- | `burkut_search_funds` | TEFAS fonlarını koda, isme veya kategoriye göre filtreler; 1 ay, 3 ay, 6 ay ve 1 yıllık getirilerine göre sıralar. |
57
- | `burkut_get_fund_detail` | Belirli bir fonun (örn: `MAC`, `TI2`, `TCD`) tüm getiri periyotları, risk seviyesi ve güncel fiyat detaylarını çeker. |
58
- | `burkut_get_stock_quote` | BIST hisselerinin (örn: `THYAO`, `ASELS`, `KCHOL`) anlık/güncel fiyat, değişim % ve hacim verilerini getirir. |
59
- | `burkut_get_kap_announcements` | Kamuyu Aydınlatma Platformu'na (KAP) düşen şirket bildirimlerini veya genel piyasa bültenini çeker. |
60
- | `burkut_get_ipo_calendar` | Aktif ve yaklaşan Halka Arz (IPO) takvimini, lot fiyatlarını ve talep toplama tarihlerini listeler. |
61
- | `burkut_get_dividends` | BIST şirketlerinin temettü geçmişi, hisse başı net ödeme ve temettü verimi oranlarını getirir. |
62
- | `burkut_get_macro_indicators` | Türkiye resmi enflasyon oranları (TÜFE/ÜFE), serbest piyasa döviz kurları (USD/TRY, EUR/TRY) ve altın fiyatlarını getirir. |
67
+ | Araç Adı | Parametreler | Açıklama |
68
+ | :--- | :--- | :--- |
69
+ | `burkut_search_funds` | `query`, `fundType`, `sortBy`, `limit` | TEFAS fonlarını filtreler; 1 ay, 3 ay, 6 ay ve 1 yıllık getirilerine göre sıralar. |
70
+ | `burkut_get_fund_detail` | `symbol` (örn: `MAC`, `TI2`) | Belirli bir fonun tüm periyot getirilerini, risk seviyesini ve detaylı künyesini döner. |
71
+ | `burkut_get_stock_quote` | `symbol` (örn: `THYAO`, `ASELS`) | BIST hissesinin 15 dk gecikmeli resmi fiyatını, günlük değişim oranını ve hacmini getirir. |
72
+ | `burkut_list_stocks` | `symbols` (örn: `THYAO,ASELS`) | BIST hisselerini listeler veya virgülle ayrılmış hisseleri toplu çeker. |
73
+ | `burkut_get_forex` | `symbol` (örn: `USD`, `EUR`) | Serbest piyasa ve TCMB döviz kurlarını getirir. |
74
+ | `burkut_get_gold` | `symbol` (örn: `ALTIN`, `CEYREK_ALTIN`) | Gram altın, çeyrek altın ve ons altın piyasa fiyatlarını döner. |
75
+ | `burkut_get_bonds` | - | Devlet tahvilleri ve hazine bonosu getirilerini listeler. |
76
+ | `burkut_get_viop` | - | VİOP vadeli işlem ve opsiyon kontrat fiyatlarını listeler. |
63
77
 
64
78
  ---
65
79
 
66
- ## 💬 Örnek İstemler (Prompt Örnekleri)
80
+ ## Örnek Türkçe İstekler (Promptlar)
81
+
82
+ Claude Desktop veya Cursor'a doğrudan şu soruları sorabilirsiniz:
83
+
84
+ * *"Bana TEFAS'taki hisse senedi yoğun fonlar arasında son 1 yılda en çok kazandıran 5 fonu listele ve yıllık getirilerini göster."*
85
+ * *"MAC ve TI2 fonlarının risk puanlarını ve son 6 aylık performanslarını karşılaştır."*
86
+ * *"Bugün KAP'a düşen önemli şirket bildirimlerini ve yeni iş ilişkilerini özetle."*
87
+ * *"Bu hafta talep toplayacak veya aktif olan halka arzlar hangileri? Dağıtım yöntemleri nedir?"*
88
+ * *"FROTO ve TUPRS şirketlerinin son temettü dağıtım oranlarını karşılaştır."*
89
+ * *"TÜİK tarafından açıklanan son yıllık TÜFE enflasyon oranı ile güncel dolar kurunu getir."*
67
90
 
68
- Claude Desktop veya Cursor Composer'da doğrudan şunları sorabilirsiniz:
91
+ ---
92
+
93
+ ## Ortam Değişkenleri (Environment Variables)
69
94
 
70
- * *"Bana TEFAS'taki hisse senedi fonları arasında son 1 yılda en yüksek getiri sağlayan ilk 5 fonu listele ve yıllık getirilerini göster."*
71
- * *"MAC ve TI2 fonlarının risk seviyelerini ve son 6 aylık performanslarını karşılaştır."*
72
- * *"Bugün KAP'a düşen önemli şirket bildirimlerini özetle."*
73
- * *"Bu hafta talep toplayacak veya aktif olan halka arzlar hangileri? Fiyatları ve tarihleri nedir?"*
74
- * *"FROTO ve TUPRS'ın son temettü dağıtım oranlarını karşılaştır."*
75
- * *"Türkiye'deki son açıklanan yıllık TÜFE enflasyon oranı ile güncel dolar kurunu getir."*
95
+ * `BURKUT_API_KEY`: Geliştirici API Anahtarınız (zorunludur, https://burkutportfoy.com/developer adresinden ücretsiz alınır).
96
+ * `BURKUT_API_BASE_URL`: Hedef API adresi (Varsayılan: `https://api.burkutportfoy.com`).
97
+ * `BURKUT_TIMEOUT_MS`: İstek zaman aşımı süresi milisaniye cinsinden (Varsayılan: `15000`).
76
98
 
77
99
  ---
78
100
 
79
- ## 🔧 Geliştirme (Local Development)
101
+ ## Yerel Geliştirme (Local Development)
80
102
 
81
103
  ```bash
82
104
  git clone https://github.com/sametakan29/burkut-sdks.git
@@ -85,26 +107,20 @@ npm install
85
107
  npm run build
86
108
  ```
87
109
 
88
- Yerel test için:
110
+ Yerel test:
89
111
  ```bash
90
112
  node dist/index.js
91
113
  ```
92
114
 
93
- Ortam Değişkenleri:
94
- * `BURKUT_API_KEY`: Bürküt Developer API anahtarınız (opsiyonel).
95
- * `BURKUT_API_BASE_URL`: Hedef API adresi (Varsayılan: `https://api.burkutportfoy.com`).
96
- * `BURKUT_TIMEOUT_MS`: İstek zaman aşımı süresi (Varsayılan: `15000` ms).
97
-
98
115
  ---
99
116
 
100
- ## 💬 Destek ve İletişim
117
+ ## Destek ve İletişim
101
118
 
102
- Her türlü geri bildirim, özel veri seti talepleri veya hata bildirimleri için:
103
119
  * **E-posta:** [destek@burkutportfoy.com](mailto:destek@burkutportfoy.com)
104
- * **GitHub Issues:** [burkut-sdks/issues](https://github.com/sametakan29/burkut-sdks/issues)
120
+ * **GitHub Issues:** [github.com/sametakan29/burkut-sdks/issues](https://github.com/sametakan29/burkut-sdks/issues)
105
121
 
106
122
  ---
107
123
 
108
- ## 📄 Lisans
124
+ ## Lisans
109
125
 
110
- MIT © [Bürküt](https://burkutportfoy.com)
126
+ Bu proje [MIT Lisansı](../LICENSE) ile korunmaktadır. Telif Hakkı &copy; 2026 Bürküt Finansal Teknolojiler.
package/dist/client.d.ts CHANGED
@@ -8,12 +8,10 @@ export declare class BurkutApiClient {
8
8
  getFundDetail(symbol: string): Promise<any>;
9
9
  getStocks(symbols?: string[]): Promise<any[]>;
10
10
  getStockQuote(symbol: string): Promise<any>;
11
- getKapAnnouncements(symbol?: string, page?: number, size?: number): Promise<any>;
12
- getKapDetail(id: string): Promise<any>;
13
- getIpoList(activeOnly?: boolean): Promise<any[]>;
14
- getIpoDetail(symbol: string): Promise<any>;
15
- getDividends(symbol?: string): Promise<any>;
16
- getInflation(): Promise<any>;
17
11
  getForex(): Promise<any[]>;
12
+ getForexDetail(symbol: string): Promise<any>;
18
13
  getGold(): Promise<any[]>;
14
+ getGoldDetail(symbol: string): Promise<any>;
15
+ getBonds(): Promise<any[]>;
16
+ getViop(): Promise<any[]>;
19
17
  }
package/dist/client.js CHANGED
@@ -14,19 +14,17 @@ export class BurkutApiClient {
14
14
  this.config = config || getConfig();
15
15
  }
16
16
  async request(path, options = {}) {
17
- const { query, usePublicV1 } = options;
18
- let resolvedPath = path;
17
+ const { query } = options;
18
+ // BURKUT_API_KEY zorunludur: Geliştirici veri borusu (/api/public/v1) için şarttır.
19
+ if (!this.config.apiKey || !this.config.apiKey.trim()) {
20
+ throw new Error("Bürküt API Anahtarı eksik! Bürküt MCP sunucusunu kullanabilmek için lütfen https://burkutportfoy.com/developer adresinden ücretsiz bir API anahtarı alın ve ayarlarınıza 'BURKUT_API_KEY' ortam değişkeni olarak ekleyin.");
21
+ }
19
22
  const headers = {
20
23
  'Accept': 'application/json',
21
- 'User-Agent': 'burkut-mcp/1.0.0',
24
+ 'User-Agent': 'burkut-mcp/1.0.2',
25
+ 'X-API-Key': this.config.apiKey.trim(),
22
26
  };
23
- if (this.config.apiKey) {
24
- headers['X-API-Key'] = this.config.apiKey;
25
- if (usePublicV1 && !path.startsWith('/api/public/v1')) {
26
- resolvedPath = `/api/public/v1${path.replace(/^\/api\/v1/, '')}`;
27
- }
28
- }
29
- const url = new URL(`${this.config.baseUrl}${resolvedPath}`);
27
+ const url = new URL(`${this.config.baseUrl}${path}`);
30
28
  if (query) {
31
29
  for (const [key, value] of Object.entries(query)) {
32
30
  if (value !== undefined && value !== null) {
@@ -55,10 +53,10 @@ export class BurkutApiClient {
55
53
  throw new Error(`Enstrüman veya veri bulunamadı (404 Not Found): ${path}`);
56
54
  }
57
55
  if (response.status === 401 || response.status === 403) {
58
- throw new Error(`Yetkilendirme hatası (${response.status}): Geçersiz veya yetkisiz API Key. Lütfen burkutportfoy.com/developer üzerinden anahtarınızı kontrol edin.`);
56
+ throw new Error(`Yetkilendirme hatası (${response.status}): Geçersiz veya iptal edilmiş API Key. Lütfen https://burkutportfoy.com/developer üzerinden anahtarınızı kontrol edin.`);
59
57
  }
60
58
  if (response.status === 429) {
61
- throw new Error(`İstek limiti aşıldı (429 Rate Limit): Lütfen birkaç saniye bekleyin veya daha yüksek kotalı bir plana geçin.`);
59
+ throw new Error(`Kotanız doldu veya dakikalık hız sınırına takıldınız (429 Rate Limit): Lütfen birkaç saniye bekleyin veya https://burkutportfoy.com/developer adresinden planınızı yükseltin.`);
62
60
  }
63
61
  throw new Error(`Bürküt API Hatası (HTTP ${response.status}): ${errorDetail || response.statusText}`);
64
62
  }
@@ -76,75 +74,41 @@ export class BurkutApiClient {
76
74
  }
77
75
  // --- Funds (TEFAS) ---
78
76
  async getFunds() {
79
- if (this.config.apiKey) {
80
- return this.request('/funds', { usePublicV1: true });
81
- }
82
- return this.request('/api/v1/market/funds');
77
+ return this.request('/funds');
83
78
  }
84
79
  async getFundDetail(symbol) {
85
80
  const sym = normalizeSymbol(symbol);
86
- if (this.config.apiKey) {
87
- return this.request(`/funds/${sym}`, { usePublicV1: true });
88
- }
89
- return this.request(`/api/v1/market/funds/${sym}`);
81
+ return this.request(`/funds/${sym}`);
90
82
  }
91
83
  // --- Stocks (BIST) ---
92
84
  async getStocks(symbols) {
93
85
  const query = symbols && symbols.length > 0 ? { symbols: symbols.map(normalizeSymbol).join(',') } : undefined;
94
- if (this.config.apiKey) {
95
- return this.request('/stocks', { query, usePublicV1: true });
96
- }
97
- return this.request('/api/v1/market/stocks', { query });
86
+ return this.request('/stocks', { query });
98
87
  }
99
88
  async getStockQuote(symbol) {
100
89
  const sym = normalizeSymbol(symbol);
101
- if (this.config.apiKey) {
102
- return this.request(`/stocks/${sym}`, { usePublicV1: true });
103
- }
104
- return this.request(`/api/v1/market/stocks/${sym}`);
105
- }
106
- // --- KAP Announcements ---
107
- async getKapAnnouncements(symbol, page = 1, size = 20) {
108
- const sym = symbol ? normalizeSymbol(symbol) : undefined;
109
- if (sym) {
110
- return this.request(`/api/v1/kap/${sym}`, { query: { page, size } });
111
- }
112
- return this.request('/api/v1/kap', { query: { page, size } });
90
+ return this.request(`/stocks/${sym}`);
113
91
  }
114
- async getKapDetail(id) {
115
- return this.request(`/api/v1/kap/detail/${encodeURIComponent(id.trim())}`);
92
+ // --- Forex ---
93
+ async getForex() {
94
+ return this.request('/forex');
116
95
  }
117
- // --- IPO (Halka Arz) ---
118
- async getIpoList(activeOnly = false) {
119
- if (activeOnly) {
120
- return this.request('/api/v1/ipo/active');
121
- }
122
- return this.request('/api/v1/ipo');
96
+ async getForexDetail(symbol) {
97
+ return this.request(`/forex/${normalizeSymbol(symbol)}`);
123
98
  }
124
- async getIpoDetail(symbol) {
125
- return this.request(`/api/v1/ipo/${normalizeSymbol(symbol)}`);
99
+ // --- Gold ---
100
+ async getGold() {
101
+ return this.request('/gold');
126
102
  }
127
- // --- Dividends (Temettü) ---
128
- async getDividends(symbol) {
129
- if (symbol) {
130
- return this.request(`/api/v1/dividends/${normalizeSymbol(symbol)}`);
131
- }
132
- return this.request('/api/v1/dividends');
103
+ async getGoldDetail(symbol) {
104
+ return this.request(`/gold/${normalizeSymbol(symbol)}`);
133
105
  }
134
- // --- Macro: Inflation, Forex, Gold ---
135
- async getInflation() {
136
- return this.request('/api/v1/turkey/inflation');
106
+ // --- Bonds ---
107
+ async getBonds() {
108
+ return this.request('/bonds');
137
109
  }
138
- async getForex() {
139
- if (this.config.apiKey) {
140
- return this.request('/forex', { usePublicV1: true });
141
- }
142
- return this.request('/api/v1/market/forex');
143
- }
144
- async getGold() {
145
- if (this.config.apiKey) {
146
- return this.request('/gold', { usePublicV1: true });
147
- }
148
- return this.request('/api/v1/market/gold');
110
+ // --- VIOP ---
111
+ async getViop() {
112
+ return this.request('/viop');
149
113
  }
150
114
  }
package/dist/config.js CHANGED
@@ -1,9 +1,23 @@
1
+ function getCliArg(flag) {
2
+ if (typeof process === 'undefined' || !Array.isArray(process.argv))
3
+ return undefined;
4
+ const args = process.argv.slice(2);
5
+ for (let i = 0; i < args.length; i++) {
6
+ if (args[i] === flag && i + 1 < args.length) {
7
+ return args[i + 1];
8
+ }
9
+ if (args[i].startsWith(`${flag}=`)) {
10
+ return args[i].slice(flag.length + 1);
11
+ }
12
+ }
13
+ return undefined;
14
+ }
1
15
  export function getConfig() {
2
- const envBaseUrl = process.env.BURKUT_API_BASE_URL;
3
- // Default to production API if not specified
4
- const baseUrl = (envBaseUrl || 'https://api.burkutportfoy.com').replace(/\/+$/, '');
5
- const apiKey = process.env.BURKUT_API_KEY || undefined;
6
- const timeoutMs = parseInt(process.env.BURKUT_TIMEOUT_MS || '15000', 10);
16
+ const envBaseUrl = process.env.BURKUT_API_BASE_URL || getCliArg('--base-url');
17
+ // Varsayılan olarak doğrudan geliştirici veri borusuna (/api/public/v1) bağlanır
18
+ const baseUrl = (envBaseUrl || 'https://api.burkutportfoy.com/api/public/v1').replace(/\/+$/, '');
19
+ const apiKey = (process.env.BURKUT_API_KEY || getCliArg('--api-key') || getCliArg('-k') || '').trim() || undefined;
20
+ const timeoutMs = parseInt(process.env.BURKUT_TIMEOUT_MS || getCliArg('--timeout') || '15000', 10);
7
21
  return {
8
22
  baseUrl,
9
23
  apiKey,
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ListPromptsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { BurkutApiClient } from './client.js';
6
6
  import { TOOLS } from './tools.js';
7
7
  import { getConfig } from './config.js';
@@ -10,10 +10,12 @@ async function main() {
10
10
  const client = new BurkutApiClient(config);
11
11
  const server = new Server({
12
12
  name: 'burkut-mcp',
13
- version: '1.0.0',
13
+ version: '1.0.2',
14
14
  }, {
15
15
  capabilities: {
16
16
  tools: {},
17
+ resources: {},
18
+ prompts: {},
17
19
  },
18
20
  });
19
21
  // Register tools list
@@ -26,6 +28,9 @@ async function main() {
26
28
  })),
27
29
  };
28
30
  });
31
+ // Clean empty handlers for optional protocol capabilities
32
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: [] }));
33
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: [] }));
29
34
  // Handle tool calls
30
35
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
31
36
  const { name, arguments: args } = request.params;
@@ -72,7 +77,7 @@ async function main() {
72
77
  console.error(`[burkut-mcp] API Key configured: ${config.apiKey.slice(0, 6)}...`);
73
78
  }
74
79
  else {
75
- console.error(`[burkut-mcp] Running in public mode (No BURKUT_API_KEY provided)`);
80
+ console.error(`[burkut-mcp] WARNING: No BURKUT_API_KEY configured. Tool calls will require an API key from https://burkutportfoy.com/developer`);
76
81
  }
77
82
  }
78
83
  main().catch((err) => {
package/dist/tools.js CHANGED
@@ -1,41 +1,49 @@
1
+ function unwrap(res) {
2
+ if (res && typeof res === 'object' && 'data' in res) {
3
+ return res.data;
4
+ }
5
+ return res;
6
+ }
1
7
  export const TOOLS = [
2
8
  {
3
9
  name: 'burkut_search_funds',
4
- description: 'Search and filter Turkish TEFAS mutual funds (Yatırım Fonları) by code, name, category, or top performance yields (1 ay, 3 ay, 6 ay, 1 yıl).',
10
+ description: 'TEFAS yatırım fonlarını ara, filtrele ve getirilerine (1 ay, 3 ay, 6 ay, 1 yıl) göre sırala.',
5
11
  inputSchema: {
6
12
  type: 'object',
7
13
  properties: {
8
14
  query: {
9
15
  type: 'string',
10
- description: 'Search keyword matching fund code (e.g. "TI2", "MAC") or name (e.g. "Hisse", "Teknoloji", "Gümüş", "Eurobond").',
16
+ description: 'Fon kodu (örn: "TI2", "MAC") veya isim anahtar kelimesi (örn: "Hisse", "Teknoloji", "Gümüş", "Eurobond").',
11
17
  },
12
18
  fundType: {
13
19
  type: 'string',
14
- description: 'Filter by fund type, e.g. "Hisse Senedi Fonu", "Para Piyasası Fonu", "Değişken Fon", "Kıymetli Madenler Fonu", "Borçlanma Araçları Fonu".',
20
+ description: 'Fon türü filtresi (örn: "Hisse Senedi Fonu", "Para Piyasası Fonu", "Değişken Fon", "Kıymetli Madenler Fonu").',
15
21
  },
16
22
  sortBy: {
17
23
  type: 'string',
18
24
  enum: ['yield1y', 'yield6m', 'yield3m', 'yield1m', 'dailyChangePct'],
19
- description: 'Sort field (highest to lowest). Default is "yield1y".',
25
+ description: 'Sıralama ölçütü (büyükten küçüğe). Varsayılan: "yield1y".',
20
26
  },
21
27
  limit: {
22
28
  type: 'number',
23
- description: 'Maximum number of funds to return (default: 15, max: 50).',
29
+ description: 'Döndürülecek maksimum fon sayısı (varsayılan: 15, maksimum: 50).',
24
30
  },
25
31
  },
26
32
  },
27
33
  handler: async (client, args) => {
28
34
  const raw = await client.getFunds();
29
35
  let list = [];
30
- if (Array.isArray(raw)) {
31
- list = raw;
36
+ const payload = unwrap(raw);
37
+ if (Array.isArray(payload)) {
38
+ list = payload;
32
39
  }
33
- else if (raw && Array.isArray(raw.items)) {
34
- list = raw.items;
40
+ else if (payload && Array.isArray(payload.items)) {
41
+ list = payload.items;
35
42
  }
36
43
  if (args.query) {
37
44
  const q = String(args.query).toLowerCase().trim();
38
45
  list = list.filter((f) => (f.symbol && f.symbol.toLowerCase().includes(q)) ||
46
+ (f.code && f.code.toLowerCase().includes(q)) ||
39
47
  (f.name && f.name.toLowerCase().includes(q)) ||
40
48
  (f.fundType && f.fundType.toLowerCase().includes(q)));
41
49
  }
@@ -51,11 +59,11 @@ export const TOOLS = [
51
59
  });
52
60
  const limit = Math.min(Math.max(Number(args.limit) || 15, 1), 50);
53
61
  const results = list.slice(0, limit).map((f) => ({
54
- kod: f.symbol,
62
+ kod: f.symbol || f.code,
55
63
  isim: f.name,
56
64
  tur: f.fundType || f.type,
57
- fiyat: f.currentPrice,
58
- gunlukDegisimPct: f.dailyChangePct,
65
+ fiyat: f.currentPrice ?? f.price,
66
+ gunlukDegisimPct: f.dailyChangePct ?? f.dailyChangePercent,
59
67
  getiri1Ay: f.yield1m != null ? `%${f.yield1m}` : 'N/A',
60
68
  getiri3Ay: f.yield3m != null ? `%${f.yield3m}` : 'N/A',
61
69
  getiri6Ay: f.yield6m != null ? `%${f.yield6m}` : 'N/A',
@@ -71,137 +79,124 @@ export const TOOLS = [
71
79
  },
72
80
  {
73
81
  name: 'burkut_get_fund_detail',
74
- description: 'Get in-depth metrics and multi-period returns for a specific Turkish TEFAS fund (e.g. MAC, TI2, TCD, GLDTR).',
82
+ description: 'Belirli bir TEFAS fonunun (örn: MAC, TI2, TCD) çoklu periyot getirilerini, risk seviyesini ve detaylı künyesini getirir.',
75
83
  inputSchema: {
76
84
  type: 'object',
77
85
  properties: {
78
86
  symbol: {
79
87
  type: 'string',
80
- description: 'The 3-5 character TEFAS fund code, e.g. "MAC", "TI2", "TCD", "AFT".',
88
+ description: 'TEFAS fon kodu (örn: "MAC", "TI2", "TCD", "AFT").',
81
89
  },
82
90
  },
83
91
  required: ['symbol'],
84
92
  },
85
93
  handler: async (client, args) => {
86
94
  const fund = await client.getFundDetail(args.symbol);
87
- return JSON.stringify(fund, null, 2);
95
+ return JSON.stringify(unwrap(fund), null, 2);
88
96
  },
89
97
  },
90
98
  {
91
99
  name: 'burkut_get_stock_quote',
92
- description: 'Get current price, percentage change, and volume for a Borsa Istanbul (BIST) equity (15-min delayed official feed).',
100
+ description: 'Borsa İstanbul (BIST) hisse senedinin 15 dk gecikmeli resmi fiyatını, günlük değişim oranını ve hacmini getirir.',
93
101
  inputSchema: {
94
102
  type: 'object',
95
103
  properties: {
96
104
  symbol: {
97
105
  type: 'string',
98
- description: 'Stock symbol without exchange prefix, e.g. "THYAO", "ASELS", "KCHOL", "GARAN".',
106
+ description: 'Hisse sembolü (örn: "THYAO", "ASELS", "KCHOL", "GARAN").',
99
107
  },
100
108
  },
101
109
  required: ['symbol'],
102
110
  },
103
111
  handler: async (client, args) => {
104
112
  const quote = await client.getStockQuote(args.symbol);
105
- return JSON.stringify(quote, null, 2);
113
+ return JSON.stringify(unwrap(quote), null, 2);
106
114
  },
107
115
  },
108
116
  {
109
- name: 'burkut_get_kap_announcements',
110
- description: 'Fetch latest Kamuyu Aydınlatma Platformu (KAP) company disclosures, material events, financial balance sheets, and corporate announcements.',
117
+ name: 'burkut_list_stocks',
118
+ description: 'Borsa İstanbul (BIST) hisselerini listeler veya virgülle ayrılmış sembol listesinin verilerini toplu çeker.',
111
119
  inputSchema: {
112
120
  type: 'object',
113
121
  properties: {
114
- symbol: {
122
+ symbols: {
115
123
  type: 'string',
116
- description: 'Optional stock symbol to filter disclosures for a specific firm (e.g. "THYAO"). If omitted, market-wide disclosures are returned.',
117
- },
118
- limit: {
119
- type: 'number',
120
- description: 'Number of notifications to retrieve (default: 10, max: 30).',
124
+ description: 'Virgülle ayrılmış hisse sembolleri (örn: "THYAO,ASELS,EREGL"). Belirtilmezse popüler hisseleri döner.',
121
125
  },
122
126
  },
123
127
  },
124
128
  handler: async (client, args) => {
125
- const limit = Math.min(Math.max(Number(args.limit) || 10, 1), 30);
126
- const data = await client.getKapAnnouncements(args.symbol, 1, limit);
127
- return JSON.stringify(data, null, 2);
129
+ const symList = args.symbols
130
+ ? String(args.symbols).split(',').map((s) => s.trim()).filter(Boolean)
131
+ : undefined;
132
+ const stocks = await client.getStocks(symList);
133
+ return JSON.stringify(unwrap(stocks), null, 2);
128
134
  },
129
135
  },
130
136
  {
131
- name: 'burkut_get_ipo_calendar',
132
- description: 'Get the Turkish public offering (Halka Arz) calendar, including active/upcoming IPOs, offering price, dates, and subscription status.',
137
+ name: 'burkut_get_forex',
138
+ description: 'Serbest piyasa ve TCMB döviz kurlarını (USD/TRY, EUR/TRY, GBP/TRY vb.) getirir.',
133
139
  inputSchema: {
134
140
  type: 'object',
135
141
  properties: {
136
- activeOnly: {
137
- type: 'boolean',
138
- description: 'If true, only returns active and upcoming IPOs. If false, returns recent IPO history too.',
142
+ symbol: {
143
+ type: 'string',
144
+ description: 'Belirli bir para birimi kodu (örn: "USD", "EUR"). Belirtilmezse tüm döviz kurlarını döner.',
139
145
  },
140
146
  },
141
147
  },
142
148
  handler: async (client, args) => {
143
- const data = await client.getIpoList(Boolean(args.activeOnly));
144
- return JSON.stringify(data, null, 2);
149
+ if (args.symbol) {
150
+ const item = await client.getForexDetail(args.symbol);
151
+ return JSON.stringify(unwrap(item), null, 2);
152
+ }
153
+ const data = await client.getForex();
154
+ return JSON.stringify(unwrap(data), null, 2);
145
155
  },
146
156
  },
147
157
  {
148
- name: 'burkut_get_dividends',
149
- description: 'Fetch dividend distribution history, dividend yield %, payout dates, and net payment per share for BIST companies.',
158
+ name: 'burkut_get_gold',
159
+ description: 'Gram Altın, Çeyrek Altın, Yarım Altın, Tam Altın ve Ons fiyatlarını getirir.',
150
160
  inputSchema: {
151
161
  type: 'object',
152
162
  properties: {
153
163
  symbol: {
154
164
  type: 'string',
155
- description: 'Optional BIST stock symbol, e.g. "FROTO", "TUPRS", "EREGL". If omitted, upcoming market dividends are returned.',
165
+ description: 'Belirli bir altın türü (örn: "ALTIN", "CEYREK_ALTIN"). Belirtilmezse tüm değerli madenleri döner.',
156
166
  },
157
167
  },
158
168
  },
159
169
  handler: async (client, args) => {
160
- const data = await client.getDividends(args.symbol);
161
- return JSON.stringify(data, null, 2);
170
+ if (args.symbol) {
171
+ const item = await client.getGoldDetail(args.symbol);
172
+ return JSON.stringify(unwrap(item), null, 2);
173
+ }
174
+ const data = await client.getGold();
175
+ return JSON.stringify(unwrap(data), null, 2);
162
176
  },
163
177
  },
164
178
  {
165
- name: 'burkut_get_macro_indicators',
166
- description: 'Fetch Turkish macroeconomic indicators: official inflation rates (TÜFE / ÜFE monthly & annual), foreign exchange rates (USD/TRY, EUR/TRY), and precious metals (Gram Altın, Çeyrek Altın, Ons).',
179
+ name: 'burkut_get_bonds',
180
+ description: 'Devlet tahvilleri ve hazine bonoları faiz getirilerini listeler.',
167
181
  inputSchema: {
168
182
  type: 'object',
169
- properties: {
170
- category: {
171
- type: 'string',
172
- enum: ['all', 'inflation', 'forex', 'gold'],
173
- description: 'Category to fetch: "inflation" for CPI/PPI, "forex" for FX rates, "gold" for precious metals, or "all" (default).',
174
- },
175
- },
183
+ properties: {},
176
184
  },
177
- handler: async (client, args) => {
178
- const category = args.category || 'all';
179
- const results = {};
180
- if (category === 'all' || category === 'inflation') {
181
- try {
182
- results.inflation = await client.getInflation();
183
- }
184
- catch (e) {
185
- results.inflation = { error: e.message };
186
- }
187
- }
188
- if (category === 'all' || category === 'forex') {
189
- try {
190
- results.forex = await client.getForex();
191
- }
192
- catch (e) {
193
- results.forex = { error: e.message };
194
- }
195
- }
196
- if (category === 'all' || category === 'gold') {
197
- try {
198
- results.gold = await client.getGold();
199
- }
200
- catch (e) {
201
- results.gold = { error: e.message };
202
- }
203
- }
204
- return JSON.stringify(results, null, 2);
185
+ handler: async (client) => {
186
+ const data = await client.getBonds();
187
+ return JSON.stringify(unwrap(data), null, 2);
188
+ },
189
+ },
190
+ {
191
+ name: 'burkut_get_viop',
192
+ description: 'VİOP (Vadeli İşlem ve Opsiyon Piyasası) kontratlarını ve güncel uzlaşma fiyatlarını listeler.',
193
+ inputSchema: {
194
+ type: 'object',
195
+ properties: {},
196
+ },
197
+ handler: async (client) => {
198
+ const data = await client.getViop();
199
+ return JSON.stringify(unwrap(data), null, 2);
205
200
  },
206
201
  },
207
202
  ];
package/package.json CHANGED
@@ -1,12 +1,10 @@
1
1
  {
2
2
  "name": "burkut-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Model Context Protocol (MCP) server for Turkish Financial Markets (BIST, TEFAS, KAP, IPOs, Macro) powered by Bürküt API.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
- "bin": {
8
- "burkut-mcp": "./dist/index.js"
9
- },
7
+ "bin": "./dist/index.js",
10
8
  "files": [
11
9
  "dist"
12
10
  ],