@purplesquirrel/volcengine-mcp 1.0.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/.github/dependabot.yml +21 -0
- package/.github/workflows/ci.yml +36 -0
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/index.js +418 -0
- package/package.json +24 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "npm"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
open-pull-requests-limit: 10
|
|
8
|
+
labels:
|
|
9
|
+
- "dependencies"
|
|
10
|
+
commit-message:
|
|
11
|
+
prefix: "chore(deps)"
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "github-actions"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
labels:
|
|
18
|
+
- "dependencies"
|
|
19
|
+
- "github-actions"
|
|
20
|
+
commit-message:
|
|
21
|
+
prefix: "chore(ci)"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
node-version: [18.x, 20.x]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: ${{ matrix.node-version }}
|
|
24
|
+
cache: 'npm'
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Run linter
|
|
30
|
+
run: npm run lint --if-present
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: npm test --if-present
|
|
34
|
+
|
|
35
|
+
- name: Build
|
|
36
|
+
run: npm run build --if-present
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Purple Squirrel Media
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
[](https://opensource.org/licenses/MIT)
|
|
2
|
+
[](https://modelcontextprotocol.io)
|
|
3
|
+
[](https://www.volcengine.com)
|
|
4
|
+
[](https://github.com/PurpleSquirrelMedia/volcengine-mcp/actions/workflows/ci.yml)
|
|
5
|
+
|
|
6
|
+
# Volcano Engine MCP Server
|
|
7
|
+
|
|
8
|
+
MCP server for ByteDance Volcano Engine (Doubao) integration with Claude Code. Enables Claude to delegate tasks to ByteDance's Doubao LLM models.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Text Generation** - Generate text using Doubao models
|
|
13
|
+
- **Chat** - Multi-turn conversations with Doubao
|
|
14
|
+
- **Embeddings** - Generate text embeddings for RAG and semantic search
|
|
15
|
+
- **Model Listing** - List available Doubao models
|
|
16
|
+
|
|
17
|
+
## Available Tools (4 total)
|
|
18
|
+
|
|
19
|
+
| Tool | Description |
|
|
20
|
+
|------|-------------|
|
|
21
|
+
| `doubao_generate` | Generate text using Doubao models |
|
|
22
|
+
| `doubao_chat` | Multi-turn chat with Doubao models |
|
|
23
|
+
| `doubao_embeddings` | Generate text embeddings |
|
|
24
|
+
| `doubao_list_models` | List available models |
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
### 1. Get Volcano Engine API Key
|
|
29
|
+
|
|
30
|
+
1. Sign up at [console.volcengine.com](https://console.volcengine.com)
|
|
31
|
+
2. Complete real-name authentication (required)
|
|
32
|
+
3. Navigate to: **Large Models** → **Volcano Ark** → **API Key Management**
|
|
33
|
+
4. Create and copy your API key
|
|
34
|
+
|
|
35
|
+
### 2. Install Dependencies
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd ~/mcp-servers/volcengine-mcp
|
|
39
|
+
npm install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Add to Claude Code
|
|
43
|
+
|
|
44
|
+
Add to `~/.claude.json`:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"volcengine": {
|
|
50
|
+
"type": "stdio",
|
|
51
|
+
"command": "node",
|
|
52
|
+
"args": ["/Users/matthewkarsten/mcp-servers/volcengine-mcp/index.js"],
|
|
53
|
+
"env": {
|
|
54
|
+
"ARK_API_KEY": "your-api-key-here"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Environment Variables
|
|
62
|
+
|
|
63
|
+
| Variable | Description | Required |
|
|
64
|
+
|----------|-------------|----------|
|
|
65
|
+
| `ARK_API_KEY` | Volcano Ark API key | Yes |
|
|
66
|
+
| `VOLCENGINE_API_KEY` | Alternative API key env var | Yes (if ARK_API_KEY not set) |
|
|
67
|
+
| `ARK_BASE_URL` | API base URL | No (defaults to Beijing region) |
|
|
68
|
+
| `ARK_CHAT_MODEL` | Default chat model | No (defaults to doubao-pro-32k) |
|
|
69
|
+
| `ARK_EMBEDDING_MODEL` | Default embedding model | No |
|
|
70
|
+
|
|
71
|
+
## Available Models
|
|
72
|
+
|
|
73
|
+
### Chat Models
|
|
74
|
+
| Model ID | Description | Context |
|
|
75
|
+
|----------|-------------|---------|
|
|
76
|
+
| `doubao-pro-32k` | General purpose, large context | 32K |
|
|
77
|
+
| `doubao-pro-4k` | General purpose, fast | 4K |
|
|
78
|
+
| `doubao-lite-32k` | Lightweight, large context | 32K |
|
|
79
|
+
| `doubao-lite-4k` | Lightweight, fast | 4K |
|
|
80
|
+
| `doubao-seed-1-6-250615` | Latest with vision support | 32K |
|
|
81
|
+
| `doubao-seed-1-6-flash-250615` | Fast thinking, low latency | 32K |
|
|
82
|
+
| `doubao-seed-1-6-thinking-250615` | Deep reasoning | 32K |
|
|
83
|
+
|
|
84
|
+
### Embedding Models
|
|
85
|
+
| Model ID | Description | Dimensions |
|
|
86
|
+
|----------|-------------|------------|
|
|
87
|
+
| `doubao-embedding` | Text embeddings | 2560 |
|
|
88
|
+
| `doubao-embedding-text-240715` | Latest embeddings | 2560 |
|
|
89
|
+
|
|
90
|
+
## Architecture
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Claude Code (Opus 4.5)
|
|
94
|
+
│
|
|
95
|
+
└──▶ Volcano Engine MCP Server
|
|
96
|
+
│
|
|
97
|
+
└──▶ Volcano Ark API
|
|
98
|
+
│
|
|
99
|
+
├── Doubao Pro Models
|
|
100
|
+
├── Doubao Lite Models
|
|
101
|
+
├── Doubao Seed Models
|
|
102
|
+
└── Embedding Models
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Usage Examples
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
User: Use Doubao to write a haiku about cloud computing
|
|
109
|
+
|
|
110
|
+
Claude: [Uses doubao_generate tool]
|
|
111
|
+
Result:
|
|
112
|
+
{
|
|
113
|
+
"text": "Servers hum softly\nData flows through endless clouds\nDigital rain falls",
|
|
114
|
+
"model": "doubao-pro-32k",
|
|
115
|
+
"usage": { "prompt_tokens": 12, "completion_tokens": 18 }
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Pricing
|
|
120
|
+
|
|
121
|
+
ByteDance Volcano Engine offers competitive pricing:
|
|
122
|
+
|
|
123
|
+
- **Free tier**: 500,000 tokens for individual users
|
|
124
|
+
- **Doubao Pro**: ~0.0008 CNY / 1K tokens (~$0.0001 USD)
|
|
125
|
+
- **Doubao Lite**: ~0.0003 CNY / 1K tokens
|
|
126
|
+
|
|
127
|
+
## Multi-Agent Architecture
|
|
128
|
+
|
|
129
|
+
This MCP server enables a multi-agent system:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Claude Code (Opus 4.5)
|
|
133
|
+
│
|
|
134
|
+
├──▶ watsonx MCP Server (IBM Granite)
|
|
135
|
+
├──▶ volcengine MCP Server (ByteDance Doubao)
|
|
136
|
+
└──▶ ibmz MCP Server (Key Protect HSM)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Claude can delegate different tasks to specialized models based on:
|
|
140
|
+
- **Language**: Doubao excels at Chinese language tasks
|
|
141
|
+
- **Latency**: Doubao Flash for real-time applications
|
|
142
|
+
- **Reasoning**: Doubao Thinking for complex analysis
|
|
143
|
+
- **Cost**: Doubao Lite for high-volume tasks
|
|
144
|
+
|
|
145
|
+
## Files
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
volcengine-mcp/
|
|
149
|
+
├── index.js # MCP server implementation
|
|
150
|
+
├── package.json # Dependencies
|
|
151
|
+
└── README.md # This file
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Dependencies
|
|
155
|
+
|
|
156
|
+
- `@modelcontextprotocol/sdk` - MCP SDK
|
|
157
|
+
|
|
158
|
+
## Author
|
|
159
|
+
|
|
160
|
+
Matthew Karsten
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Volcano Engine (ByteDance) MCP Server
|
|
5
|
+
*
|
|
6
|
+
* Provides integration with ByteDance's Doubao LLM models via the Volcano Ark API.
|
|
7
|
+
* Enables Claude to delegate tasks to Doubao models for text generation, chat, and embeddings.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
11
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
|
+
import {
|
|
13
|
+
CallToolRequestSchema,
|
|
14
|
+
ListToolsRequestSchema,
|
|
15
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
16
|
+
|
|
17
|
+
// Configuration from environment variables
|
|
18
|
+
const ARK_API_KEY = process.env.ARK_API_KEY || process.env.VOLCENGINE_API_KEY;
|
|
19
|
+
const ARK_BASE_URL = process.env.ARK_BASE_URL || 'https://ark.cn-beijing.volces.com/api/v3';
|
|
20
|
+
|
|
21
|
+
// Default models
|
|
22
|
+
const DEFAULT_CHAT_MODEL = process.env.ARK_CHAT_MODEL || 'doubao-pro-32k';
|
|
23
|
+
const DEFAULT_EMBEDDING_MODEL = process.env.ARK_EMBEDDING_MODEL || 'doubao-embedding';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Make authenticated request to Volcano Ark API
|
|
27
|
+
*/
|
|
28
|
+
async function arkRequest(endpoint, body, method = 'POST') {
|
|
29
|
+
if (!ARK_API_KEY) {
|
|
30
|
+
throw new Error('ARK_API_KEY or VOLCENGINE_API_KEY environment variable is required');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const response = await fetch(`${ARK_BASE_URL}${endpoint}`, {
|
|
34
|
+
method,
|
|
35
|
+
headers: {
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
'Authorization': `Bearer ${ARK_API_KEY}`,
|
|
38
|
+
},
|
|
39
|
+
body: method !== 'GET' ? JSON.stringify(body) : undefined,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
const error = await response.text();
|
|
44
|
+
throw new Error(`Volcano Ark API error (${response.status}): ${error}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Generate text using Doubao models
|
|
52
|
+
*/
|
|
53
|
+
async function generateText(prompt, options = {}) {
|
|
54
|
+
const {
|
|
55
|
+
model = DEFAULT_CHAT_MODEL,
|
|
56
|
+
max_tokens = 2048,
|
|
57
|
+
temperature = 0.7,
|
|
58
|
+
top_p = 0.9,
|
|
59
|
+
system_prompt = null,
|
|
60
|
+
} = options;
|
|
61
|
+
|
|
62
|
+
const messages = [];
|
|
63
|
+
|
|
64
|
+
if (system_prompt) {
|
|
65
|
+
messages.push({ role: 'system', content: system_prompt });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
messages.push({ role: 'user', content: prompt });
|
|
69
|
+
|
|
70
|
+
const response = await arkRequest('/chat/completions', {
|
|
71
|
+
model,
|
|
72
|
+
messages,
|
|
73
|
+
max_tokens,
|
|
74
|
+
temperature,
|
|
75
|
+
top_p,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
text: response.choices?.[0]?.message?.content || '',
|
|
80
|
+
model: response.model,
|
|
81
|
+
usage: response.usage,
|
|
82
|
+
finish_reason: response.choices?.[0]?.finish_reason,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Chat with Doubao models (multi-turn conversation)
|
|
88
|
+
*/
|
|
89
|
+
async function chat(messages, options = {}) {
|
|
90
|
+
const {
|
|
91
|
+
model = DEFAULT_CHAT_MODEL,
|
|
92
|
+
max_tokens = 2048,
|
|
93
|
+
temperature = 0.7,
|
|
94
|
+
top_p = 0.9,
|
|
95
|
+
} = options;
|
|
96
|
+
|
|
97
|
+
const response = await arkRequest('/chat/completions', {
|
|
98
|
+
model,
|
|
99
|
+
messages,
|
|
100
|
+
max_tokens,
|
|
101
|
+
temperature,
|
|
102
|
+
top_p,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
response: response.choices?.[0]?.message?.content || '',
|
|
107
|
+
model: response.model,
|
|
108
|
+
usage: response.usage,
|
|
109
|
+
finish_reason: response.choices?.[0]?.finish_reason,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Generate embeddings using Doubao embedding models
|
|
115
|
+
*/
|
|
116
|
+
async function generateEmbeddings(texts, options = {}) {
|
|
117
|
+
const { model = DEFAULT_EMBEDDING_MODEL } = options;
|
|
118
|
+
|
|
119
|
+
const input = Array.isArray(texts) ? texts : [texts];
|
|
120
|
+
|
|
121
|
+
const response = await arkRequest('/embeddings', {
|
|
122
|
+
model,
|
|
123
|
+
input,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
embeddings: response.data?.map(d => d.embedding) || [],
|
|
128
|
+
model: response.model,
|
|
129
|
+
usage: response.usage,
|
|
130
|
+
dimensions: response.data?.[0]?.embedding?.length || 0,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* List available models (known Doubao models)
|
|
136
|
+
*/
|
|
137
|
+
function listModels() {
|
|
138
|
+
// Volcano Ark doesn't have a public model list API, so we return known models
|
|
139
|
+
return {
|
|
140
|
+
models: [
|
|
141
|
+
{
|
|
142
|
+
id: 'doubao-pro-32k',
|
|
143
|
+
name: 'Doubao Pro 32K',
|
|
144
|
+
description: 'General purpose model with 32K context window',
|
|
145
|
+
type: 'chat',
|
|
146
|
+
context_length: 32768,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: 'doubao-pro-4k',
|
|
150
|
+
name: 'Doubao Pro 4K',
|
|
151
|
+
description: 'General purpose model with 4K context window',
|
|
152
|
+
type: 'chat',
|
|
153
|
+
context_length: 4096,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: 'doubao-lite-32k',
|
|
157
|
+
name: 'Doubao Lite 32K',
|
|
158
|
+
description: 'Lightweight model with 32K context window',
|
|
159
|
+
type: 'chat',
|
|
160
|
+
context_length: 32768,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: 'doubao-lite-4k',
|
|
164
|
+
name: 'Doubao Lite 4K',
|
|
165
|
+
description: 'Lightweight model with 4K context window',
|
|
166
|
+
type: 'chat',
|
|
167
|
+
context_length: 4096,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 'doubao-seed-1-6-250615',
|
|
171
|
+
name: 'Doubao Seed 1.6',
|
|
172
|
+
description: 'Latest Doubao model with vision support for agents',
|
|
173
|
+
type: 'chat',
|
|
174
|
+
context_length: 32768,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: 'doubao-seed-1-6-flash-250615',
|
|
178
|
+
name: 'Doubao Seed 1.6 Flash',
|
|
179
|
+
description: 'Fast thinking model with low latency',
|
|
180
|
+
type: 'chat',
|
|
181
|
+
context_length: 32768,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: 'doubao-seed-1-6-thinking-250615',
|
|
185
|
+
name: 'Doubao Seed 1.6 Thinking',
|
|
186
|
+
description: 'Deep reasoning model for complex tasks',
|
|
187
|
+
type: 'chat',
|
|
188
|
+
context_length: 32768,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: 'doubao-embedding',
|
|
192
|
+
name: 'Doubao Embedding',
|
|
193
|
+
description: 'Text embedding model',
|
|
194
|
+
type: 'embedding',
|
|
195
|
+
dimensions: 2560,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 'doubao-embedding-text-240715',
|
|
199
|
+
name: 'Doubao Embedding Text',
|
|
200
|
+
description: 'Latest text embedding model',
|
|
201
|
+
type: 'embedding',
|
|
202
|
+
dimensions: 2560,
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Create MCP Server
|
|
209
|
+
const server = new Server(
|
|
210
|
+
{
|
|
211
|
+
name: 'volcengine-mcp-server',
|
|
212
|
+
version: '1.0.0',
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
capabilities: {
|
|
216
|
+
tools: {},
|
|
217
|
+
},
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
// Define available tools
|
|
222
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
223
|
+
return {
|
|
224
|
+
tools: [
|
|
225
|
+
{
|
|
226
|
+
name: 'doubao_generate',
|
|
227
|
+
description: 'Generate text using ByteDance Doubao models. Use for text completion, content generation, and single-turn tasks.',
|
|
228
|
+
inputSchema: {
|
|
229
|
+
type: 'object',
|
|
230
|
+
properties: {
|
|
231
|
+
prompt: {
|
|
232
|
+
type: 'string',
|
|
233
|
+
description: 'The prompt to send to the model',
|
|
234
|
+
},
|
|
235
|
+
model: {
|
|
236
|
+
type: 'string',
|
|
237
|
+
description: 'Model ID (e.g., doubao-pro-32k, doubao-lite-4k, doubao-seed-1-6-250615)',
|
|
238
|
+
default: DEFAULT_CHAT_MODEL,
|
|
239
|
+
},
|
|
240
|
+
max_tokens: {
|
|
241
|
+
type: 'number',
|
|
242
|
+
description: 'Maximum tokens to generate',
|
|
243
|
+
default: 2048,
|
|
244
|
+
},
|
|
245
|
+
temperature: {
|
|
246
|
+
type: 'number',
|
|
247
|
+
description: 'Sampling temperature (0-1)',
|
|
248
|
+
default: 0.7,
|
|
249
|
+
},
|
|
250
|
+
system_prompt: {
|
|
251
|
+
type: 'string',
|
|
252
|
+
description: 'Optional system prompt to set context',
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
required: ['prompt'],
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: 'doubao_chat',
|
|
260
|
+
description: 'Have a multi-turn conversation with Doubao models. Supports conversation history.',
|
|
261
|
+
inputSchema: {
|
|
262
|
+
type: 'object',
|
|
263
|
+
properties: {
|
|
264
|
+
messages: {
|
|
265
|
+
type: 'array',
|
|
266
|
+
description: 'Array of chat messages with role (system/user/assistant) and content',
|
|
267
|
+
items: {
|
|
268
|
+
type: 'object',
|
|
269
|
+
properties: {
|
|
270
|
+
role: {
|
|
271
|
+
type: 'string',
|
|
272
|
+
enum: ['system', 'user', 'assistant'],
|
|
273
|
+
},
|
|
274
|
+
content: {
|
|
275
|
+
type: 'string',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
required: ['role', 'content'],
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
model: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
description: 'Model ID to use',
|
|
284
|
+
default: DEFAULT_CHAT_MODEL,
|
|
285
|
+
},
|
|
286
|
+
max_tokens: {
|
|
287
|
+
type: 'number',
|
|
288
|
+
default: 2048,
|
|
289
|
+
},
|
|
290
|
+
temperature: {
|
|
291
|
+
type: 'number',
|
|
292
|
+
default: 0.7,
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
required: ['messages'],
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: 'doubao_embeddings',
|
|
300
|
+
description: 'Generate text embeddings using Doubao embedding models. Useful for semantic search and RAG.',
|
|
301
|
+
inputSchema: {
|
|
302
|
+
type: 'object',
|
|
303
|
+
properties: {
|
|
304
|
+
texts: {
|
|
305
|
+
type: 'array',
|
|
306
|
+
description: 'Array of texts to embed',
|
|
307
|
+
items: { type: 'string' },
|
|
308
|
+
},
|
|
309
|
+
model: {
|
|
310
|
+
type: 'string',
|
|
311
|
+
description: 'Embedding model ID',
|
|
312
|
+
default: DEFAULT_EMBEDDING_MODEL,
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
required: ['texts'],
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: 'doubao_list_models',
|
|
320
|
+
description: 'List available Doubao models from Volcano Engine',
|
|
321
|
+
inputSchema: {
|
|
322
|
+
type: 'object',
|
|
323
|
+
properties: {},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
};
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// Handle tool calls
|
|
331
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
332
|
+
const { name, arguments: args } = request.params;
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
switch (name) {
|
|
336
|
+
case 'doubao_generate': {
|
|
337
|
+
const result = await generateText(args.prompt, {
|
|
338
|
+
model: args.model,
|
|
339
|
+
max_tokens: args.max_tokens,
|
|
340
|
+
temperature: args.temperature,
|
|
341
|
+
system_prompt: args.system_prompt,
|
|
342
|
+
});
|
|
343
|
+
return {
|
|
344
|
+
content: [
|
|
345
|
+
{
|
|
346
|
+
type: 'text',
|
|
347
|
+
text: JSON.stringify(result, null, 2),
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
case 'doubao_chat': {
|
|
354
|
+
const result = await chat(args.messages, {
|
|
355
|
+
model: args.model,
|
|
356
|
+
max_tokens: args.max_tokens,
|
|
357
|
+
temperature: args.temperature,
|
|
358
|
+
});
|
|
359
|
+
return {
|
|
360
|
+
content: [
|
|
361
|
+
{
|
|
362
|
+
type: 'text',
|
|
363
|
+
text: JSON.stringify(result, null, 2),
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
case 'doubao_embeddings': {
|
|
370
|
+
const result = await generateEmbeddings(args.texts, {
|
|
371
|
+
model: args.model,
|
|
372
|
+
});
|
|
373
|
+
return {
|
|
374
|
+
content: [
|
|
375
|
+
{
|
|
376
|
+
type: 'text',
|
|
377
|
+
text: JSON.stringify(result, null, 2),
|
|
378
|
+
},
|
|
379
|
+
],
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
case 'doubao_list_models': {
|
|
384
|
+
const result = listModels();
|
|
385
|
+
return {
|
|
386
|
+
content: [
|
|
387
|
+
{
|
|
388
|
+
type: 'text',
|
|
389
|
+
text: JSON.stringify(result, null, 2),
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
default:
|
|
396
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
397
|
+
}
|
|
398
|
+
} catch (error) {
|
|
399
|
+
return {
|
|
400
|
+
content: [
|
|
401
|
+
{
|
|
402
|
+
type: 'text',
|
|
403
|
+
text: `Error: ${error.message}`,
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
isError: true,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// Start server
|
|
412
|
+
async function main() {
|
|
413
|
+
const transport = new StdioServerTransport();
|
|
414
|
+
await server.connect(transport);
|
|
415
|
+
console.error('Volcano Engine MCP Server running on stdio');
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@purplesquirrel/volcengine-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for ByteDance Volcano Engine (Doubao) integration with Claude Code",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node index.js"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"mcp",
|
|
12
|
+
"volcano-engine",
|
|
13
|
+
"volcengine",
|
|
14
|
+
"bytedance",
|
|
15
|
+
"doubao",
|
|
16
|
+
"ai",
|
|
17
|
+
"llm"
|
|
18
|
+
],
|
|
19
|
+
"author": "Matthew Karsten",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@modelcontextprotocol/sdk": "^1.24.0"
|
|
23
|
+
}
|
|
24
|
+
}
|