@moonbanking/mcp-server 0.5.7 → 0.5.10

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.
@@ -135,3 +135,122 @@ jobs:
135
135
  echo "Skipping publish step." >> $GITHUB_STEP_SUMMARY
136
136
  echo "" >> $GITHUB_STEP_SUMMARY
137
137
  echo "**npm URL:** https://www.npmjs.com/package/@moonbanking/mcp-server" >> $GITHUB_STEP_SUMMARY
138
+
139
+ - name: Set publish status
140
+ id: publish_status
141
+ run: |
142
+ if [ "${{ steps.check_version.outputs.exists }}" == "false" ] && ([ "${{ github.event_name }}" == "push" ] || [ "${{ github.event.inputs.dry_run }}" == "false" ]); then
143
+ echo "published=true" >> $GITHUB_OUTPUT
144
+ else
145
+ echo "published=false" >> $GITHUB_OUTPUT
146
+ fi
147
+
148
+ outputs:
149
+ published: ${{ steps.publish_status.outputs.published }}
150
+ version: ${{ steps.package_version.outputs.version }}
151
+
152
+ sync-docs:
153
+ name: Sync Documentation
154
+ needs: publish
155
+ if: needs.publish.outputs.published == 'true'
156
+ runs-on: ubuntu-latest
157
+ permissions:
158
+ contents: write
159
+ steps:
160
+ - name: Checkout mcp-server repo
161
+ uses: actions/checkout@v4
162
+ with:
163
+ path: mcp-server
164
+
165
+ - name: Checkout moonbanking repo
166
+ uses: actions/checkout@v4
167
+ with:
168
+ repository: getfullup/moonbanking
169
+ token: ${{ secrets.SYNC_DOCS_TOKEN }}
170
+ path: moonbanking
171
+
172
+ - name: Update documentation
173
+ run: |
174
+ # Create the target directory if it doesn't exist
175
+ mkdir -p moonbanking/apps/docs/app/mcp
176
+
177
+ # Create the new content with prepended metadata
178
+ cat > moonbanking/apps/docs/app/mcp/page.mdx << 'EOF'
179
+ {/*
180
+ DO NOT EDIT THIS FILE DIRECTLY!
181
+
182
+ It is automatically generated by the npm-publish GitHub Action in
183
+ the moonbanking/mcp-server repository.
184
+ */}
185
+
186
+ export const metadata = {
187
+ title: `MCP`,
188
+ description: `Create AI agents using Moon Banking's MCP server. Get high-quality data about banks worldwide from your favorite LLM platform with Moon Banking's MCP.`,
189
+ };
190
+
191
+ <ApiKeyNote featureName="MCP" />
192
+
193
+ EOF
194
+
195
+ # Append the README content
196
+ cat mcp-server/README.md >> moonbanking/apps/docs/app/mcp/page.mdx
197
+
198
+ echo "✅ Documentation updated"
199
+
200
+ - name: Check for changes
201
+ id: check_changes
202
+ run: |
203
+ cd moonbanking
204
+ if git diff --quiet apps/docs/app/mcp/page.mdx; then
205
+ echo "has_changes=false" >> $GITHUB_OUTPUT
206
+ echo "ℹ️ No changes detected in documentation"
207
+ else
208
+ echo "has_changes=true" >> $GITHUB_OUTPUT
209
+ echo "✅ Changes detected in documentation"
210
+ fi
211
+
212
+ - name: Create Pull Request
213
+ if: steps.check_changes.outputs.has_changes == 'true'
214
+ uses: peter-evans/create-pull-request@v6
215
+ with:
216
+ token: ${{ secrets.SYNC_DOCS_TOKEN }}
217
+ path: moonbanking
218
+ commit-message: 'docs: sync MCP documentation from mcp-server v${{ needs.publish.outputs.version }}'
219
+ branch: sync-mcp-docs-v${{ needs.publish.outputs.version }}
220
+ delete-branch: true
221
+ title: 'docs: sync MCP documentation v${{ needs.publish.outputs.version }}'
222
+ body: |
223
+ ## 🔄 Automated Documentation Sync
224
+
225
+ This PR automatically syncs the MCP server documentation from the [mcp-server repository](https://github.com/moonbanking/mcp-server).
226
+
227
+ **Version:** v${{ needs.publish.outputs.version }}
228
+ **Source:** README.md from mcp-server
229
+ **Target:** apps/docs/app/mcp/page.mdx
230
+
231
+ ### Changes
232
+ - Updated MCP documentation with latest content from mcp-server v${{ needs.publish.outputs.version }}
233
+
234
+ ---
235
+ *This PR was automatically created by the npm-publish GitHub Action*
236
+ labels: |
237
+ documentation
238
+ automated
239
+
240
+ - name: Summary
241
+ run: |
242
+ if [ "${{ steps.check_changes.outputs.has_changes }}" == "true" ]; then
243
+ echo "## 📚 Documentation Sync Complete!" >> $GITHUB_STEP_SUMMARY
244
+ echo "" >> $GITHUB_STEP_SUMMARY
245
+ echo "Created pull request to sync MCP documentation to getfullup/moonbanking repository." >> $GITHUB_STEP_SUMMARY
246
+ echo "" >> $GITHUB_STEP_SUMMARY
247
+ echo "**Version:** v${{ needs.publish.outputs.version }}" >> $GITHUB_STEP_SUMMARY
248
+ echo "**Target File:** apps/docs/app/mcp/page.mdx" >> $GITHUB_STEP_SUMMARY
249
+ else
250
+ echo "## ℹ️ No Documentation Changes" >> $GITHUB_STEP_SUMMARY
251
+ echo "" >> $GITHUB_STEP_SUMMARY
252
+ echo "Documentation is already up to date. No pull request created." >> $GITHUB_STEP_SUMMARY
253
+ echo "" >> $GITHUB_STEP_SUMMARY
254
+ echo "**Version:** v${{ needs.publish.outputs.version }}" >> $GITHUB_STEP_SUMMARY
255
+ echo "**Target File:** apps/docs/app/mcp/page.mdx" >> $GITHUB_STEP_SUMMARY
256
+ fi
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Moon Banking
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 CHANGED
@@ -1,59 +1,56 @@
1
- # @moonbanking/mcp-server
1
+ # Moon Banking MCP Server
2
2
 
3
- # Welcome to the Moon Banking API!
4
-
5
- Enjoy the documentation and happy coding. Share this spec with your LLM of choice to speed up your development, or take a look at our MCP server and various SDKs.
6
-
7
- ### More information
8
-
9
- For more information about the Moon Banking API, please visit the [Moon Banking Documentation](https://docs.moonbanking.com).
10
-
11
- This MCP server provides tools to interact with the Moon Banking API API based on OpenAPI specification version 2025-07-11.
3
+ The Moon Banking MCP server is generated from the [OpenAPI specification](https://github.com/moonbanking/moonbanking-openapi).
12
4
 
13
5
  ## Installation
14
6
 
15
- ```bash
16
- npm install @moonbanking/mcp-server
17
- ```
7
+ ### Direct invocation
18
8
 
19
- Or use with npx:
9
+ You can run the MCP Server directly via `npx`:
20
10
 
21
- ```bash
22
- npx @moonbanking/mcp-server
11
+ ```sh
12
+ export MOON_BANKING_API_KEY="Bearer mb_sk_..."
13
+ npx -y @moonbanking/mcp-server
23
14
  ```
24
15
 
25
- ## Configuration
26
-
27
- ### Required Environment Variables
28
-
29
- - `MOON_BANKING_API_KEY`: Your API key for authentication
30
-
31
- ### Optional Environment Variables
16
+ ### Via MCP Client
32
17
 
33
- - `MOON_BANKING_INTERNAL_BASE_URL`: Custom base URL (defaults to https://api.moonbanking.com/v1)
18
+ There is a partial list of existing clients at [modelcontextprotocol.io](https://modelcontextprotocol.io/clients). If you already
19
+ have a client, consult their documentation to install the MCP server.
34
20
 
35
- ## Usage
36
-
37
- ### With MCP Client
38
-
39
- Add to your MCP client configuration:
21
+ For clients with a configuration JSON, it might look something like this:
40
22
 
41
23
  ```json
42
24
  {
43
25
  "mcpServers": {
44
- "mcp-server": {
26
+ "moonbanking-mcp": {
45
27
  "command": "npx",
46
28
  "args": ["-y", "@moonbanking/mcp-server"],
47
29
  "env": {
48
- "MOON_BANKING_API_KEY": "your-api-key-here",
49
- "MOON_BANKING_INTERNAL_BASE_URL": "https://api.moonbanking.com/v1"
30
+ "MOON_BANKING_API_KEY": "Bearer mb_sk_..."
50
31
  }
51
32
  }
52
33
  }
53
34
  }
54
35
  ```
55
36
 
56
- ### Filter Specific Tools
37
+ ### Cursor
38
+
39
+ If you use Cursor, you can install the MCP server by using the button below. You will need to set your environment variables
40
+ in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > New MCP Server.
41
+
42
+ [![Add to Cursor](https://cursor.com/en-US/install-mcp?name=moonbanking-mcp&config=eyJlbnYiOnsiTU9PTl9CQU5LSU5HX0FQSV9LRVkiOiJTZXQgeW91ciBNT09OX0JBTktJTkdfQVBJX0tFWSBoZXJlLiJ9LCJjb21tYW5kIjoibnB4IC15IEBtb29uYmFua2luZy9tY3Atc2VydmVyIn0%3D)
43
+
44
+ ### Claude Code
45
+
46
+ If you use Claude Code, you can install the MCP server by running the command below in your terminal. You will need to set your
47
+ environment variables in Claude Code's `claude.json`, which can be found in your home directory.
48
+
49
+ ```
50
+ claude mcp add --transport stdio moonbanking_api --env MOON_BANKING_API_KEY="Your MOON_BANKING_API_KEY here." -- npx -y @moonbanking/mcp-server
51
+ ```
52
+
53
+ ## Filter Specific Tools
57
54
 
58
55
  You can limit which tools are exposed by using the `--tool` flag:
59
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moonbanking/mcp-server",
3
- "version": "0.5.7",
3
+ "version": "0.5.10",
4
4
  "description": "# Welcome to the Moon Banking API!\n\nEnjoy the documentation and happy coding. Share this spec with your LLM of choice to speed up your development, or take a look at our MCP server and various SDKs.\n\n### More information\n\nFor more information about the Moon Banking API, please visit the [Moon Banking Documentation](https://docs.moonbanking.com).",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/index.ts DELETED
@@ -1,778 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
- import {
6
- CallToolRequestSchema,
7
- ListToolsRequestSchema,
8
- } from '@modelcontextprotocol/sdk/types.js';
9
- import fetch from 'node-fetch';
10
-
11
- // Configuration
12
- const DEFAULT_BASE_URL = 'https://api.moonbanking.com/v1';
13
- const BASE_URL = process.env.MOON_BANKING_INTERNAL_BASE_URL || DEFAULT_BASE_URL;
14
- const API_KEY = process.env.MOON_BANKING_API_KEY;
15
-
16
- if (!API_KEY) {
17
- console.error('Error: MOON_BANKING_API_KEY environment variable is required');
18
- process.exit(1);
19
- }
20
-
21
- // API client helper
22
- const apiCall = async (
23
- method: string,
24
- path: string,
25
- options: {
26
- params?: Record<string, unknown>;
27
- body?: unknown;
28
- } = {},
29
- ): Promise<unknown> => {
30
- try {
31
- // Build URL with query parameters
32
- const url = new URL(`${BASE_URL}${path}`);
33
- if (options.params) {
34
- Object.entries(options.params).forEach(([key, value]) => {
35
- if (value !== undefined && value !== null) {
36
- url.searchParams.append(key, String(value));
37
- }
38
- });
39
- }
40
-
41
- const fetchOptions: Parameters<typeof fetch>[1] = {
42
- method,
43
- headers: {
44
- 'Authorization': `Bearer ${API_KEY}`,
45
- 'Content-Type': 'application/json',
46
- },
47
- };
48
-
49
- if (options.body && method !== 'GET' && method !== 'HEAD') {
50
- fetchOptions.body = JSON.stringify(options.body);
51
- }
52
-
53
- const response = await fetch(url.toString(), fetchOptions);
54
-
55
- if (!response.ok) {
56
- const errorText = await response.text();
57
- throw new Error(`API request failed: ${response.status} ${response.statusText} - ${errorText}`);
58
- }
59
-
60
- const contentType = response.headers.get('content-type');
61
- if (contentType && contentType.includes('application/json')) {
62
- return await response.json();
63
- }
64
-
65
- return await response.text();
66
- } catch (error) {
67
- console.error('API call error:', error);
68
- throw error;
69
- }
70
- };
71
-
72
- // Tool definitions
73
- const tools = [
74
- {
75
- "name": "bank-get",
76
- "description": "This endpoint allows you to retrieve a paginated list of all banks. By default, a maximum of ten banks are shown per page. You can search banks by name, filter by country and description (including null/not_null status or semantic content search using vector embeddings), sort them by various fields, and include related data like scores and country information. When searching description content, results are ordered by semantic similarity.",
77
- "inputSchema": {
78
- "type": "object",
79
- "properties": {
80
- "limit": {
81
- "type": "integer",
82
- "description": "Number of items to return.",
83
- "default": 10
84
- },
85
- "starting_after": {
86
- "type": "string",
87
- "description": "Cursor for forward pagination. Use the id of the last item from the previous page to get the next page."
88
- },
89
- "ending_before": {
90
- "type": "string",
91
- "description": "Cursor for backward pagination. Use the id of the first item from the current page to get the previous page."
92
- },
93
- "search": {
94
- "type": "string",
95
- "description": "Search banks by name."
96
- },
97
- "description": {
98
- "type": "string",
99
- "description": "Filter banks by description. Under the hood, this is a semantic search that uses vector embeddings, so you may get better results if you use general language. Besides a full text search, you can use \"null\" to return banks without descriptions or \"not_null\" to return banks with descriptions."
100
- },
101
- "sortBy": {
102
- "type": "string",
103
- "description": "Field to sort by.",
104
- "enum": [
105
- "name",
106
- "rank",
107
- "countryRank",
108
- "storiesCount",
109
- "countryId",
110
- "overall_score",
111
- "overall_total",
112
- "overall_up",
113
- "overall_down",
114
- "cryptoFriendly_score",
115
- "cryptoFriendly_total",
116
- "cryptoFriendly_up",
117
- "cryptoFriendly_down",
118
- "customerService_score",
119
- "customerService_total",
120
- "customerService_up",
121
- "customerService_down",
122
- "feesPricing_score",
123
- "feesPricing_total",
124
- "feesPricing_up",
125
- "feesPricing_down",
126
- "digitalExperience_score",
127
- "digitalExperience_total",
128
- "digitalExperience_up",
129
- "digitalExperience_down",
130
- "securityTrust_score",
131
- "securityTrust_total",
132
- "securityTrust_up",
133
- "securityTrust_down",
134
- "accountFeatures_score",
135
- "accountFeatures_total",
136
- "accountFeatures_up",
137
- "accountFeatures_down",
138
- "branchAtmAccess_score",
139
- "branchAtmAccess_total",
140
- "branchAtmAccess_up",
141
- "branchAtmAccess_down",
142
- "internationalBanking_score",
143
- "internationalBanking_total",
144
- "internationalBanking_up",
145
- "internationalBanking_down",
146
- "businessBanking_score",
147
- "businessBanking_total",
148
- "businessBanking_up",
149
- "businessBanking_down",
150
- "processingSpeed_score",
151
- "processingSpeed_total",
152
- "processingSpeed_up",
153
- "processingSpeed_down",
154
- "transparency_score",
155
- "transparency_total",
156
- "transparency_up",
157
- "transparency_down",
158
- "innovation_score",
159
- "innovation_total",
160
- "innovation_up",
161
- "innovation_down",
162
- "investmentServices_score",
163
- "investmentServices_total",
164
- "investmentServices_up",
165
- "investmentServices_down",
166
- "lending_score",
167
- "lending_total",
168
- "lending_up",
169
- "lending_down"
170
- ],
171
- "default": "name"
172
- },
173
- "sortOrder": {
174
- "type": "string",
175
- "description": "Sort order. Either ascending or descending.",
176
- "enum": [
177
- "asc",
178
- "desc"
179
- ],
180
- "default": "asc"
181
- },
182
- "include": {
183
- "type": "string",
184
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `scores`, `country`, `meta`"
185
- },
186
- "countryId": {
187
- "type": "string",
188
- "description": "Only return banks in the specified country. A country's ID is Moon Banking's unique identifier for the country."
189
- },
190
- "countryCode": {
191
- "type": "string",
192
- "description": "Only return banks in the specified country. A country's code is the ISO 3166-1 code for the country. If both `countryId` and `countryCode` are provided, `countryId` will be used."
193
- }
194
- }
195
- }
196
- },
197
- {
198
- "name": "bank-getById",
199
- "description": "This endpoint allows you to retrieve a specific bank by providing the bank ID. You can include related data like scores and country information in the response.",
200
- "inputSchema": {
201
- "type": "object",
202
- "properties": {
203
- "id": {
204
- "type": "string",
205
- "description": "The bank's auto-generated unique identifier."
206
- },
207
- "include": {
208
- "type": "string",
209
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `scores`, `country`"
210
- }
211
- },
212
- "required": [
213
- "id"
214
- ]
215
- }
216
- },
217
- {
218
- "name": "bankVote-get",
219
- "description": "This endpoint allows you to retrieve a paginated list of bank votes. You can filter by bank ID, category, country, vote type (upvote or downvote), and other parameters.",
220
- "inputSchema": {
221
- "type": "object",
222
- "properties": {
223
- "limit": {
224
- "type": "integer",
225
- "description": "Number of items to return.",
226
- "default": 10
227
- },
228
- "starting_after": {
229
- "type": "string",
230
- "description": "Cursor for forward pagination. Use the id of the last item from the previous page to get the next page."
231
- },
232
- "ending_before": {
233
- "type": "string",
234
- "description": "Cursor for backward pagination. Use the id of the first item from the current page to get the previous page."
235
- },
236
- "bankId": {
237
- "type": "string",
238
- "description": "The bank's auto-generated unique identifier."
239
- },
240
- "categories": {
241
- "type": "string",
242
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `CRYPTO_FRIENDLY`, `CUSTOMER_SERVICE`, `FEES_PRICING`, `DIGITAL_EXPERIENCE`, `SECURITY_TRUST`, `ACCOUNT_FEATURES`, `BRANCH_ATM_ACCESS`, `INTERNATIONAL_BANKING`, `BUSINESS_BANKING`, `PROCESSING_SPEED`, `TRANSPARENCY`, `INNOVATION`, `INVESTMENT_SERVICES`, `LENDING`"
243
- },
244
- "isUp": {
245
- "type": "boolean",
246
- "description": "Whether to filter for upvotes (true) or downvotes (false)."
247
- },
248
- "countryCode": {
249
- "type": "string",
250
- "description": "The country's ISO 3166-1 code (2 characters)."
251
- },
252
- "sortBy": {
253
- "type": "string",
254
- "description": "Field to sort by.",
255
- "enum": [
256
- "createdAt"
257
- ],
258
- "default": "createdAt"
259
- },
260
- "sortOrder": {
261
- "type": "string",
262
- "description": "Sort order. Either ascending or descending.",
263
- "enum": [
264
- "asc",
265
- "desc"
266
- ],
267
- "default": "desc"
268
- },
269
- "include": {
270
- "type": "string",
271
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `bank`, `country`"
272
- }
273
- }
274
- }
275
- },
276
- {
277
- "name": "country-get",
278
- "description": "This endpoint allows you to retrieve a paginated list of all countries. By default, a maximum of ten countries are shown per page. You can search countries by name or 2-letter code, sort them by various fields, and include related data like scores.",
279
- "inputSchema": {
280
- "type": "object",
281
- "properties": {
282
- "limit": {
283
- "type": "integer",
284
- "description": "Number of items to return.",
285
- "default": 10
286
- },
287
- "starting_after": {
288
- "type": "string",
289
- "description": "Cursor for forward pagination. Use the id of the last item from the previous page to get the next page."
290
- },
291
- "ending_before": {
292
- "type": "string",
293
- "description": "Cursor for backward pagination. Use the id of the first item from the current page to get the previous page."
294
- },
295
- "search": {
296
- "type": "string",
297
- "description": "Search countries by name or 2-letter code."
298
- },
299
- "sortBy": {
300
- "type": "string",
301
- "description": "Field to sort by.",
302
- "enum": [
303
- "name",
304
- "code",
305
- "rank",
306
- "banksCount",
307
- "storiesCount",
308
- "overall_score",
309
- "overall_total",
310
- "overall_up",
311
- "overall_down",
312
- "cryptoFriendly_score",
313
- "cryptoFriendly_total",
314
- "cryptoFriendly_up",
315
- "cryptoFriendly_down",
316
- "customerService_score",
317
- "customerService_total",
318
- "customerService_up",
319
- "customerService_down",
320
- "feesPricing_score",
321
- "feesPricing_total",
322
- "feesPricing_up",
323
- "feesPricing_down",
324
- "digitalExperience_score",
325
- "digitalExperience_total",
326
- "digitalExperience_up",
327
- "digitalExperience_down",
328
- "securityTrust_score",
329
- "securityTrust_total",
330
- "securityTrust_up",
331
- "securityTrust_down",
332
- "accountFeatures_score",
333
- "accountFeatures_total",
334
- "accountFeatures_up",
335
- "accountFeatures_down",
336
- "branchAtmAccess_score",
337
- "branchAtmAccess_total",
338
- "branchAtmAccess_up",
339
- "branchAtmAccess_down",
340
- "internationalBanking_score",
341
- "internationalBanking_total",
342
- "internationalBanking_up",
343
- "internationalBanking_down",
344
- "businessBanking_score",
345
- "businessBanking_total",
346
- "businessBanking_up",
347
- "businessBanking_down",
348
- "processingSpeed_score",
349
- "processingSpeed_total",
350
- "processingSpeed_up",
351
- "processingSpeed_down",
352
- "transparency_score",
353
- "transparency_total",
354
- "transparency_up",
355
- "transparency_down",
356
- "innovation_score",
357
- "innovation_total",
358
- "innovation_up",
359
- "innovation_down",
360
- "investmentServices_score",
361
- "investmentServices_total",
362
- "investmentServices_up",
363
- "investmentServices_down",
364
- "lending_score",
365
- "lending_total",
366
- "lending_up",
367
- "lending_down"
368
- ],
369
- "default": "name"
370
- },
371
- "sortOrder": {
372
- "type": "string",
373
- "description": "Sort order. Either ascending or descending.",
374
- "enum": [
375
- "asc",
376
- "desc"
377
- ],
378
- "default": "asc"
379
- },
380
- "include": {
381
- "type": "string",
382
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `scores`"
383
- }
384
- }
385
- }
386
- },
387
- {
388
- "name": "country-getByCountryCode",
389
- "description": "This endpoint allows you to retrieve a specific country by providing the 2-letter ISO country code. You can include related data like scores in the response.",
390
- "inputSchema": {
391
- "type": "object",
392
- "properties": {
393
- "code": {
394
- "type": "string",
395
- "description": "The country's ISO 3166-1 code (2 characters)."
396
- },
397
- "include": {
398
- "type": "string",
399
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `scores`"
400
- }
401
- },
402
- "required": [
403
- "code"
404
- ]
405
- }
406
- },
407
- {
408
- "name": "story-get",
409
- "description": "This endpoint allows you to retrieve a paginated list of all stories. By default, a maximum of ten stories are shown per page. You can search stories by text content, filter by bank ID, sort them by various fields, and include related data like bank and country information.",
410
- "inputSchema": {
411
- "type": "object",
412
- "properties": {
413
- "limit": {
414
- "type": "integer",
415
- "description": "Number of items to return.",
416
- "default": 10
417
- },
418
- "starting_after": {
419
- "type": "string",
420
- "description": "Cursor for forward pagination. Use the id of the last item from the previous page to get the next page."
421
- },
422
- "ending_before": {
423
- "type": "string",
424
- "description": "Cursor for backward pagination. Use the id of the first item from the current page to get the previous page."
425
- },
426
- "search": {
427
- "type": "string",
428
- "description": "Search stories by text content."
429
- },
430
- "sortBy": {
431
- "type": "string",
432
- "description": "Field to sort by.",
433
- "enum": [
434
- "createdAt",
435
- "thumbsUpCount"
436
- ],
437
- "default": "createdAt"
438
- },
439
- "sortOrder": {
440
- "type": "string",
441
- "description": "Sort order. Either ascending or descending.",
442
- "enum": [
443
- "asc",
444
- "desc"
445
- ],
446
- "default": "asc"
447
- },
448
- "include": {
449
- "type": "string",
450
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `bank`, `country`"
451
- },
452
- "countryCode": {
453
- "type": "string",
454
- "description": "The country's ISO 3166-1 code (2 characters)."
455
- },
456
- "bankId": {
457
- "type": "string",
458
- "description": "The bank's auto-generated unique identifier."
459
- },
460
- "tags": {
461
- "type": "string",
462
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `CRYPTO_FRIENDLY`, `CUSTOMER_SERVICE`, `FEES_PRICING`, `DIGITAL_EXPERIENCE`, `SECURITY_TRUST`, `ACCOUNT_FEATURES`, `BRANCH_ATM_ACCESS`, `INTERNATIONAL_BANKING`, `BUSINESS_BANKING`, `PROCESSING_SPEED`, `TRANSPARENCY`, `INNOVATION`, `INVESTMENT_SERVICES`, `LENDING`"
463
- }
464
- }
465
- }
466
- },
467
- {
468
- "name": "story-getById",
469
- "description": "This endpoint allows you to retrieve a specific story by providing the story ID. You can include related data like bank and country information in the response.",
470
- "inputSchema": {
471
- "type": "object",
472
- "properties": {
473
- "id": {
474
- "type": "string",
475
- "description": "The story's auto-generated unique identifier."
476
- },
477
- "include": {
478
- "type": "string",
479
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `bank`, `country`"
480
- }
481
- },
482
- "required": [
483
- "id"
484
- ]
485
- }
486
- },
487
- {
488
- "name": "world-getOverview",
489
- "description": "This endpoint allows you to retrieve global overview data that aggregates banks votes, stories and other data across all banks in all countries. You can include related data like scores in the response.",
490
- "inputSchema": {
491
- "type": "object",
492
- "properties": {
493
- "include": {
494
- "type": "string",
495
- "description": "An optional comma-separated list of fields to include in the response. Possible values: `scores`"
496
- }
497
- }
498
- }
499
- }
500
- ];
501
-
502
- // Parse command line arguments for tool filtering
503
- const args = process.argv.slice(2);
504
- const selectedTools = new Set<string>();
505
-
506
- args.forEach(arg => {
507
- if (arg.startsWith('--tool=')) {
508
- selectedTools.add(arg.substring('--tool='.length));
509
- }
510
- });
511
-
512
- // Filter tools if specific ones were requested
513
- const availableTools = selectedTools.size > 0
514
- ? tools.filter(tool => selectedTools.has(tool.name))
515
- : tools;
516
-
517
- // Create MCP server
518
- const server = new Server(
519
- {
520
- name: 'moon banking api-mcp',
521
- version: '2025-07-11',
522
- },
523
- {
524
- capabilities: {
525
- tools: {},
526
- },
527
- },
528
- );
529
-
530
- // Register tool list handler
531
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
532
- tools: availableTools,
533
- }));
534
-
535
- // Register tool call handler
536
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
537
- const { name, arguments: args = {} } = request.params;
538
-
539
- try {
540
- switch (name) {
541
- case 'bank-get': {
542
- const result = await apiCall(
543
- 'GET',
544
- `/banks`,
545
- {
546
- params: {
547
- limit: args.limit,
548
- starting_after: args.starting_after,
549
- ending_before: args.ending_before,
550
- search: args.search,
551
- description: args.description,
552
- sortBy: args.sortBy,
553
- sortOrder: args.sortOrder,
554
- include: args.include,
555
- countryId: args.countryId,
556
- countryCode: args.countryCode,
557
- },
558
-
559
- },
560
- );
561
-
562
- return {
563
- content: [
564
- {
565
- type: 'text',
566
- text: JSON.stringify(result, null, 2),
567
- },
568
- ],
569
- };
570
- }
571
-
572
- case 'bank-getById': {
573
- const result = await apiCall(
574
- 'GET',
575
- `/banks/${args.id}`,
576
- {
577
- params: {
578
- include: args.include,
579
- },
580
-
581
- },
582
- );
583
-
584
- return {
585
- content: [
586
- {
587
- type: 'text',
588
- text: JSON.stringify(result, null, 2),
589
- },
590
- ],
591
- };
592
- }
593
-
594
- case 'bankVote-get': {
595
- const result = await apiCall(
596
- 'GET',
597
- `/bank-votes`,
598
- {
599
- params: {
600
- limit: args.limit,
601
- starting_after: args.starting_after,
602
- ending_before: args.ending_before,
603
- bankId: args.bankId,
604
- categories: args.categories,
605
- isUp: args.isUp,
606
- countryCode: args.countryCode,
607
- sortBy: args.sortBy,
608
- sortOrder: args.sortOrder,
609
- include: args.include,
610
- },
611
-
612
- },
613
- );
614
-
615
- return {
616
- content: [
617
- {
618
- type: 'text',
619
- text: JSON.stringify(result, null, 2),
620
- },
621
- ],
622
- };
623
- }
624
-
625
- case 'country-get': {
626
- const result = await apiCall(
627
- 'GET',
628
- `/countries`,
629
- {
630
- params: {
631
- limit: args.limit,
632
- starting_after: args.starting_after,
633
- ending_before: args.ending_before,
634
- search: args.search,
635
- sortBy: args.sortBy,
636
- sortOrder: args.sortOrder,
637
- include: args.include,
638
- },
639
-
640
- },
641
- );
642
-
643
- return {
644
- content: [
645
- {
646
- type: 'text',
647
- text: JSON.stringify(result, null, 2),
648
- },
649
- ],
650
- };
651
- }
652
-
653
- case 'country-getByCountryCode': {
654
- const result = await apiCall(
655
- 'GET',
656
- `/countries/${args.code}`,
657
- {
658
- params: {
659
- include: args.include,
660
- },
661
-
662
- },
663
- );
664
-
665
- return {
666
- content: [
667
- {
668
- type: 'text',
669
- text: JSON.stringify(result, null, 2),
670
- },
671
- ],
672
- };
673
- }
674
-
675
- case 'story-get': {
676
- const result = await apiCall(
677
- 'GET',
678
- `/stories`,
679
- {
680
- params: {
681
- limit: args.limit,
682
- starting_after: args.starting_after,
683
- ending_before: args.ending_before,
684
- search: args.search,
685
- sortBy: args.sortBy,
686
- sortOrder: args.sortOrder,
687
- include: args.include,
688
- countryCode: args.countryCode,
689
- bankId: args.bankId,
690
- tags: args.tags,
691
- },
692
-
693
- },
694
- );
695
-
696
- return {
697
- content: [
698
- {
699
- type: 'text',
700
- text: JSON.stringify(result, null, 2),
701
- },
702
- ],
703
- };
704
- }
705
-
706
- case 'story-getById': {
707
- const result = await apiCall(
708
- 'GET',
709
- `/stories/${args.id}`,
710
- {
711
- params: {
712
- include: args.include,
713
- },
714
-
715
- },
716
- );
717
-
718
- return {
719
- content: [
720
- {
721
- type: 'text',
722
- text: JSON.stringify(result, null, 2),
723
- },
724
- ],
725
- };
726
- }
727
-
728
- case 'world-getOverview': {
729
- const result = await apiCall(
730
- 'GET',
731
- `/world`,
732
- {
733
- params: {
734
- include: args.include,
735
- },
736
-
737
- },
738
- );
739
-
740
- return {
741
- content: [
742
- {
743
- type: 'text',
744
- text: JSON.stringify(result, null, 2),
745
- },
746
- ],
747
- };
748
- }
749
- default:
750
- throw new Error(`Unknown tool: ${name}`);
751
- }
752
- } catch (error) {
753
- const errorMessage = error instanceof Error ? error.message : String(error);
754
- return {
755
- content: [
756
- {
757
- type: 'text',
758
- text: `Error: ${errorMessage}`,
759
- },
760
- ],
761
- isError: true,
762
- };
763
- }
764
- });
765
-
766
- // Start server
767
- const main = async (): Promise<void> => {
768
- const transport = new StdioServerTransport();
769
- await server.connect(transport);
770
- console.error('Moon Banking API MCP server running on stdio');
771
- console.error(`Base URL: ${BASE_URL}`);
772
- console.error(`Available tools: ${availableTools.length}`);
773
- };
774
-
775
- main().catch((error) => {
776
- console.error('Server error:', error);
777
- process.exit(1);
778
- });
package/tsconfig.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ES2022",
5
- "lib": [
6
- "ES2022"
7
- ],
8
- "moduleResolution": "node",
9
- "outDir": "./dist",
10
- "rootDir": "./src",
11
- "strict": true,
12
- "esModuleInterop": true,
13
- "skipLibCheck": true,
14
- "forceConsistentCasingInFileNames": true,
15
- "resolveJsonModule": true,
16
- "declaration": true,
17
- "declarationMap": true,
18
- "sourceMap": true
19
- },
20
- "include": [
21
- "src/**/*"
22
- ],
23
- "exclude": [
24
- "node_modules",
25
- "dist"
26
- ]
27
- }