pse-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/GEMINI.md +72 -0
- package/License.md +3 -0
- package/MCP Documents/README.md +1 -0
- package/MCP Documents/mcp-client-guide.txt +736 -0
- package/MCP Documents/mcp-complete-guide.txt +522 -0
- package/MCP Documents/mcp-enhanced-instructions.md +297 -0
- package/MCP Documents/mcp-server-guide.md +415 -0
- package/MCP Documents/mcp-windows.txt +161 -0
- package/QWEN.md +207 -0
- package/README.md +220 -0
- package/dist/content-fetcher.js +36 -0
- package/dist/google-search.js +421 -0
- package/dist/services/content-extractor.service.js +195 -0
- package/dist/services/google-search.service.js +244 -0
- package/dist/types.js +1 -0
- package/dist-package/README.md +210 -0
- package/dist-package/dist/content-fetcher.js +36 -0
- package/dist-package/dist/google-search.js +420 -0
- package/dist-package/dist/services/content-extractor.service.js +195 -0
- package/dist-package/dist/services/google-search.service.js +244 -0
- package/dist-package/dist/types.js +1 -0
- package/dist-package/package-lock.json +3104 -0
- package/dist-package/package.json +23 -0
- package/license +4 -0
- package/package.json +40 -0
- package/src/google-search.ts +477 -0
- package/src/mcp.d.ts +36 -0
- package/src/services/content-extractor.service.ts +232 -0
- package/src/services/google-search.service.ts +305 -0
- package/src/types.ts +64 -0
- package/tasks.md +141 -0
- package/tsconfig.json +16 -0
@@ -0,0 +1,297 @@
|
|
1
|
+
# Instructions for LLM:
|
2
|
+
|
3
|
+
You are an expert software development assistant. Your task is to provide a detailed plan and guidance for building a Windows desktop application according to the user's requirements.
|
4
|
+
|
5
|
+
## User Goal:
|
6
|
+
Create a Windows desktop application that allows a user to have a text-based conversation with Google's Gemini Flash 2.0 model via the Google Gemini API, while also supporting Anthropic's Model Context Protocol (MCP) for enhanced contextual capabilities. The application should support requests for image generation from Gemini and allow the user to save the generated images locally, preferably in the chat window as part of the conversation.
|
7
|
+
|
8
|
+
## Core Requirements:
|
9
|
+
|
10
|
+
- **Platform**: Windows Desktop.
|
11
|
+
|
12
|
+
- **Functionality**:
|
13
|
+
- Chat interface for conversation with Gemini Flash 2.0.
|
14
|
+
- Integration with Anthropic's Model Context Protocol (MCP) for accessing external data sources and tools.
|
15
|
+
- Ability to request image generation within the conversation.
|
16
|
+
- Display generated images within the application.
|
17
|
+
- Save generated images to the user's local machine.
|
18
|
+
|
19
|
+
- **APIs**:
|
20
|
+
- Google Gemini API for text and image generation
|
21
|
+
- Model Context Protocol (MCP) support for connecting to data sources and tools
|
22
|
+
|
23
|
+
- **Models**:
|
24
|
+
- Gemini Flash 2.0 (or latest appropriate Flash model).
|
25
|
+
- Support for MCP-compatible models
|
26
|
+
|
27
|
+
- **Technology**: User suggested Node.js, React, Three.js but is open. We will recommend Electron with Node.js and potentially React for the UI, as this fits the desktop requirement and leverages JavaScript expertise.
|
28
|
+
|
29
|
+
## Recommended Technology Stack:
|
30
|
+
|
31
|
+
- **Framework**: Electron (Allows building cross-platform desktop apps with web technologies - HTML, CSS, JavaScript).
|
32
|
+
|
33
|
+
- **Backend Logic (Main Process)**: Node.js (Runs within Electron's main process, handles API calls, file system operations).
|
34
|
+
|
35
|
+
- **Frontend UI (Renderer Process)**: HTML, CSS, JavaScript. Optionally, use React for building the user interface components, as suggested by the user and well-supported within Electron.
|
36
|
+
|
37
|
+
- **API Interactions**:
|
38
|
+
- Official Google Generative AI SDK for JavaScript (@google/generative-ai)
|
39
|
+
- Model Context Protocol SDKs (@anthropic/mcp-sdk or official TypeScript/JavaScript SDK)
|
40
|
+
|
41
|
+
## Detailed Plan & Steps:
|
42
|
+
|
43
|
+
### Phase 1: Setup and Basic Structure
|
44
|
+
|
45
|
+
#### Environment Setup:
|
46
|
+
|
47
|
+
- Ensure Node.js and npm (or yarn) are installed.
|
48
|
+
- Obtain a Google Gemini API Key from Google AI Studio. Store this key securely.
|
49
|
+
- If using Anthropic's Claude models via MCP, obtain necessary API credentials.
|
50
|
+
|
51
|
+
#### Project Initialization:
|
52
|
+
|
53
|
+
- Create a new project directory.
|
54
|
+
- Initialize npm: `npm init -y`
|
55
|
+
- Install Electron: `npm install --save-dev electron`
|
56
|
+
- Optional (If using React): Use a template like electron-vite with React or manually set up create-react-app and integrate it with Electron. Install React dependencies: `npm install react react-dom`.
|
57
|
+
- Install the Google AI SDK: `npm install @google/generative-ai`
|
58
|
+
- Install the MCP SDK: `npm install @anthropic/mcp-client` (or official MCP TypeScript SDK)
|
59
|
+
- Install dotenv for API key management: `npm install dotenv`
|
60
|
+
|
61
|
+
#### Electron Basic Structure:
|
62
|
+
|
63
|
+
- Create the main process entry file (e.g., main.js or src/electron/main.js). This Node.js script creates the application window (BrowserWindow) and handles system events.
|
64
|
+
- Create the renderer process files (e.g., index.html, renderer.js, style.css or React components if using React). This is the web page displayed within the Electron window.
|
65
|
+
- Configure package.json: Set the main field to your main process file and add a script to start Electron (e.g., "start": "electron .").
|
66
|
+
- Establish Inter-Process Communication (IPC) using ipcMain (in main.js) and ipcRenderer (in renderer.js or React components) for communication between the frontend and backend.
|
67
|
+
|
68
|
+
### Phase 2: UI Development
|
69
|
+
|
70
|
+
#### Design the UI (Renderer Process):
|
71
|
+
|
72
|
+
- Create the chat interface layout using HTML and CSS (or React components).
|
73
|
+
- Include:
|
74
|
+
- A display area for chat messages (user, Gemini, and MCP-enhanced responses).
|
75
|
+
- An input field for the user to type messages.
|
76
|
+
- A "Send" button.
|
77
|
+
- A tool/context selector for choosing between Gemini and MCP servers.
|
78
|
+
- An area to display generated images.
|
79
|
+
- A "Save Image" button (initially hidden or disabled).
|
80
|
+
|
81
|
+
### Phase 3: MCP Integration
|
82
|
+
|
83
|
+
#### Setup MCP Client:
|
84
|
+
|
85
|
+
- In the main process, create MCP client initialization logic:
|
86
|
+
```javascript
|
87
|
+
const { createClient } = require('@anthropic/mcp-client'); // or equivalent SDK
|
88
|
+
|
89
|
+
// Initialize MCP client
|
90
|
+
const mcpClient = createClient({
|
91
|
+
// Configure with appropriate options
|
92
|
+
});
|
93
|
+
```
|
94
|
+
|
95
|
+
#### Implement MCP Server Discovery & Connections:
|
96
|
+
|
97
|
+
- Create a mechanism to discover and connect to local MCP servers.
|
98
|
+
- Implement a configuration system to store MCP server settings:
|
99
|
+
```javascript
|
100
|
+
// Example MCP server configuration in settings.json
|
101
|
+
const mcpServerConfig = {
|
102
|
+
"fileSystem": {
|
103
|
+
"command": "node",
|
104
|
+
"args": ["./mcp-servers/filesystem-server.js"]
|
105
|
+
},
|
106
|
+
"database": {
|
107
|
+
"command": "node",
|
108
|
+
"args": ["./mcp-servers/database-server.js"]
|
109
|
+
}
|
110
|
+
};
|
111
|
+
```
|
112
|
+
|
113
|
+
#### Create Process Management for MCP Servers:
|
114
|
+
|
115
|
+
- Implement a system to start/stop MCP server processes.
|
116
|
+
- Handle IPC messages to manage these servers from the UI.
|
117
|
+
|
118
|
+
#### Implement MCP Tool Calls:
|
119
|
+
|
120
|
+
- Create a mechanism for sending tool requests to MCP servers.
|
121
|
+
- Handle responses and integrate them into the chat flow.
|
122
|
+
```javascript
|
123
|
+
async function callMCPTool(serverName, toolName, params) {
|
124
|
+
const server = mcpClient.connectToServer(serverName);
|
125
|
+
const toolResponse = await server.callTool(toolName, params);
|
126
|
+
return toolResponse;
|
127
|
+
}
|
128
|
+
```
|
129
|
+
|
130
|
+
### Phase 4: Gemini API Integration (Text)
|
131
|
+
|
132
|
+
#### Setup Gemini Client (Main Process):
|
133
|
+
|
134
|
+
- In main.js, import and initialize the @google/generative-ai SDK using your API key (loaded securely via dotenv).
|
135
|
+
- Specify the gemini-1.5-flash-latest model (or check documentation for the exact identifier for Gemini Flash 2.0 when available).
|
136
|
+
|
137
|
+
#### Implement Text Chat Logic:
|
138
|
+
|
139
|
+
- Renderer: When the user clicks "Send", capture the input text and send it to the main process via IPC (e.g., ipcRenderer.send('send-message', userText)).
|
140
|
+
- Main Process: Set up an ipcMain.on('send-message', ...) listener.
|
141
|
+
- Inside the listener:
|
142
|
+
- Determine whether to use Gemini API directly or route through MCP based on user selection/context.
|
143
|
+
- For Gemini direct use: Call the Gemini API using the SDK's generateContent method with the user's text prompt.
|
144
|
+
- For MCP-enhanced use: Transform the Gemini "tool calling" format to MCP format and use appropriate MCP servers.
|
145
|
+
- Handle the asynchronous response.
|
146
|
+
- Send the response back to the renderer process via IPC.
|
147
|
+
- Renderer: Display the received response in the chat display area.
|
148
|
+
|
149
|
+
### Phase 5: Bridge Gemini Tool Calling with MCP
|
150
|
+
|
151
|
+
#### Create MCP-to-Gemini Adapter:
|
152
|
+
|
153
|
+
- Implement a mechanism to translate between Gemini's tool calling format and MCP's protocol:
|
154
|
+
```javascript
|
155
|
+
function adaptGeminiToolCallToMCP(geminiToolCall) {
|
156
|
+
// Transform Gemini tool call format to MCP format
|
157
|
+
const mcpToolCall = {
|
158
|
+
name: geminiToolCall.name,
|
159
|
+
parameters: geminiToolCall.parameters
|
160
|
+
// Add other necessary MCP fields
|
161
|
+
};
|
162
|
+
return mcpToolCall;
|
163
|
+
}
|
164
|
+
|
165
|
+
function adaptMCPResponseToGemini(mcpResponse) {
|
166
|
+
// Transform MCP response format to Gemini format
|
167
|
+
const geminiResponse = {
|
168
|
+
// Format appropriately for Gemini
|
169
|
+
};
|
170
|
+
return geminiResponse;
|
171
|
+
}
|
172
|
+
```
|
173
|
+
|
174
|
+
### Phase 6: Gemini API Integration (Image Generation)
|
175
|
+
|
176
|
+
#### Implement Image Generation Request:
|
177
|
+
|
178
|
+
- Determine Trigger: Decide how the user requests an image (e.g., specific keywords in the prompt like "generate an image of...", a separate button, etc.).
|
179
|
+
- Renderer: When an image request is detected, send the prompt to the main process via IPC.
|
180
|
+
- Main Process: Handle image generation requests.
|
181
|
+
- Call the Gemini API using the SDK. Check the Gemini API documentation for the exact model and parameters needed for image generation.
|
182
|
+
|
183
|
+
#### Process Image Response (Main Process):
|
184
|
+
|
185
|
+
- Extract the image data (Base64, URL, etc.) based on the response format.
|
186
|
+
- If it returns a URL, use Node.js's built-in fetch or libraries like axios to download the image data.
|
187
|
+
|
188
|
+
#### Display Image (Renderer Process):
|
189
|
+
|
190
|
+
- Main Process: Send the image data back to the renderer process via IPC.
|
191
|
+
- Renderer: Display the image in the designated image display area.
|
192
|
+
- Enable the "Save Image" button.
|
193
|
+
|
194
|
+
### Phase 7: Image Saving
|
195
|
+
|
196
|
+
#### Implement Image Saving:
|
197
|
+
|
198
|
+
- Renderer: Add an event listener to the "Save Image" button. When clicked, send a request to the main process via IPC.
|
199
|
+
- Main Process: Set up an IPC listener for save requests.
|
200
|
+
- Use Electron's dialog.showSaveDialog method to prompt the user for a file path and name.
|
201
|
+
- Save the image data to the selected file path.
|
202
|
+
- Optionally, send a confirmation or error message back to the renderer.
|
203
|
+
|
204
|
+
### Phase 8: MCP Server Implementation Examples
|
205
|
+
|
206
|
+
#### Implement Example MCP Servers:
|
207
|
+
|
208
|
+
- Create a directory for MCP server implementations.
|
209
|
+
- Implement basic servers for common use cases:
|
210
|
+
|
211
|
+
1. **File System MCP Server**:
|
212
|
+
```javascript
|
213
|
+
const { Server, Tool } = require('@anthropic/mcp-server'); // or equivalent SDK
|
214
|
+
|
215
|
+
const app = new Server("filesystem-server");
|
216
|
+
|
217
|
+
// List tools
|
218
|
+
app.listTools(() => [
|
219
|
+
new Tool({
|
220
|
+
name: "read_file",
|
221
|
+
description: "Read content from a file",
|
222
|
+
inputSchema: {
|
223
|
+
type: "object",
|
224
|
+
properties: {
|
225
|
+
path: { type: "string", description: "Path to the file" }
|
226
|
+
},
|
227
|
+
required: ["path"]
|
228
|
+
}
|
229
|
+
}),
|
230
|
+
new Tool({
|
231
|
+
name: "write_file",
|
232
|
+
description: "Write content to a file",
|
233
|
+
inputSchema: {
|
234
|
+
type: "object",
|
235
|
+
properties: {
|
236
|
+
path: { type: "string", description: "Path to the file" },
|
237
|
+
content: { type: "string", description: "Content to write" }
|
238
|
+
},
|
239
|
+
required: ["path", "content"]
|
240
|
+
}
|
241
|
+
})
|
242
|
+
]);
|
243
|
+
|
244
|
+
// Implement tool handlers
|
245
|
+
app.handleTool("read_file", async ({ path }) => {
|
246
|
+
const fs = require('fs').promises;
|
247
|
+
const content = await fs.readFile(path, 'utf-8');
|
248
|
+
return { content };
|
249
|
+
});
|
250
|
+
|
251
|
+
app.handleTool("write_file", async ({ path, content }) => {
|
252
|
+
const fs = require('fs').promises;
|
253
|
+
await fs.writeFile(path, content, 'utf-8');
|
254
|
+
return { success: true };
|
255
|
+
});
|
256
|
+
|
257
|
+
// Start the server
|
258
|
+
app.start();
|
259
|
+
```
|
260
|
+
|
261
|
+
2. **Database MCP Server**:
|
262
|
+
```javascript
|
263
|
+
// Similar structure for database access
|
264
|
+
```
|
265
|
+
|
266
|
+
### Phase 9: Refinement and Packaging
|
267
|
+
|
268
|
+
#### Error Handling:
|
269
|
+
- Implement robust error handling for API calls, MCP interactions, file operations, and IPC communication.
|
270
|
+
|
271
|
+
#### Packaging:
|
272
|
+
- Use tools like electron-builder or electron-packager to bundle the application into a distributable Windows executable (.exe).
|
273
|
+
- Configure package.json with necessary build settings (app ID, icons, etc.).
|
274
|
+
|
275
|
+
## Important Considerations:
|
276
|
+
|
277
|
+
### API Key Security:
|
278
|
+
- The Gemini API key and any Anthropic API credentials must be kept secure and not embedded directly in client-side/renderer code. Use environment variables loaded in the main process.
|
279
|
+
|
280
|
+
### Gemini-MCP Interoperability:
|
281
|
+
- Gemini and MCP use different formats for tool calling. Create adapters to translate between these formats.
|
282
|
+
- Document clearly how the two systems interact within your application.
|
283
|
+
|
284
|
+
### MCP Server Management:
|
285
|
+
- MCP servers typically run as separate processes. Implement proper process management to start/stop these servers as needed.
|
286
|
+
- Consider resource usage and ensure servers are properly terminated when the application closes.
|
287
|
+
|
288
|
+
### Asynchronous Operations:
|
289
|
+
- Most operations (API calls, MCP interactions, file I/O, IPC) are asynchronous. Use async/await or Promises correctly.
|
290
|
+
|
291
|
+
### Rate Limits:
|
292
|
+
- Be mindful of Gemini API usage limits and costs.
|
293
|
+
- Implement appropriate rate limiting for MCP server calls.
|
294
|
+
|
295
|
+
### Documentation:
|
296
|
+
- Provide clear documentation on how to configure and use MCP servers within your application.
|
297
|
+
- Explain the differences between using Gemini directly vs. through MCP.
|
@@ -0,0 +1,415 @@
|
|
1
|
+
# Guide for Building an MCP Server
|
2
|
+
|
3
|
+
## Introduction to MCP Servers
|
4
|
+
|
5
|
+
A Model Context Protocol (MCP) server is a component that exposes data, tools, and prompts to LLM applications in a standardized way. Think of it as an API specifically designed for LLM interactions.
|
6
|
+
|
7
|
+
MCP servers can:
|
8
|
+
- Expose data through **Resources** (providing context to LLMs)
|
9
|
+
- Provide functionality through **Tools** (executable functions)
|
10
|
+
- Define interaction patterns through **Prompts** (reusable templates for LLM interactions)
|
11
|
+
|
12
|
+
## Prerequisites
|
13
|
+
|
14
|
+
- Node.js (version 18 or later) and npm
|
15
|
+
- Basic knowledge of TypeScript/JavaScript or Python
|
16
|
+
- VS Code (recommended for development)
|
17
|
+
|
18
|
+
## Getting Started with TypeScript Implementation
|
19
|
+
|
20
|
+
### 1. Setting Up Your Project
|
21
|
+
|
22
|
+
Create a new directory for your MCP server:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
mkdir my-mcp-server
|
26
|
+
cd my-mcp-server
|
27
|
+
npm init -y
|
28
|
+
```
|
29
|
+
|
30
|
+
Install the MCP SDK:
|
31
|
+
|
32
|
+
```bash
|
33
|
+
npm install @modelcontextprotocol/sdk
|
34
|
+
```
|
35
|
+
|
36
|
+
Add TypeScript and other dev dependencies:
|
37
|
+
|
38
|
+
```bash
|
39
|
+
npm install --save-dev typescript ts-node @types/node
|
40
|
+
```
|
41
|
+
|
42
|
+
Create a `tsconfig.json` file:
|
43
|
+
|
44
|
+
```json
|
45
|
+
{
|
46
|
+
"compilerOptions": {
|
47
|
+
"target": "ES2020",
|
48
|
+
"module": "NodeNext",
|
49
|
+
"esModuleInterop": true,
|
50
|
+
"forceConsistentCasingInFileNames": true,
|
51
|
+
"strict": true,
|
52
|
+
"skipLibCheck": true,
|
53
|
+
"outDir": "./build"
|
54
|
+
},
|
55
|
+
"include": ["src/**/*"]
|
56
|
+
}
|
57
|
+
```
|
58
|
+
|
59
|
+
### 2. Creating Your Server
|
60
|
+
|
61
|
+
Create a `src` directory and an `index.ts` file inside it:
|
62
|
+
|
63
|
+
```bash
|
64
|
+
mkdir src
|
65
|
+
touch src/index.ts
|
66
|
+
```
|
67
|
+
|
68
|
+
### 3. Basic Server Implementation
|
69
|
+
|
70
|
+
Here's a basic MCP server implementation:
|
71
|
+
|
72
|
+
```typescript
|
73
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
74
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
75
|
+
import { z } from "@modelcontextprotocol/sdk/deps.js";
|
76
|
+
|
77
|
+
// Create a new MCP server
|
78
|
+
const server = new McpServer({
|
79
|
+
name: "example-server",
|
80
|
+
version: "1.0.0",
|
81
|
+
});
|
82
|
+
|
83
|
+
// Define a resource
|
84
|
+
server.resource(
|
85
|
+
"greeting",
|
86
|
+
{},
|
87
|
+
async () => {
|
88
|
+
return {
|
89
|
+
content: {
|
90
|
+
type: "text",
|
91
|
+
text: "Hello from MCP server!",
|
92
|
+
},
|
93
|
+
};
|
94
|
+
}
|
95
|
+
);
|
96
|
+
|
97
|
+
// Define a tool
|
98
|
+
server.tool(
|
99
|
+
"echo",
|
100
|
+
{
|
101
|
+
message: z.string().describe("Message to echo"),
|
102
|
+
},
|
103
|
+
async ({ message }) => {
|
104
|
+
return {
|
105
|
+
content: {
|
106
|
+
type: "text",
|
107
|
+
text: `You said: ${message}`,
|
108
|
+
},
|
109
|
+
};
|
110
|
+
}
|
111
|
+
);
|
112
|
+
|
113
|
+
// Define a prompt
|
114
|
+
server.prompt(
|
115
|
+
"introduce",
|
116
|
+
{
|
117
|
+
name: z.string().describe("Person's name"),
|
118
|
+
},
|
119
|
+
({ name }) => ({
|
120
|
+
messages: [
|
121
|
+
{
|
122
|
+
role: "user",
|
123
|
+
content: {
|
124
|
+
type: "text",
|
125
|
+
text: `Please introduce yourself to ${name}.`,
|
126
|
+
},
|
127
|
+
},
|
128
|
+
],
|
129
|
+
})
|
130
|
+
);
|
131
|
+
|
132
|
+
// Start the server
|
133
|
+
const transport = new StdioServerTransport();
|
134
|
+
server.listen(transport);
|
135
|
+
```
|
136
|
+
|
137
|
+
### 4. Building and Running
|
138
|
+
|
139
|
+
Add scripts to your `package.json`:
|
140
|
+
|
141
|
+
```json
|
142
|
+
"scripts": {
|
143
|
+
"build": "tsc",
|
144
|
+
"start": "node build/index.js"
|
145
|
+
}
|
146
|
+
```
|
147
|
+
|
148
|
+
Build and run your server:
|
149
|
+
|
150
|
+
```bash
|
151
|
+
npm run build
|
152
|
+
npm run start
|
153
|
+
```
|
154
|
+
|
155
|
+
## Getting Started with Python Implementation
|
156
|
+
|
157
|
+
### 1. Setting Up Your Python Environment
|
158
|
+
|
159
|
+
```bash
|
160
|
+
# Create and activate a virtual environment
|
161
|
+
python -m venv venv
|
162
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
163
|
+
|
164
|
+
# Install the MCP SDK
|
165
|
+
pip install mcp-sdk
|
166
|
+
```
|
167
|
+
|
168
|
+
### 2. Creating a Basic Python MCP Server
|
169
|
+
|
170
|
+
Create a file named `server.py`:
|
171
|
+
|
172
|
+
```python
|
173
|
+
import asyncio
|
174
|
+
from mcp import Server, StdioTransport, Tool, Resource, Prompt
|
175
|
+
from pydantic import BaseModel
|
176
|
+
|
177
|
+
class EchoParams(BaseModel):
|
178
|
+
message: str
|
179
|
+
|
180
|
+
class GreetingParams(BaseModel):
|
181
|
+
name: str
|
182
|
+
|
183
|
+
# Create a server
|
184
|
+
server = Server(name="python-example-server", version="1.0.0")
|
185
|
+
|
186
|
+
# Define a resource
|
187
|
+
@server.resource("greeting")
|
188
|
+
async def greeting_resource(params=None):
|
189
|
+
return {
|
190
|
+
"content": {
|
191
|
+
"type": "text",
|
192
|
+
"text": "Hello from Python MCP server!"
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
# Define a tool
|
197
|
+
@server.tool("echo")
|
198
|
+
async def echo_tool(params: EchoParams):
|
199
|
+
return {
|
200
|
+
"content": {
|
201
|
+
"type": "text",
|
202
|
+
"text": f"You said: {params.message}"
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
# Define a prompt
|
207
|
+
@server.prompt("introduce")
|
208
|
+
async def introduce_prompt(params: GreetingParams):
|
209
|
+
return {
|
210
|
+
"messages": [
|
211
|
+
{
|
212
|
+
"role": "user",
|
213
|
+
"content": {
|
214
|
+
"type": "text",
|
215
|
+
"text": f"Please introduce yourself to {params.name}."
|
216
|
+
}
|
217
|
+
}
|
218
|
+
]
|
219
|
+
}
|
220
|
+
|
221
|
+
# Run the server
|
222
|
+
if __name__ == "__main__":
|
223
|
+
transport = StdioTransport()
|
224
|
+
asyncio.run(server.listen(transport))
|
225
|
+
```
|
226
|
+
|
227
|
+
Run your Python server:
|
228
|
+
|
229
|
+
```bash
|
230
|
+
python server.py
|
231
|
+
```
|
232
|
+
|
233
|
+
## Advanced MCP Server Concepts
|
234
|
+
|
235
|
+
### 1. Adding Authentication
|
236
|
+
|
237
|
+
For HTTP transport, you might need to add authentication:
|
238
|
+
|
239
|
+
```typescript
|
240
|
+
// TypeScript example
|
241
|
+
import { HttpServerTransport } from "@modelcontextprotocol/sdk/server/http.js";
|
242
|
+
|
243
|
+
const transport = new HttpServerTransport({
|
244
|
+
port: 3000,
|
245
|
+
auth: async (req) => {
|
246
|
+
const token = req.headers.authorization?.split(" ")[1];
|
247
|
+
if (token !== "your-secret-token") {
|
248
|
+
throw new Error("Unauthorized");
|
249
|
+
}
|
250
|
+
},
|
251
|
+
});
|
252
|
+
```
|
253
|
+
|
254
|
+
### 2. Working with External APIs
|
255
|
+
|
256
|
+
MCP servers often connect to external services:
|
257
|
+
|
258
|
+
```typescript
|
259
|
+
// TypeScript example with an external API
|
260
|
+
import fetch from "node-fetch";
|
261
|
+
|
262
|
+
server.tool(
|
263
|
+
"get-weather",
|
264
|
+
{
|
265
|
+
location: z.string().describe("Location to get weather for"),
|
266
|
+
},
|
267
|
+
async ({ location }) => {
|
268
|
+
try {
|
269
|
+
const response = await fetch(
|
270
|
+
`https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=${location}`
|
271
|
+
);
|
272
|
+
const data = await response.json();
|
273
|
+
|
274
|
+
return {
|
275
|
+
content: {
|
276
|
+
type: "text",
|
277
|
+
text: `Current weather in ${location}: ${data.current.temp_c}°C, ${data.current.condition.text}`,
|
278
|
+
},
|
279
|
+
};
|
280
|
+
} catch (error) {
|
281
|
+
return {
|
282
|
+
content: {
|
283
|
+
type: "text",
|
284
|
+
text: `Error fetching weather data: ${error.message}`,
|
285
|
+
},
|
286
|
+
};
|
287
|
+
}
|
288
|
+
}
|
289
|
+
);
|
290
|
+
```
|
291
|
+
|
292
|
+
### 3. Dynamic Resources
|
293
|
+
|
294
|
+
Resources can dynamically generate content based on parameters:
|
295
|
+
|
296
|
+
```typescript
|
297
|
+
server.resource(
|
298
|
+
"document",
|
299
|
+
{
|
300
|
+
id: z.string().describe("Document ID to retrieve"),
|
301
|
+
},
|
302
|
+
async ({ id }) => {
|
303
|
+
// Imagine this fetches from a database
|
304
|
+
const document = await getDocumentById(id);
|
305
|
+
|
306
|
+
return {
|
307
|
+
content: {
|
308
|
+
type: "text",
|
309
|
+
text: document.content,
|
310
|
+
},
|
311
|
+
};
|
312
|
+
}
|
313
|
+
);
|
314
|
+
```
|
315
|
+
|
316
|
+
## Best Practices
|
317
|
+
|
318
|
+
1. **Keep it Simple**: Start with basic capabilities and expand gradually.
|
319
|
+
2. **Error Handling**: Always include proper error handling in your tools and resources.
|
320
|
+
3. **Validation**: Use Zod (TypeScript) or Pydantic (Python) for robust parameter validation.
|
321
|
+
4. **Documentation**: Provide clear descriptions for all tools, resources, and prompts.
|
322
|
+
5. **Security**: Be cautious about what your server exposes, especially with tools that execute code.
|
323
|
+
6. **Testing**: Test your MCP server with real clients like Claude Desktop or Cody.
|
324
|
+
7. **Platform Compatibility**:
|
325
|
+
- Test on both Unix and Windows systems
|
326
|
+
- Use binary mode for stdio on Windows
|
327
|
+
- Handle path separators correctly
|
328
|
+
- Consider using cross-platform libraries
|
329
|
+
8. **Resource Management**:
|
330
|
+
- Implement proper cleanup for resources
|
331
|
+
- Handle connection timeouts gracefully
|
332
|
+
- Monitor memory usage
|
333
|
+
- Cache responses when appropriate
|
334
|
+
9. **Versioning**:
|
335
|
+
- Follow semantic versioning
|
336
|
+
- Maintain backwards compatibility
|
337
|
+
- Document breaking changes
|
338
|
+
- Provide migration guides
|
339
|
+
|
340
|
+
## Platform-Specific Considerations
|
341
|
+
|
342
|
+
### Windows Implementation
|
343
|
+
When developing MCP servers for Windows:
|
344
|
+
|
345
|
+
1. **stdio Handling**:
|
346
|
+
```typescript
|
347
|
+
if (process.platform === 'win32') {
|
348
|
+
process.stdin.setEncoding('binary');
|
349
|
+
process.stdout.setDefaultEncoding('binary');
|
350
|
+
}
|
351
|
+
```
|
352
|
+
|
353
|
+
2. **Path Management**:
|
354
|
+
```typescript
|
355
|
+
import { join } from 'path';
|
356
|
+
|
357
|
+
const configPath = join(process.cwd(), 'config.json');
|
358
|
+
```
|
359
|
+
|
360
|
+
3. **Error Handling**:
|
361
|
+
```typescript
|
362
|
+
process.on('uncaughtException', (error) => {
|
363
|
+
console.error(`Uncaught Exception: ${error.message}`);
|
364
|
+
process.exit(1);
|
365
|
+
});
|
366
|
+
```
|
367
|
+
|
368
|
+
### Unix Implementation
|
369
|
+
For Unix-based systems:
|
370
|
+
|
371
|
+
1. **Signal Handling**:
|
372
|
+
```typescript
|
373
|
+
process.on('SIGTERM', () => {
|
374
|
+
console.error('Received SIGTERM, shutting down...');
|
375
|
+
process.exit(0);
|
376
|
+
});
|
377
|
+
```
|
378
|
+
|
379
|
+
2. **File Permissions**:
|
380
|
+
```typescript
|
381
|
+
import { chmod } from 'fs/promises';
|
382
|
+
|
383
|
+
await chmod('server.sh', 0o755);
|
384
|
+
```
|
385
|
+
|
386
|
+
## Integration with VS Code
|
387
|
+
|
388
|
+
If you're developing an MCP server for VS Code:
|
389
|
+
|
390
|
+
1. Follow the standard MCP server implementation.
|
391
|
+
2. Consider using the VS Code Extension API for deeper integration.
|
392
|
+
3. Look at examples like Continue, Cody, or other VS Code extensions that implement MCP.
|
393
|
+
4. Handle workspace-specific configurations.
|
394
|
+
5. Implement proper error reporting to VS Code's output channels.
|
395
|
+
|
396
|
+
## Debugging
|
397
|
+
|
398
|
+
For debugging your MCP server:
|
399
|
+
|
400
|
+
1. Use console logs to track execution flow.
|
401
|
+
2. Implement detailed error messages.
|
402
|
+
3. Use VS Code's debugging features for TypeScript/JavaScript or Python.
|
403
|
+
4. Test with simple clients first before integrating with more complex systems.
|
404
|
+
|
405
|
+
## Resources
|
406
|
+
|
407
|
+
- [Official MCP Documentation](https://modelcontextprotocol.io/)
|
408
|
+
- [MCP Specification](https://spec.modelcontextprotocol.io/)
|
409
|
+
- [TypeScript SDK GitHub Repository](https://github.com/modelcontextprotocol/typescript-sdk)
|
410
|
+
- [Python SDK GitHub Repository](https://github.com/modelcontextprotocol/python-sdk)
|
411
|
+
- [Example MCP Servers Repository](https://github.com/modelcontextprotocol/servers)
|
412
|
+
|
413
|
+
---
|
414
|
+
|
415
|
+
This guide provides a foundation for building MCP servers. As the ecosystem evolves, new patterns and best practices will emerge. Stay updated with the official documentation and community resources for the latest developments.
|