update
This commit is contained in:
parent
7a6b857bae
commit
63fb5d3494
11
CHANGELOG.md
11
CHANGELOG.md
@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
## [main] 0.1.10
|
## [main] 0.1.10
|
||||||
- 修复 issue #48: 修复错误的引导路径。
|
- 修复 issue #48: 修复错误的引导路径。
|
||||||
- 完成引导界面的多语言。
|
|
||||||
- 支持 kimi 的 usage 计数 + 支持 kimi 的 system prompt。
|
- 支持 kimi 的 usage 计数 + 支持 kimi 的 system prompt。
|
||||||
- 实现 openmcp 工具测试的并行执行和暂停功能。
|
- 实现 openmcp 工具测试的并行执行和暂停功能。 https://picx.zhimg.com/80/v2-4e09958d91dcf561c578294d8b6f3349_1440w.png
|
||||||
- 修正 API 测速中算法,剥离为 tps + 排队时间两部分。
|
- 修正 API 测速中算法,剥离为 tps + 排队时间两部分。 https://picx.zhimg.com/80/v2-1cc3044a3ec3d5d21cb265dd67518ca0_1440w.png
|
||||||
- 大模型 api 测速目前可以自定义 prompt 了。
|
- 大模型 api 测速目前可以自定义 prompt 了。 https://picx.zhimg.com/80/v2-ff70af72254b82c11a941fe9cc29eeb8_1440w.png
|
||||||
- 实现 issue#49,工具模块,调试希望支持markdown渲染回显。
|
- 实现 issue#49,工具模块,调试希望支持markdown渲染回显。 https://picx.zhimg.com/80/v2-5d708ccab00f33fdf63a656a0066bf23_1440w.png
|
||||||
|
- 实现 issue#54,右击服务器列表名,可以重命名服务器。 https://picx.zhimg.com/80/v2-87c2a29abdd2dd56a4d18cc4a8b946ff_1440w.png
|
||||||
|
- 修复 resources 和 prompts 有关热更新的一些问题。
|
||||||
|
|
||||||
## [main] 0.1.9
|
## [main] 0.1.9
|
||||||
- 增加 mook 功能:可以利用随机种子或者AI生成来自动化填充测试 tool 的表单数据
|
- 增加 mook 功能:可以利用随机种子或者AI生成来自动化填充测试 tool 的表单数据
|
||||||
|
@ -16,5 +16,7 @@
|
|||||||
"comment-plugin": "Comment Plugin",
|
"comment-plugin": "Comment Plugin",
|
||||||
"preset-env-sync": "Preset environment variables synchronized successfully",
|
"preset-env-sync": "Preset environment variables synchronized successfully",
|
||||||
"preset-env-sync.fail": "Failed to sync preset environment variables",
|
"preset-env-sync.fail": "Failed to sync preset environment variables",
|
||||||
"error.notOpenWorkspace": "No workspace is currently open in VSCode. Please open a workspace (e.g., open a folder) first."
|
"error.notOpenWorkspace": "No workspace is currently open in VSCode. Please open a workspace (e.g., open a folder) first.",
|
||||||
|
"openmcp.sidebar.installed-connection.changeConnectionName.title": "Enter the new connection name",
|
||||||
|
"error.connectionNameRequired": "Server name cannot be empty"
|
||||||
}
|
}
|
@ -16,6 +16,6 @@
|
|||||||
"comment-plugin": "コメントプラグイン",
|
"comment-plugin": "コメントプラグイン",
|
||||||
"preset-env-sync": "プリセット環境変数の同期が完了しました",
|
"preset-env-sync": "プリセット環境変数の同期が完了しました",
|
||||||
"preset-env-sync.fail": "プリセット環境変数の同期に失敗しました",
|
"preset-env-sync.fail": "プリセット環境変数の同期に失敗しました",
|
||||||
"error.notOpenWorkspace": "現在、VSCode でワークスペースが開かれていません。まずワークスペース(例:フォルダーを開く)を開いてください。"
|
"openmcp.sidebar.installed-connection.changeConnectionName.title": "変更する接続名を入力してください",
|
||||||
|
"error.connectionNameRequired": "サーバー名は必須です"
|
||||||
}
|
}
|
@ -16,5 +16,7 @@
|
|||||||
"comment-plugin": "评论插件",
|
"comment-plugin": "评论插件",
|
||||||
"preset-env-sync": "预设环境变量同步完成",
|
"preset-env-sync": "预设环境变量同步完成",
|
||||||
"preset-env-sync.fail": "预设环境变量同步失败",
|
"preset-env-sync.fail": "预设环境变量同步失败",
|
||||||
"error.notOpenWorkspace": "当前VScode没有打开工作区,请先打开工作区(例如打开文件夹)"
|
"error.notOpenWorkspace": "当前VScode没有打开工作区,请先打开工作区(例如打开文件夹)",
|
||||||
|
"openmcp.sidebar.installed-connection.changeConnectionName.title": "输入修改的名称",
|
||||||
|
"error.connectionNameRequired": "服务器名称不能为空"
|
||||||
}
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon">
|
||||||
<link rel="stylesheet" href="/default-dark.css">
|
<link rel="stylesheet" href="/default-dark.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>OpenMCP News Feature</title>
|
<title>OpenMCP News Feature</title>
|
||||||
|
@ -1,73 +1,146 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
version: {
|
version: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '0.1.9'
|
default: '0.1.9'
|
||||||
},
|
},
|
||||||
changelogs: {
|
changelogs: {
|
||||||
type: Array as () => string[],
|
type: Array as () => string[],
|
||||||
default: () => [
|
default: () => [
|
||||||
'Brand new VSCode WebView adaptation, smoother experience',
|
'Brand new VSCode WebView adaptation, smoother experience https://example.com/image1.png',
|
||||||
'Support for AI Mock, toolchain visualization, and automatic topology detection',
|
'Support for AI Mock, toolchain visualization https://example.com/diagram.jpg and automatic topology detection',
|
||||||
'Multi-model concurrency, enhanced plugin capabilities'
|
'Multi-model concurrency, enhanced plugin capabilities https://example.com/arch.svg'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理变更日志,提取文本和图片
|
||||||
|
const processedChangelogs = computed(() => {
|
||||||
|
return props.changelogs.map(log => {
|
||||||
|
// 提取所有https图片链接
|
||||||
|
const imageRegex = /(https:\/\/[^\s]+?\.(?:png|jpg|jpeg|gif|svg|webp))/gi;
|
||||||
|
const images = [];
|
||||||
|
let match;
|
||||||
|
|
||||||
|
// 从文本中提取所有匹配的图片URL
|
||||||
|
while ((match = imageRegex.exec(log)) !== null) {
|
||||||
|
images.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从原始文本中移除图片URL
|
||||||
|
const text = log.replace(imageRegex, '').replace(/\s{2,}/g, ' ').trim();
|
||||||
|
|
||||||
|
return { text, images };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="news-section">
|
<section class="news-section">
|
||||||
<div class="news-title">
|
<div class="news-title">
|
||||||
<span>📣 What's New in <span class="highlight">{{ props.version }}</span></span>
|
<span>📣 What's New in <span class="highlight">{{ props.version }}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="news-content">
|
<div class="news-content">
|
||||||
<ul class="news-list">
|
<ul class="news-list">
|
||||||
<li v-for="(log, index) in props.changelogs" :key="index">
|
<li v-for="(item, index) in processedChangelogs" :key="index">
|
||||||
<span class="news-badge">{{ '/' }}</span>
|
<span class="news-badge">{{ '/' }}</span>
|
||||||
<span>{{ log }}</span>
|
<div class="log-content">
|
||||||
</li>
|
<span>{{ item.text }}</span>
|
||||||
</ul>
|
<div v-if="item.images.length" class="image-container">
|
||||||
<br>
|
<a v-for="(img, imgIndex) in item.images" :key="imgIndex" :href="img" target="_blank" rel="noopener">
|
||||||
<a class="release-link" href="https://openmcp.kirigaya.cn/preview/changelog.html" target="_blank"
|
<img :src="img" alt="Changelog image" class="changelog-image" />
|
||||||
rel="noopener">View History Changelog →</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
<a class="release-link" href="https://openmcp.kirigaya.cn/preview/changelog.html" target="_blank"
|
||||||
|
rel="noopener">View History Changelog →</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.news-section {
|
.news-section {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-title {
|
.news-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #B988D1;
|
color: #B988D1;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-title .logo {
|
.news-title .logo {
|
||||||
width: 38px;
|
width: 38px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-title .highlight {
|
.news-title .highlight {
|
||||||
color: #B988D1;
|
color: #B988D1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-content {
|
.news-content {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
background-color: var(--vscode-sideBar-background);
|
background-color: var(--vscode-sideBar-background);
|
||||||
box-shadow: 0 2px 8px var(--vscode-widget-shadow);
|
box-shadow: 0 2px 8px var(--vscode-widget-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-content li {
|
.news-content li {
|
||||||
margin-bottom: 0.7rem;
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-badge {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 10px;
|
||||||
|
color: #B988D1;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog-image {
|
||||||
|
max-height: 250px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--vscode-widget-border);
|
||||||
|
object-fit: contain;
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
padding: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.release-link {
|
||||||
|
color: #B988D1;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -3,8 +3,8 @@
|
|||||||
"changelogs": [
|
"changelogs": [
|
||||||
"Add mook functionality: Automatically fill in test tool form data using random seeds or AI generation.",
|
"Add mook functionality: Automatically fill in test tool form data using random seeds or AI generation.",
|
||||||
"Add tool self-check functionality: Under openmcp's tool, click 'Tool Self-Check' on the right side of 'Tool Module' to enter self-check mode. In this mode, users can define the topological order of tool execution and perform automatic detection in one go.",
|
"Add tool self-check functionality: Under openmcp's tool, click 'Tool Self-Check' on the right side of 'Tool Module' to enter self-check mode. In this mode, users can define the topological order of tool execution and perform automatic detection in one go.",
|
||||||
"Fix issue #44: Complete platform adaptation for link redirection.",
|
"Fix issue #44: Complete platform adaptation for link redirection. https://picx.zhimg.com/80/v2-87c2a29abdd2dd56a4d18cc4a8b946ff_1440w.png",
|
||||||
"Fix issue #36: Ensure successful startup when not opening a folder.",
|
"Fix issue #36: Ensure successful startup when not opening a folder. https://picx.zhimg.com/80/v2-87c2a29abdd2dd56a4d18cc4a8b946ff_1440w.png",
|
||||||
"Fix issue #45: Array type parameters are not supported.",
|
"Fix issue #45: Array type parameters are not supported.",
|
||||||
"Fix the issue of abnormal dialog styles when pasting multi-line conversations into the dialog box."
|
"Fix the issue of abnormal dialog styles when pasting multi-line conversations into the dialog box."
|
||||||
],
|
],
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "openmcp",
|
"name": "openmcp",
|
||||||
"displayName": "OpenMCP",
|
"displayName": "OpenMCP",
|
||||||
"description": "An all in one MCP Client/TestTool",
|
"description": "An all in one MCP Client/TestTool",
|
||||||
"version": "0.1.9",
|
"version": "0.1.10",
|
||||||
"publisher": "kirigaya",
|
"publisher": "kirigaya",
|
||||||
"private": true,
|
"private": true,
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<h3 class="resource-template">
|
<h3 class="resource-template">
|
||||||
<span>resources/templates/list</span>
|
<span>resources/templates/list</span>
|
||||||
<span class="iconfont icon-restart" @click="reloadResources(client, { first: false })"></span>
|
<span class="iconfont icon-restart" @click.stop="reloadResources(client, { first: false })"></span>
|
||||||
</h3>
|
</h3>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<h3 class="resource-template">
|
<h3 class="resource-template">
|
||||||
<span>resources/list</span>
|
<span>resources/list</span>
|
||||||
<span class="iconfont icon-restart" @click="reloadResources(client, { first: false })"></span>
|
<span class="iconfont icon-restart" @click.stop="reloadResources(client, { first: false })"></span>
|
||||||
</h3>
|
</h3>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -282,7 +282,6 @@ export class McpClient {
|
|||||||
this.resourceTemplates = new Map<string, ResourceTemplate>();
|
this.resourceTemplates = new Map<string, ResourceTemplate>();
|
||||||
msg.resourceTemplates.forEach(template => {
|
msg.resourceTemplates.forEach(template => {
|
||||||
this.resourceTemplates!.set(template.name, template);
|
this.resourceTemplates!.set(template.name, template);
|
||||||
|
|
||||||
});
|
});
|
||||||
return this.resourceTemplates;
|
return this.resourceTemplates;
|
||||||
}
|
}
|
||||||
@ -496,7 +495,7 @@ export class McpClient {
|
|||||||
|
|
||||||
|
|
||||||
class McpClientAdapter {
|
class McpClientAdapter {
|
||||||
public clients: Reactive<McpClient[]> = [];
|
public clients: Reactive<McpClient[]> = reactive([]);
|
||||||
public currentClientIndex: number = 0;
|
public currentClientIndex: number = 0;
|
||||||
public refreshSignal = reactive({ value: 0 });
|
public refreshSignal = reactive({ value: 0 });
|
||||||
|
|
||||||
@ -586,7 +585,9 @@ class McpClientAdapter {
|
|||||||
console.log('clientIndex', clientIndex);
|
console.log('clientIndex', clientIndex);
|
||||||
|
|
||||||
await this.clients[clientIndex].refreshAllResources();
|
await this.clients[clientIndex].refreshAllResources();
|
||||||
this.refreshSignal.value++;
|
|
||||||
|
// 更新 refreshSignal,所有 watch refreshSignal 的部分会发生更新
|
||||||
|
this.refreshSignal.value ++;
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
chalk.gray(`[${new Date().toLocaleString()}]`),
|
chalk.gray(`[${new Date().toLocaleString()}]`),
|
||||||
|
@ -44,6 +44,7 @@ export class McpServerConnectMonitor {
|
|||||||
|
|
||||||
switch (options.connectionType) {
|
switch (options.connectionType) {
|
||||||
case 'STDIO':
|
case 'STDIO':
|
||||||
|
console.log('monitor on ' + this.filePath);
|
||||||
this.setupStdioMonitor(onchange);
|
this.setupStdioMonitor(onchange);
|
||||||
break;
|
break;
|
||||||
case 'SSE':
|
case 'SSE':
|
||||||
@ -64,8 +65,6 @@ export class McpServerConnectMonitor {
|
|||||||
try {
|
try {
|
||||||
await onchange(this.uuid, this.Options);
|
await onchange(this.uuid, this.Options);
|
||||||
|
|
||||||
console.log('send something');
|
|
||||||
|
|
||||||
this.sendWebviewMessage('connect/refresh', {
|
this.sendWebviewMessage('connect/refresh', {
|
||||||
code: 200,
|
code: 200,
|
||||||
msg: {
|
msg: {
|
||||||
|
@ -25,6 +25,21 @@ export async function updateClientMap(uuid: string, options: McpOptions): Promis
|
|||||||
chalk.white('update client tools'),
|
chalk.white('update client tools'),
|
||||||
chalk.blue(tools.tools.map(tool => tool.name).join(','))
|
chalk.blue(tools.tools.map(tool => tool.name).join(','))
|
||||||
);
|
);
|
||||||
|
const resourceTemplates = await client.listResourceTemplates();
|
||||||
|
console.log(
|
||||||
|
chalk.white('update client resourceTemplates'),
|
||||||
|
chalk.blue(resourceTemplates.resourceTemplates.map(r => r.name).join(','))
|
||||||
|
);
|
||||||
|
const resources = await client.listResources();
|
||||||
|
console.log(
|
||||||
|
chalk.white('update client resources'),
|
||||||
|
chalk.blue(resources.resources.map(r => r.name).join(','))
|
||||||
|
);
|
||||||
|
const prompts = await client.listPrompts();
|
||||||
|
console.log(
|
||||||
|
chalk.white('update client prompts'),
|
||||||
|
chalk.blue(prompts.prompts.map(p => p.name).join(','))
|
||||||
|
);
|
||||||
return { res: true };
|
return { res: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[updateClientMap] error:', error);
|
console.error('[updateClientMap] error:', error);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"clientId": "ea2b1e70-1e70-5b1e705a3ac-8b1e705a3ac8921-c8921324",
|
"clientId": "27a62b3c-2b3c-562b3c408e5-862b3c408e5800e-5800ec5e",
|
||||||
"currentIndex": 1,
|
"currentIndex": 0,
|
||||||
"tabs": [
|
"tabs": [
|
||||||
{
|
{
|
||||||
"name": "工具",
|
"name": "工具",
|
||||||
@ -42,7 +42,11 @@
|
|||||||
],
|
],
|
||||||
"isError": false
|
"isError": false
|
||||||
},
|
},
|
||||||
"currentPromptName": "translate"
|
"currentPromptName": "translate",
|
||||||
|
"autoDetectDiagram": {
|
||||||
|
"edges": [],
|
||||||
|
"views": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -410,322 +414,6 @@
|
|||||||
},
|
},
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "k_get_full_page_text",
|
|
||||||
"description": "获取页面所有文本内容",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {}
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_navigate",
|
|
||||||
"description": "Navigate to a URL",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"url": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "URL to navigate to"
|
|
||||||
},
|
|
||||||
"launchOptions": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: { headless: true, args: ['--no-sandbox'] }"
|
|
||||||
},
|
|
||||||
"allowDangerous": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Allow dangerous LaunchOptions that reduce security. When false, dangerous args like --no-sandbox will throw errors. Default false."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"url"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_screenshot",
|
|
||||||
"description": "Take a screenshot of the current page or a specific element",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Name for the screenshot"
|
|
||||||
},
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to screenshot"
|
|
||||||
},
|
|
||||||
"width": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Width in pixels (default: 800)"
|
|
||||||
},
|
|
||||||
"height": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Height in pixels (default: 600)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_click",
|
|
||||||
"description": "Click an element on the page",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to click"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_fill",
|
|
||||||
"description": "Fill out an input field",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for input field"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Value to fill"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector",
|
|
||||||
"value"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_select",
|
|
||||||
"description": "Select an element on the page with Select tag",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to select"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Value to select"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector",
|
|
||||||
"value"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_hover",
|
|
||||||
"description": "Hover an element on the page",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to hover"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_evaluate",
|
|
||||||
"description": "Execute JavaScript in the browser console",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"script": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "JavaScript code to execute"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"script"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_get_full_page_text",
|
|
||||||
"description": "获取页面所有文本内容",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {}
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_navigate",
|
|
||||||
"description": "Navigate to a URL",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"url": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "URL to navigate to"
|
|
||||||
},
|
|
||||||
"launchOptions": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: { headless: true, args: ['--no-sandbox'] }"
|
|
||||||
},
|
|
||||||
"allowDangerous": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Allow dangerous LaunchOptions that reduce security. When false, dangerous args like --no-sandbox will throw errors. Default false."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"url"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_screenshot",
|
|
||||||
"description": "Take a screenshot of the current page or a specific element",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Name for the screenshot"
|
|
||||||
},
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to screenshot"
|
|
||||||
},
|
|
||||||
"width": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Width in pixels (default: 800)"
|
|
||||||
},
|
|
||||||
"height": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Height in pixels (default: 600)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_click",
|
|
||||||
"description": "Click an element on the page",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to click"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_fill",
|
|
||||||
"description": "Fill out an input field",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for input field"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Value to fill"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector",
|
|
||||||
"value"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_select",
|
|
||||||
"description": "Select an element on the page with Select tag",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to select"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Value to select"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector",
|
|
||||||
"value"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_hover",
|
|
||||||
"description": "Hover an element on the page",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"selector": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "CSS selector for element to hover"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"selector"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "k_evaluate",
|
|
||||||
"description": "Execute JavaScript in the browser console",
|
|
||||||
"inputSchema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"script": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "JavaScript code to execute"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"script"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "k_get_full_page_text",
|
"name": "k_get_full_page_text",
|
||||||
"description": "获取页面所有文本内容",
|
"description": "获取页面所有文本内容",
|
||||||
|
@ -39,6 +39,7 @@ export interface McpOptions {
|
|||||||
name?: string;
|
name?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
type?: ConnectionType;
|
type?: ConnectionType;
|
||||||
|
rename?: boolean;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
@ -152,8 +153,7 @@ export function getWorkspaceConnectionConfig():IConnectionConfig| null {
|
|||||||
|
|
||||||
const workspacePath = getWorkspacePath();
|
const workspacePath = getWorkspacePath();
|
||||||
for (let item of connection.items) {
|
for (let item of connection.items) {
|
||||||
const connections = Array.isArray(item) ? item : [item];
|
for (let connection of detachMcpOptionAsArray(item)) {
|
||||||
for (let connection of connections) {
|
|
||||||
const connectionType = (connection.type || connection.connectionType).toUpperCase() as ConnectionType;
|
const connectionType = (connection.type || connection.connectionType).toUpperCase() as ConnectionType;
|
||||||
connection.type = undefined;
|
connection.type = undefined;
|
||||||
connection.connectionType = connectionType;
|
connection.connectionType = connectionType;
|
||||||
@ -205,8 +205,9 @@ export function saveWorkspaceConnectionConfig(workspace: string) {
|
|||||||
|
|
||||||
const workspacePath = getWorkspacePath();
|
const workspacePath = getWorkspacePath();
|
||||||
for (let item of connectionConfig.items) {
|
for (let item of connectionConfig.items) {
|
||||||
const connections = Array.isArray(item) ? item : [item];
|
for (let connection of detachMcpOptionAsArray(item)) {
|
||||||
for (let connection of connections) {
|
console.log(connection);
|
||||||
|
|
||||||
const connectionType = (connection.type || connection.connectionType).toUpperCase() as ConnectionType;
|
const connectionType = (connection.type || connection.connectionType).toUpperCase() as ConnectionType;
|
||||||
connection.type = undefined;
|
connection.type = undefined;
|
||||||
connection.connectionType = connectionType;
|
connection.connectionType = connectionType;
|
||||||
@ -245,20 +246,22 @@ export function updateWorkspaceConnectionConfig(
|
|||||||
|
|
||||||
// 如果存在,替换老的 connectionItem
|
// 如果存在,替换老的 connectionItem
|
||||||
if (connectionItem) {
|
if (connectionItem) {
|
||||||
console.log("存在的 connection")
|
|
||||||
const index = workspaceConnectionConfig.items.indexOf(connectionItem);
|
const index = workspaceConnectionConfig.items.indexOf(connectionItem);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
// 替换现有项目而不是删除后插入到开头
|
// check rename value
|
||||||
console.log("替换现有项目而不是删除后插入到开头")
|
const oldNItem = detachMcpOptionAsItem(workspaceConnectionConfig.items[index]);
|
||||||
|
if (oldNItem.rename) {
|
||||||
|
// if renamed, reserve user defined name
|
||||||
|
const newNItem = detachMcpOptionAsItem(data);
|
||||||
|
newNItem.name = oldNItem.name;
|
||||||
|
}
|
||||||
|
|
||||||
workspaceConnectionConfig.items[index] = data;
|
workspaceConnectionConfig.items[index] = data;
|
||||||
} else {
|
} else {
|
||||||
// 如果索引查找失败,则插入到第一个
|
// insert new one
|
||||||
console.log("没有找到现有项目,插入到第一个")
|
|
||||||
workspaceConnectionConfig.items.unshift(data);
|
workspaceConnectionConfig.items.unshift(data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 没有找到现有项目,插入到第一个
|
|
||||||
console.log("没有找到现有项目,插入到第一个")
|
|
||||||
workspaceConnectionConfig.items.unshift(data);
|
workspaceConnectionConfig.items.unshift(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,18 +289,14 @@ export function updateInstalledConnectionConfig(
|
|||||||
|
|
||||||
console.log('get connectionItem: ', data);
|
console.log('get connectionItem: ', data);
|
||||||
|
|
||||||
// 如果存在,替换老的 connectionItem
|
|
||||||
if (connectionItem) {
|
if (connectionItem) {
|
||||||
const index = installedConnectionConfig.items.indexOf(connectionItem);
|
const index = installedConnectionConfig.items.indexOf(connectionItem);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
// 替换现有项目而不是删除后插入到开头
|
|
||||||
installedConnectionConfig.items[index] = data;
|
installedConnectionConfig.items[index] = data;
|
||||||
} else {
|
} else {
|
||||||
// 如果索引查找失败,则插入到第一个
|
|
||||||
installedConnectionConfig.items.unshift(data);
|
installedConnectionConfig.items.unshift(data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 没有找到现有项目,插入到第一个
|
|
||||||
installedConnectionConfig.items.unshift(data);
|
installedConnectionConfig.items.unshift(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +337,7 @@ export function getWorkspaceConnectionConfigItemByPath(absPath: string) {
|
|||||||
|
|
||||||
const normaliseAbsPath = absPath.replace(/\\/g, '/');
|
const normaliseAbsPath = absPath.replace(/\\/g, '/');
|
||||||
for (let item of workspaceConnectionConfig.items) {
|
for (let item of workspaceConnectionConfig.items) {
|
||||||
const nItem = Array.isArray(item) ? item[0] : item;
|
const nItem = detachMcpOptionAsItem(item);
|
||||||
|
|
||||||
const filePath = normaliseConnectionFilePath(nItem, workspacePath);
|
const filePath = normaliseConnectionFilePath(nItem, workspacePath);
|
||||||
if (filePath === normaliseAbsPath) {
|
if (filePath === normaliseAbsPath) {
|
||||||
@ -359,7 +358,7 @@ export function getWorkspaceConnectionConfigItemByName(name: string) {
|
|||||||
return null; // 如果没有工作区连接配置文件,则返回 null
|
return null; // 如果没有工作区连接配置文件,则返回 null
|
||||||
}
|
}
|
||||||
for (let item of workspaceConnectionConfig.items) {
|
for (let item of workspaceConnectionConfig.items) {
|
||||||
const nItem = Array.isArray(item) ? item[0] : item;
|
const nItem = detachMcpOptionAsItem(item);
|
||||||
if (nItem.name === name) {
|
if (nItem.name === name) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -376,7 +375,7 @@ export function getInstalledConnectionConfigItemByName(name: string) {
|
|||||||
const installedConnectionConfig = getConnectionConfig();
|
const installedConnectionConfig = getConnectionConfig();
|
||||||
|
|
||||||
for (let item of installedConnectionConfig.items) {
|
for (let item of installedConnectionConfig.items) {
|
||||||
const nItem = Array.isArray(item) ? item[0] : item;
|
const nItem = detachMcpOptionAsItem(item);
|
||||||
|
|
||||||
if (nItem.name) {
|
if (nItem.name) {
|
||||||
return item;
|
return item;
|
||||||
@ -396,7 +395,7 @@ export function getInstalledConnectionConfigItemByPath(absPath: string) {
|
|||||||
|
|
||||||
const normaliseAbsPath = absPath.replace(/\\/g, '/');
|
const normaliseAbsPath = absPath.replace(/\\/g, '/');
|
||||||
for (let item of installedConnectionConfig.items) {
|
for (let item of installedConnectionConfig.items) {
|
||||||
const nItem = Array.isArray(item) ? item[0] : item;
|
const nItem = detachMcpOptionAsItem(item);
|
||||||
|
|
||||||
const filePath = (nItem.filePath || '').replace(/\\/g, '/');
|
const filePath = (nItem.filePath || '').replace(/\\/g, '/');
|
||||||
if (filePath === normaliseAbsPath) {
|
if (filePath === normaliseAbsPath) {
|
||||||
@ -449,3 +448,11 @@ export async function exportFile(filename: string, content: any) {
|
|||||||
fs.writeFileSync(uri.fsPath, content, 'utf-8');
|
fs.writeFileSync(uri.fsPath, content, 'utf-8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function detachMcpOptionAsItem(data: McpOptions | McpOptions[]): McpOptions {
|
||||||
|
return Array.isArray(data) ? data[0] : data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function detachMcpOptionAsArray(data: McpOptions | McpOptions[]): McpOptions[] {
|
||||||
|
return Array.isArray(data) ? data : [data];
|
||||||
|
}
|
@ -71,15 +71,13 @@ export async function changeInstalledConnectionName(item: McpOptions[] | McpOpti
|
|||||||
|
|
||||||
// 更新连接名称
|
// 更新连接名称
|
||||||
masterNode.name = newName.trim();
|
masterNode.name = newName.trim();
|
||||||
|
masterNode.rename = true;
|
||||||
|
|
||||||
// 保存更新后的配置
|
// 保存更新后的配置
|
||||||
saveConnectionConfig();
|
saveConnectionConfig();
|
||||||
|
|
||||||
// 刷新侧边栏视图
|
// 刷新侧边栏视图
|
||||||
vscode.commands.executeCommand('openmcp.sidebar.installed-connection.refresh');
|
vscode.commands.executeCommand('openmcp.sidebar.installed-connection.refresh');
|
||||||
|
|
||||||
// 显示成功消息
|
|
||||||
vscode.window.showInformationMessage(t('connectionNameChanged', currentName, newName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function acquireInstalledConnection(): Promise<McpOptions[]> {
|
export async function acquireInstalledConnection(): Promise<McpOptions[]> {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { getFirstValidPathFromCommand, getWorkspaceConnectionConfig, getWorkspacePath, McpOptions, panels, saveWorkspaceConnectionConfig } from "../global.js";
|
import { getFirstValidPathFromCommand, getWorkspaceConnectionConfig, getWorkspacePath, McpOptions, panels, saveWorkspaceConnectionConfig } from "../global.js";
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { t } from "../i18n/index.js";
|
import { t } from "../i18n/index.js";
|
||||||
import { promisify } from 'util';
|
|
||||||
import { spawn } from 'node:child_process';
|
|
||||||
|
|
||||||
export async function deleteUserConnection(item: McpOptions[] | McpOptions) {
|
export async function deleteUserConnection(item: McpOptions[] | McpOptions) {
|
||||||
// 弹出确认对话框
|
// 弹出确认对话框
|
||||||
@ -80,16 +78,16 @@ export async function changeUserConnectionName(item: McpOptions[] | McpOptions)
|
|||||||
|
|
||||||
// 更新连接名称
|
// 更新连接名称
|
||||||
masterNode.name = newName.trim();
|
masterNode.name = newName.trim();
|
||||||
|
masterNode.rename = true;
|
||||||
|
|
||||||
|
vscode.window.showInformationMessage('enter here');
|
||||||
|
|
||||||
// 保存更新后的配置
|
// 保存更新后的配置
|
||||||
const workspacePath = getWorkspacePath();
|
const workspacePath = getWorkspacePath();
|
||||||
await saveWorkspaceConnectionConfig(workspacePath);
|
saveWorkspaceConnectionConfig(workspacePath);
|
||||||
|
|
||||||
// 刷新侧边栏视图
|
// 刷新侧边栏视图
|
||||||
vscode.commands.executeCommand('openmcp.sidebar.workspace-connection.refresh');
|
vscode.commands.executeCommand('openmcp.sidebar.workspace-connection.refresh');
|
||||||
|
|
||||||
// 显示成功消息
|
|
||||||
vscode.window.showInformationMessage(t('connectionNameChanged', currentName, newName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function acquireUserCustomConnection(): Promise<McpOptions[]> {
|
export async function acquireUserCustomConnection(): Promise<McpOptions[]> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user