create-mcp-use-app 0.2.1 → 0.3.1
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/dist/index.js +61 -6
- package/dist/templates/ui/package.json +2 -3
- package/package.json +1 -3
- package/dist/templates/api/README.md +0 -224
- package/dist/templates/api/package.json +0 -24
- package/dist/templates/api/src/server.ts +0 -229
- package/dist/templates/api/tsconfig.json +0 -20
- package/dist/templates/basic/README.md +0 -64
- package/dist/templates/basic/package.json +0 -23
- package/dist/templates/basic/src/server.ts +0 -67
- package/dist/templates/basic/tsconfig.json +0 -20
- package/dist/templates/filesystem/README.md +0 -139
- package/dist/templates/filesystem/package.json +0 -23
- package/dist/templates/filesystem/src/server.ts +0 -155
- package/dist/templates/filesystem/tsconfig.json +0 -20
- package/dist/templates/ui/package-lock.json +0 -2870
package/dist/index.js
CHANGED
|
@@ -5,12 +5,23 @@ import { execSync } from "child_process";
|
|
|
5
5
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
6
6
|
import { dirname, join, resolve } from "path";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
|
+
import { createInterface } from "readline";
|
|
8
9
|
import { Command } from "commander";
|
|
9
10
|
var __filename = fileURLToPath(import.meta.url);
|
|
10
11
|
var __dirname = dirname(__filename);
|
|
11
12
|
var program = new Command();
|
|
12
|
-
program.name("create-mcp-use-app").description("Create a new MCP server project").version("0.1.0").argument("
|
|
13
|
+
program.name("create-mcp-use-app").description("Create a new MCP server project").version("0.1.0").argument("[project-name]", "Name of the MCP server project").option("-t, --template <template>", "Template to use", "ui").option("--no-install", "Skip installing dependencies").action(async (projectName, options) => {
|
|
13
14
|
try {
|
|
15
|
+
if (!projectName) {
|
|
16
|
+
console.log("\u{1F3AF} Welcome to create-mcp-use-app!");
|
|
17
|
+
console.log("");
|
|
18
|
+
const promptedName = await promptForProjectName();
|
|
19
|
+
if (!promptedName) {
|
|
20
|
+
console.log("\u274C Project creation cancelled.");
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
projectName = promptedName;
|
|
24
|
+
}
|
|
14
25
|
console.log(`\u{1F680} Creating MCP server "${projectName}"...`);
|
|
15
26
|
const projectPath = resolve(process.cwd(), projectName);
|
|
16
27
|
if (existsSync(projectPath)) {
|
|
@@ -37,11 +48,23 @@ program.name("create-mcp-use-app").description("Create a new MCP server project"
|
|
|
37
48
|
console.log("");
|
|
38
49
|
console.log("\u{1F4C1} Project structure:");
|
|
39
50
|
console.log(` ${projectName}/`);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
if (options.template === "ui") {
|
|
52
|
+
console.log(" \u251C\u2500\u2500 src/");
|
|
53
|
+
console.log(" \u2502 \u2514\u2500\u2500 server.ts");
|
|
54
|
+
console.log(" \u251C\u2500\u2500 resources/");
|
|
55
|
+
console.log(" \u2502 \u251C\u2500\u2500 data-visualization.tsx");
|
|
56
|
+
console.log(" \u2502 \u251C\u2500\u2500 kanban-board.tsx");
|
|
57
|
+
console.log(" \u2502 \u2514\u2500\u2500 todo-list.tsx");
|
|
58
|
+
console.log(" \u251C\u2500\u2500 package.json");
|
|
59
|
+
console.log(" \u251C\u2500\u2500 tsconfig.json");
|
|
60
|
+
console.log(" \u2514\u2500\u2500 README.md");
|
|
61
|
+
} else {
|
|
62
|
+
console.log(" \u251C\u2500\u2500 src/");
|
|
63
|
+
console.log(" \u2502 \u2514\u2500\u2500 server.ts");
|
|
64
|
+
console.log(" \u251C\u2500\u2500 package.json");
|
|
65
|
+
console.log(" \u251C\u2500\u2500 tsconfig.json");
|
|
66
|
+
console.log(" \u2514\u2500\u2500 README.md");
|
|
67
|
+
}
|
|
45
68
|
console.log("");
|
|
46
69
|
console.log("\u{1F680} To get started:");
|
|
47
70
|
console.log(` cd ${projectName}`);
|
|
@@ -61,6 +84,7 @@ async function copyTemplate(projectPath, template) {
|
|
|
61
84
|
if (!existsSync(templatePath)) {
|
|
62
85
|
console.error(`\u274C Template "${template}" not found!`);
|
|
63
86
|
console.log("Available templates: basic, filesystem, api, ui");
|
|
87
|
+
console.log('\u{1F4A1} Tip: Use "ui" template for React components and modern UI features');
|
|
64
88
|
process.exit(1);
|
|
65
89
|
}
|
|
66
90
|
copyDirectory(templatePath, projectPath);
|
|
@@ -85,4 +109,35 @@ function updatePackageJson(projectPath, projectName) {
|
|
|
85
109
|
packageJson.description = `MCP server: ${projectName}`;
|
|
86
110
|
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
87
111
|
}
|
|
112
|
+
function promptForProjectName() {
|
|
113
|
+
return new Promise((resolvePromise) => {
|
|
114
|
+
const rl = createInterface({
|
|
115
|
+
input: process.stdin,
|
|
116
|
+
output: process.stdout
|
|
117
|
+
});
|
|
118
|
+
const askForName = () => {
|
|
119
|
+
rl.question("What is your project name? ", (answer) => {
|
|
120
|
+
const trimmed = answer.trim();
|
|
121
|
+
if (!trimmed) {
|
|
122
|
+
console.log("\u274C Project name is required");
|
|
123
|
+
askForName();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(trimmed)) {
|
|
127
|
+
console.log("\u274C Project name can only contain letters, numbers, hyphens, and underscores");
|
|
128
|
+
askForName();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (existsSync(join(process.cwd(), trimmed))) {
|
|
132
|
+
console.log(`\u274C Directory "${trimmed}" already exists! Please choose a different name.`);
|
|
133
|
+
askForName();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
rl.close();
|
|
137
|
+
resolvePromise(trimmed);
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
askForName();
|
|
141
|
+
});
|
|
142
|
+
}
|
|
88
143
|
program.parse();
|
|
@@ -22,13 +22,12 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@mcp-ui/server": "^5.11.0",
|
|
25
|
-
"@mcp-use/inspector": "workspace:*",
|
|
26
25
|
"cors": "^2.8.5",
|
|
27
26
|
"express": "^4.18.0",
|
|
28
|
-
"mcp-use": "
|
|
27
|
+
"mcp-use": "^0.3.0"
|
|
29
28
|
},
|
|
30
29
|
"devDependencies": {
|
|
31
|
-
"@mcp-use/cli": "
|
|
30
|
+
"@mcp-use/cli": "^2.0.2",
|
|
32
31
|
"@types/cors": "^2.8.0",
|
|
33
32
|
"@types/express": "^4.17.0",
|
|
34
33
|
"@types/node": "^20.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-mcp-use-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Create MCP-Use apps with one command",
|
|
6
6
|
"author": "mcp-use, Inc.",
|
|
@@ -38,13 +38,11 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"commander": "^11.0.0",
|
|
41
|
-
"prompts": "^2.4.2",
|
|
42
41
|
"chalk": "^5.3.0",
|
|
43
42
|
"fs-extra": "^11.2.0"
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
45
|
"@types/node": "^20.0.0",
|
|
47
|
-
"@types/prompts": "^2.4.9",
|
|
48
46
|
"@types/fs-extra": "^11.0.4",
|
|
49
47
|
"typescript": "^5.0.0",
|
|
50
48
|
"vitest": "^1.0.0"
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
# API MCP Server
|
|
2
|
-
|
|
3
|
-
An API MCP server created with `create-mcp-app` that provides HTTP operations and API integrations.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **🌐 HTTP Requests**: GET and POST requests
|
|
8
|
-
- **🌤️ Weather API**: Get weather information
|
|
9
|
-
- **📊 JSON Placeholder**: Test API interactions
|
|
10
|
-
- **📚 Documentation**: Generate API documentation
|
|
11
|
-
|
|
12
|
-
## Getting Started
|
|
13
|
-
|
|
14
|
-
### Development
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
# Install dependencies
|
|
18
|
-
npm install
|
|
19
|
-
|
|
20
|
-
# Run in development mode
|
|
21
|
-
npm run dev
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### Production
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# Build the server
|
|
28
|
-
npm run build
|
|
29
|
-
|
|
30
|
-
# Run the built server
|
|
31
|
-
npm start
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Available Tools
|
|
35
|
-
|
|
36
|
-
### `http-get`
|
|
37
|
-
|
|
38
|
-
Make an HTTP GET request to any URL.
|
|
39
|
-
|
|
40
|
-
**Parameters:**
|
|
41
|
-
|
|
42
|
-
- `url` (string, required): URL to make the GET request to
|
|
43
|
-
- `headers` (object, optional): Optional headers to include
|
|
44
|
-
|
|
45
|
-
**Example:**
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"url": "https://api.github.com/users/octocat",
|
|
50
|
-
"headers": {
|
|
51
|
-
"User-Agent": "MyApp/1.0"
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### `http-post`
|
|
57
|
-
|
|
58
|
-
Make an HTTP POST request to any URL.
|
|
59
|
-
|
|
60
|
-
**Parameters:**
|
|
61
|
-
|
|
62
|
-
- `url` (string, required): URL to make the POST request to
|
|
63
|
-
- `data` (object, required): Data to send in the request body
|
|
64
|
-
- `headers` (object, optional): Optional headers to include
|
|
65
|
-
|
|
66
|
-
**Example:**
|
|
67
|
-
|
|
68
|
-
```json
|
|
69
|
-
{
|
|
70
|
-
"url": "https://httpbin.org/post",
|
|
71
|
-
"data": {
|
|
72
|
-
"message": "Hello World"
|
|
73
|
-
},
|
|
74
|
-
"headers": {
|
|
75
|
-
"Content-Type": "application/json"
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### `weather`
|
|
81
|
-
|
|
82
|
-
Get weather information for a city.
|
|
83
|
-
|
|
84
|
-
**Parameters:**
|
|
85
|
-
|
|
86
|
-
- `city` (string, required): City name to get weather for
|
|
87
|
-
- `apiKey` (string, optional): OpenWeatherMap API key
|
|
88
|
-
|
|
89
|
-
**Example:**
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"city": "London",
|
|
94
|
-
"apiKey": "your-api-key-here"
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**Note:** Get a free API key at [OpenWeatherMap](https://openweathermap.org/api).
|
|
99
|
-
|
|
100
|
-
### `json-placeholder`
|
|
101
|
-
|
|
102
|
-
Interact with JSONPlaceholder API for testing.
|
|
103
|
-
|
|
104
|
-
**Parameters:**
|
|
105
|
-
|
|
106
|
-
- `resource` (string, required): Resource type (posts, users, comments, albums, photos, todos)
|
|
107
|
-
- `id` (string, optional): Specific ID (will list all if not provided)
|
|
108
|
-
|
|
109
|
-
**Example:**
|
|
110
|
-
|
|
111
|
-
```json
|
|
112
|
-
{
|
|
113
|
-
"resource": "posts",
|
|
114
|
-
"id": "1"
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Available Resources
|
|
119
|
-
|
|
120
|
-
### `api://status`
|
|
121
|
-
|
|
122
|
-
Current status and information about the API server.
|
|
123
|
-
|
|
124
|
-
## Available Prompts
|
|
125
|
-
|
|
126
|
-
### `api-docs`
|
|
127
|
-
|
|
128
|
-
Generate API documentation for endpoints.
|
|
129
|
-
|
|
130
|
-
**Parameters:**
|
|
131
|
-
|
|
132
|
-
- `endpoint` (string, required): API endpoint to document
|
|
133
|
-
- `method` (string, optional): HTTP method (default: GET)
|
|
134
|
-
|
|
135
|
-
## API Integrations
|
|
136
|
-
|
|
137
|
-
### Weather API
|
|
138
|
-
|
|
139
|
-
- **Service**: OpenWeatherMap
|
|
140
|
-
- **Free Tier**: 1,000 calls/day
|
|
141
|
-
- **Signup**: [OpenWeatherMap](https://openweathermap.org/api)
|
|
142
|
-
|
|
143
|
-
### JSON Placeholder
|
|
144
|
-
|
|
145
|
-
- **Service**: JSONPlaceholder
|
|
146
|
-
- **Free**: Yes, no API key required
|
|
147
|
-
- **Documentation**: [JSONPlaceholder](https://jsonplaceholder.typicode.com/)
|
|
148
|
-
|
|
149
|
-
## Customization
|
|
150
|
-
|
|
151
|
-
### Adding New API Integrations
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
// Add a new API tool
|
|
155
|
-
mcp.tool({
|
|
156
|
-
name: 'my-api',
|
|
157
|
-
description: 'Call my custom API',
|
|
158
|
-
inputs: [
|
|
159
|
-
{ name: 'endpoint', type: 'string', required: true },
|
|
160
|
-
{ name: 'params', type: 'object', required: false }
|
|
161
|
-
],
|
|
162
|
-
fn: async ({ endpoint, params }) => {
|
|
163
|
-
const response = await axios.get(`https://my-api.com/${endpoint}`, { params })
|
|
164
|
-
return JSON.stringify(response.data, null, 2)
|
|
165
|
-
}
|
|
166
|
-
})
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Adding Authentication
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// Add API key authentication
|
|
173
|
-
const apiKey = process.env.MY_API_KEY
|
|
174
|
-
if (!apiKey) {
|
|
175
|
-
throw new Error('MY_API_KEY environment variable is required')
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Use in requests
|
|
179
|
-
const response = await axios.get(url, {
|
|
180
|
-
headers: { Authorization: `Bearer ${apiKey}` }
|
|
181
|
-
})
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Error Handling
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
// Custom error handling
|
|
188
|
-
mcp.tool({
|
|
189
|
-
name: 'safe-request',
|
|
190
|
-
inputs: [{ name: 'url', type: 'string', required: true }],
|
|
191
|
-
fn: async ({ url }) => {
|
|
192
|
-
try {
|
|
193
|
-
const response = await axios.get(url, { timeout: 5000 })
|
|
194
|
-
return `Success: ${response.status}`
|
|
195
|
-
}
|
|
196
|
-
catch (error) {
|
|
197
|
-
if (axios.isAxiosError(error)) {
|
|
198
|
-
return `HTTP Error: ${error.response?.status} - ${error.message}`
|
|
199
|
-
}
|
|
200
|
-
return `Error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
})
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Environment Variables
|
|
207
|
-
|
|
208
|
-
Create a `.env` file for API keys:
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
# Weather API
|
|
212
|
-
OPENWEATHER_API_KEY=your_openweather_api_key
|
|
213
|
-
|
|
214
|
-
# Custom APIs
|
|
215
|
-
MY_API_KEY=your_custom_api_key
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
## Learn More
|
|
219
|
-
|
|
220
|
-
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
221
|
-
- [mcp-use Documentation](https://docs.mcp-use.io)
|
|
222
|
-
- [Axios Documentation](https://axios-http.com/)
|
|
223
|
-
- [OpenWeatherMap API](https://openweathermap.org/api)
|
|
224
|
-
- [JSONPlaceholder](https://jsonplaceholder.typicode.com/)
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "my-mcp-server",
|
|
3
|
-
"type": "module",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"description": "MCP server: my-mcp-server",
|
|
6
|
-
"author": "",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"keywords": ["mcp", "server", "api", "http", "ai", "tools"],
|
|
9
|
-
"main": "dist/server.js",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
12
|
-
"dev": "tsx src/server.ts",
|
|
13
|
-
"start": "node dist/server.js"
|
|
14
|
-
},
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"axios": "^1.6.0",
|
|
17
|
-
"mcp-use": "latest"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@types/node": "^20.0.0",
|
|
21
|
-
"tsx": "^4.0.0",
|
|
22
|
-
"typescript": "^5.0.0"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import axios from 'axios'
|
|
2
|
-
import { create } from 'mcp-use/server'
|
|
3
|
-
|
|
4
|
-
// Create an API MCP server
|
|
5
|
-
const mcp = create('api-server', {
|
|
6
|
-
version: '1.0.0',
|
|
7
|
-
description: 'An API MCP server for HTTP operations',
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
// Resource for server status
|
|
11
|
-
mcp.resource({
|
|
12
|
-
uri: 'api://status',
|
|
13
|
-
name: 'API Server Status',
|
|
14
|
-
description: 'Current status of the API server',
|
|
15
|
-
mimeType: 'application/json',
|
|
16
|
-
fn: async () => {
|
|
17
|
-
return JSON.stringify({
|
|
18
|
-
name: 'api-server',
|
|
19
|
-
version: '1.0.0',
|
|
20
|
-
status: 'running',
|
|
21
|
-
timestamp: new Date().toISOString(),
|
|
22
|
-
endpoints: ['http-get', 'http-post', 'weather', 'json-placeholder'],
|
|
23
|
-
}, null, 2)
|
|
24
|
-
},
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
// Tool for making HTTP GET requests
|
|
28
|
-
mcp.tool({
|
|
29
|
-
name: 'http-get',
|
|
30
|
-
description: 'Make an HTTP GET request to a URL',
|
|
31
|
-
inputs: [
|
|
32
|
-
{
|
|
33
|
-
name: 'url',
|
|
34
|
-
type: 'string',
|
|
35
|
-
description: 'URL to make the GET request to',
|
|
36
|
-
required: true,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: 'headers',
|
|
40
|
-
type: 'object',
|
|
41
|
-
description: 'Optional headers to include',
|
|
42
|
-
required: false,
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
fn: async ({ url, headers = {} }: { url: string, headers?: Record<string, string> }) => {
|
|
46
|
-
try {
|
|
47
|
-
const response = await axios.get(url, { headers })
|
|
48
|
-
return `GET ${url}\nStatus: ${response.status}\nHeaders: ${JSON.stringify(response.headers, null, 2)}\n\nResponse:\n${JSON.stringify(response.data, null, 2)}`
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
if (axios.isAxiosError(error)) {
|
|
52
|
-
return `Error making GET request to ${url}:\nStatus: ${error.response?.status}\nMessage: ${error.message}`
|
|
53
|
-
}
|
|
54
|
-
return `Error making GET request to ${url}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
// Tool for making HTTP POST requests
|
|
60
|
-
mcp.tool({
|
|
61
|
-
name: 'http-post',
|
|
62
|
-
description: 'Make an HTTP POST request to a URL',
|
|
63
|
-
inputs: [
|
|
64
|
-
{
|
|
65
|
-
name: 'url',
|
|
66
|
-
type: 'string',
|
|
67
|
-
description: 'URL to make the POST request to',
|
|
68
|
-
required: true,
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'data',
|
|
72
|
-
type: 'object',
|
|
73
|
-
description: 'Data to send in the request body',
|
|
74
|
-
required: true,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
name: 'headers',
|
|
78
|
-
type: 'object',
|
|
79
|
-
description: 'Optional headers to include',
|
|
80
|
-
required: false,
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
fn: async ({ url, data, headers = {} }: { url: string, data: any, headers?: Record<string, string> }) => {
|
|
84
|
-
try {
|
|
85
|
-
const response = await axios.post(url, data, { headers })
|
|
86
|
-
return `POST ${url}\nStatus: ${response.status}\nHeaders: ${JSON.stringify(response.headers, null, 2)}\n\nResponse:\n${JSON.stringify(response.data, null, 2)}`
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
if (axios.isAxiosError(error)) {
|
|
90
|
-
return `Error making POST request to ${url}:\nStatus: ${error.response?.status}\nMessage: ${error.message}`
|
|
91
|
-
}
|
|
92
|
-
return `Error making POST request to ${url}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
// Tool for getting weather information (example API integration)
|
|
98
|
-
mcp.tool({
|
|
99
|
-
name: 'weather',
|
|
100
|
-
description: 'Get weather information for a city (using OpenWeatherMap API)',
|
|
101
|
-
inputs: [
|
|
102
|
-
{
|
|
103
|
-
name: 'city',
|
|
104
|
-
type: 'string',
|
|
105
|
-
description: 'City name to get weather for',
|
|
106
|
-
required: true,
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: 'apiKey',
|
|
110
|
-
type: 'string',
|
|
111
|
-
description: 'OpenWeatherMap API key (get one at openweathermap.org)',
|
|
112
|
-
required: false,
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
fn: async ({ city, apiKey }: { city: string, apiKey?: string }) => {
|
|
116
|
-
try {
|
|
117
|
-
// Use a demo API key for demonstration (replace with your own)
|
|
118
|
-
const key = apiKey || 'demo'
|
|
119
|
-
const url = `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(city)}&appid=${key}&units=metric`
|
|
120
|
-
|
|
121
|
-
const response = await axios.get(url)
|
|
122
|
-
const weather = response.data
|
|
123
|
-
|
|
124
|
-
return `Weather in ${city}:\nTemperature: ${weather.main.temp}°C\nDescription: ${weather.weather[0].description}\nHumidity: ${weather.main.humidity}%\nWind: ${weather.wind.speed} m/s`
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
if (axios.isAxiosError(error)) {
|
|
128
|
-
return `Error getting weather for ${city}: ${error.response?.status === 401 ? 'Invalid API key' : error.message}`
|
|
129
|
-
}
|
|
130
|
-
return `Error getting weather for ${city}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
// Tool for JSON Placeholder API (free testing API)
|
|
136
|
-
mcp.tool({
|
|
137
|
-
name: 'json-placeholder',
|
|
138
|
-
description: 'Interact with JSONPlaceholder API (posts, users, comments)',
|
|
139
|
-
inputs: [
|
|
140
|
-
{
|
|
141
|
-
name: 'resource',
|
|
142
|
-
type: 'string',
|
|
143
|
-
description: 'Resource type (posts, users, comments, albums, photos, todos)',
|
|
144
|
-
required: true,
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
name: 'id',
|
|
148
|
-
type: 'string',
|
|
149
|
-
description: 'Specific ID (optional, will list all if not provided)',
|
|
150
|
-
required: false,
|
|
151
|
-
},
|
|
152
|
-
],
|
|
153
|
-
fn: async ({ resource, id }: { resource: string, id?: string }) => {
|
|
154
|
-
try {
|
|
155
|
-
const baseUrl = 'https://jsonplaceholder.typicode.com'
|
|
156
|
-
const url = id ? `${baseUrl}/${resource}/${id}` : `${baseUrl}/${resource}`
|
|
157
|
-
|
|
158
|
-
const response = await axios.get(url)
|
|
159
|
-
return `JSONPlaceholder ${resource}${id ? ` (ID: ${id})` : ' (all items)'}:\n\n${JSON.stringify(response.data, null, 2)}`
|
|
160
|
-
}
|
|
161
|
-
catch (error) {
|
|
162
|
-
if (axios.isAxiosError(error)) {
|
|
163
|
-
return `Error fetching ${resource} from JSONPlaceholder: ${error.message}`
|
|
164
|
-
}
|
|
165
|
-
return `Error fetching ${resource}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
// Prompt for API documentation
|
|
171
|
-
mcp.prompt({
|
|
172
|
-
name: 'api-docs',
|
|
173
|
-
description: 'Generate API documentation',
|
|
174
|
-
args: [
|
|
175
|
-
{
|
|
176
|
-
name: 'endpoint',
|
|
177
|
-
type: 'string',
|
|
178
|
-
description: 'API endpoint to document',
|
|
179
|
-
required: true,
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
name: 'method',
|
|
183
|
-
type: 'string',
|
|
184
|
-
description: 'HTTP method (GET, POST, PUT, DELETE)',
|
|
185
|
-
required: false,
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
fn: async ({ endpoint, method = 'GET' }: { endpoint: string, method?: string }) => {
|
|
189
|
-
return `# API Documentation
|
|
190
|
-
|
|
191
|
-
## ${method} ${endpoint}
|
|
192
|
-
|
|
193
|
-
### Description
|
|
194
|
-
Documentation for the ${method} ${endpoint} endpoint.
|
|
195
|
-
|
|
196
|
-
### Parameters
|
|
197
|
-
- **endpoint**: ${endpoint}
|
|
198
|
-
- **method**: ${method}
|
|
199
|
-
|
|
200
|
-
### Example Request
|
|
201
|
-
\`\`\`bash
|
|
202
|
-
curl -X ${method} "${endpoint}"
|
|
203
|
-
\`\`\`
|
|
204
|
-
|
|
205
|
-
### Example Response
|
|
206
|
-
\`\`\`json
|
|
207
|
-
{
|
|
208
|
-
"status": "success",
|
|
209
|
-
"data": {}
|
|
210
|
-
}
|
|
211
|
-
\`\`\`
|
|
212
|
-
|
|
213
|
-
### Error Handling
|
|
214
|
-
- 400: Bad Request
|
|
215
|
-
- 401: Unauthorized
|
|
216
|
-
- 404: Not Found
|
|
217
|
-
- 500: Internal Server Error`
|
|
218
|
-
},
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
console.log('🚀 Starting API MCP Server...')
|
|
222
|
-
console.log('📋 Server: api-server v1.0.0')
|
|
223
|
-
console.log('📦 Resources: api://status')
|
|
224
|
-
console.log('🛠️ Tools: http-get, http-post, weather, json-placeholder')
|
|
225
|
-
console.log('💬 Prompts: api-docs')
|
|
226
|
-
console.log('✅ Server ready!')
|
|
227
|
-
|
|
228
|
-
// Start the server
|
|
229
|
-
mcp.serve().catch(console.error)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"rootDir": "./src",
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"moduleResolution": "node",
|
|
7
|
-
"allowJs": true,
|
|
8
|
-
"strict": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"declarationMap": true,
|
|
11
|
-
"outDir": "./dist",
|
|
12
|
-
"sourceMap": true,
|
|
13
|
-
"allowSyntheticDefaultImports": true,
|
|
14
|
-
"esModuleInterop": true,
|
|
15
|
-
"forceConsistentCasingInFileNames": true,
|
|
16
|
-
"skipLibCheck": true
|
|
17
|
-
},
|
|
18
|
-
"include": ["src/**/*"],
|
|
19
|
-
"exclude": ["node_modules", "dist"]
|
|
20
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# My MCP Server
|
|
2
|
-
|
|
3
|
-
A simple MCP server created with `create-mcp-app`.
|
|
4
|
-
|
|
5
|
-
## Getting Started
|
|
6
|
-
|
|
7
|
-
### Development
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Install dependencies
|
|
11
|
-
npm install
|
|
12
|
-
|
|
13
|
-
# Run in development mode
|
|
14
|
-
npm run dev
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### Production
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# Build the server
|
|
21
|
-
npm run build
|
|
22
|
-
|
|
23
|
-
# Run the built server
|
|
24
|
-
npm start
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Features
|
|
28
|
-
|
|
29
|
-
- **Resource**: `info://server` - Server information
|
|
30
|
-
- **Tool**: `echo` - Echo back messages
|
|
31
|
-
- **Prompt**: `greeting` - Generate personalized greetings
|
|
32
|
-
|
|
33
|
-
## Customization
|
|
34
|
-
|
|
35
|
-
Edit `src/server.ts` to add your own resources, tools, and prompts:
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
// Add a new resource
|
|
39
|
-
mcp.resource({
|
|
40
|
-
uri: 'my://resource',
|
|
41
|
-
name: 'My Resource',
|
|
42
|
-
fn: async () => 'Resource content'
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
// Add a new tool
|
|
46
|
-
mcp.tool({
|
|
47
|
-
name: 'my-tool',
|
|
48
|
-
inputs: [{ name: 'input', type: 'string', required: true }],
|
|
49
|
-
fn: async ({ input }) => `Processed: ${input}`
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
// Add a new prompt
|
|
53
|
-
mcp.prompt({
|
|
54
|
-
name: 'my-prompt',
|
|
55
|
-
args: [{ name: 'topic', type: 'string', required: true }],
|
|
56
|
-
fn: async ({ topic }) => `Generate content about ${topic}`
|
|
57
|
-
})
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Learn More
|
|
61
|
-
|
|
62
|
-
- [MCP Documentation](https://modelcontextprotocol.io)
|
|
63
|
-
- [mcp-use Documentation](https://docs.mcp-use.io)
|
|
64
|
-
- [Examples](https://github.com/mcp-use/mcp-use-ts/tree/main/examples)
|