opt layout
This commit is contained in:
parent
c964f79c99
commit
c8a9951be6
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"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.0.1",
|
"version": "0.0.1",
|
||||||
|
"publisher": "kirigaya",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "kirigaya",
|
"name": "kirigaya",
|
||||||
"email": "1193466151@qq.com"
|
"email": "1193466151@qq.com"
|
||||||
@ -19,7 +20,7 @@
|
|||||||
],
|
],
|
||||||
"activationEvents": [],
|
"activationEvents": [],
|
||||||
"main": "./dist/extension.js",
|
"main": "./dist/extension.js",
|
||||||
"icon": "./icons/openmcp.png",
|
"icon": "icons/openmcp.png",
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 4870215 */
|
font-family: "iconfont"; /* Project id 4870215 */
|
||||||
src: url('iconfont.woff2?t=1744289078529') format('woff2'),
|
src: url('iconfont.woff2?t=1744476757936') format('woff2'),
|
||||||
url('iconfont.woff?t=1744289078529') format('woff'),
|
url('iconfont.woff?t=1744476757936') format('woff'),
|
||||||
url('iconfont.ttf?t=1744289078529') format('truetype');
|
url('iconfont.ttf?t=1744476757936') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -13,6 +13,10 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-connect:before {
|
||||||
|
content: "\ecda";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-openmcp:before {
|
.icon-openmcp:before {
|
||||||
content: "\e666";
|
content: "\e666";
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -14,7 +14,7 @@ import MainPanel from '@/components/main-panel/index.vue';
|
|||||||
import { setDefaultCss } from './hook/css';
|
import { setDefaultCss } from './hook/css';
|
||||||
import { pinkLog } from './views/setting/util';
|
import { pinkLog } from './views/setting/util';
|
||||||
import { acquireVsCodeApi, useMessageBridge } from './api/message-bridge';
|
import { acquireVsCodeApi, useMessageBridge } from './api/message-bridge';
|
||||||
import { connectionArgs, connectionMethods, connectionResult, doConnect, launchConnect } from './views/connect/connection';
|
import { connectionArgs, connectionMethods, connectionResult, doConnect, getServerVersion, launchConnect } from './views/connect/connection';
|
||||||
import { loadSetting } from './hook/setting';
|
import { loadSetting } from './hook/setting';
|
||||||
import { loadPanels } from './hook/panel';
|
import { loadPanels } from './hook/panel';
|
||||||
|
|
||||||
@ -26,16 +26,24 @@ bridge.addCommandListener('hello', data => {
|
|||||||
pinkLog(`version: ${data.version}`);
|
pinkLog(`version: ${data.version}`);
|
||||||
}, { once: true });
|
}, { once: true });
|
||||||
|
|
||||||
|
// 监听 connect
|
||||||
|
bridge.addCommandListener('connect', async data => {
|
||||||
|
const { code, msg } = data;
|
||||||
|
connectionResult.success = (code === 200);
|
||||||
|
connectionResult.logString = msg;
|
||||||
|
|
||||||
|
const res = await getServerVersion() as { name: string, version: string };
|
||||||
|
connectionResult.serverInfo.name = res.name || '';
|
||||||
|
connectionResult.serverInfo.version = res.version || '';
|
||||||
|
|
||||||
|
}, { once: true });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function initDebug() {
|
function initDebug() {
|
||||||
connectionArgs.commandString = 'mcp run ../servers/main.py';
|
connectionArgs.commandString = 'mcp run ../servers/main.py';
|
||||||
connectionMethods.current = 'STDIO';
|
connectionMethods.current = 'STDIO';
|
||||||
|
|
||||||
bridge.addCommandListener('connect', data => {
|
|
||||||
const { code, msg } = data;
|
|
||||||
connectionResult.success = (code === 200);
|
|
||||||
connectionResult.logString = msg;
|
|
||||||
}, { once: true });
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 初始化 设置
|
// 初始化 设置
|
||||||
loadSetting();
|
loadSetting();
|
||||||
@ -56,12 +64,6 @@ function initProduce() {
|
|||||||
connectionArgs.commandString = 'mcp run ../servers/main.py';
|
connectionArgs.commandString = 'mcp run ../servers/main.py';
|
||||||
connectionMethods.current = 'STDIO';
|
connectionMethods.current = 'STDIO';
|
||||||
|
|
||||||
bridge.addCommandListener('connect', data => {
|
|
||||||
const { code, msg } = data;
|
|
||||||
connectionResult.success = (code === 200);
|
|
||||||
connectionResult.logString = msg;
|
|
||||||
}, { once: true });
|
|
||||||
|
|
||||||
// 初始化 设置
|
// 初始化 设置
|
||||||
loadSetting();
|
loadSetting();
|
||||||
|
|
||||||
|
@ -2,12 +2,24 @@
|
|||||||
<div class="connected-status-container"
|
<div class="connected-status-container"
|
||||||
@click.stop="toggleConnectionPanel()"
|
@click.stop="toggleConnectionPanel()"
|
||||||
>
|
>
|
||||||
<span
|
<span class="mcp-server-info">
|
||||||
class="status-circle"
|
<el-tooltip
|
||||||
:class="statusColorStyle"
|
class="extra-connect-container"
|
||||||
|
effect="dark"
|
||||||
|
placement="right"
|
||||||
|
:content="fullDisplayServerName"
|
||||||
>
|
>
|
||||||
|
<span class="name">{{ displayServerName }}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
<span class="connect-status">
|
||||||
|
<span
|
||||||
|
class="status-circle"
|
||||||
|
:class="statusColorStyle"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
<span class="status-string">{{ statusString }}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="status-string">{{ statusString }}</span>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -38,7 +50,17 @@ const statusColorStyle = computed(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fullDisplayServerName = computed(() => {
|
||||||
|
return connectionResult.serverInfo.name + '/' + connectionResult.serverInfo.version;
|
||||||
|
});
|
||||||
|
|
||||||
|
const displayServerName = computed(() => {
|
||||||
|
if (connectionResult.serverInfo.name.length > 20) {
|
||||||
|
return connectionResult.serverInfo.name.substring(0, 20);
|
||||||
|
} else {
|
||||||
|
return connectionResult.serverInfo.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function toggleConnectionPanel() {
|
function toggleConnectionPanel() {
|
||||||
Connection.showPanel = true;
|
Connection.showPanel = true;
|
||||||
@ -59,27 +81,65 @@ function toggleConnectionPanel() {
|
|||||||
.status-circle {
|
.status-circle {
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
margin-right: 10px;
|
margin-right: 8px;
|
||||||
border-radius: 99%;
|
border-radius: 99%;
|
||||||
|
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-connect-container {
|
.extra-connect-container {
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.connected-status-container {
|
.connected-status-container {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: auto;
|
||||||
justify-content: center;
|
padding: 8px 0;
|
||||||
|
flex-direction: column;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.connected-status-container:hover .status-string {
|
.connected-status-container .connect-status {
|
||||||
color: var(--main-color);
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connected-status-container:hover {
|
||||||
|
background-color: var(--sidebar-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.status-string {
|
||||||
|
color: var(--foreground);
|
||||||
transition: var(--animation-3s);
|
transition: var(--animation-3s);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mcp-server-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mcp-server-info .name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
max-width: 60px;
|
||||||
|
white-space: wrap;
|
||||||
|
background-color: #f39a6d;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: .5em;
|
||||||
|
color: #1e1e1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mcp-server-info .version {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -2,8 +2,6 @@
|
|||||||
<div class="sidebar-container">
|
<div class="sidebar-container">
|
||||||
<div>
|
<div>
|
||||||
<McpTitle></McpTitle>
|
<McpTitle></McpTitle>
|
||||||
<hr>
|
|
||||||
<br>
|
|
||||||
<SidebarItemContainer></SidebarItemContainer>
|
<SidebarItemContainer></SidebarItemContainer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -15,7 +13,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { sidebarItems } from './sidebar';
|
|
||||||
|
|
||||||
import McpTitle from './mcp-title.vue';
|
import McpTitle from './mcp-title.vue';
|
||||||
import SidebarItemContainer from './sidebar-item-container.vue';
|
import SidebarItemContainer from './sidebar-item-container.vue';
|
||||||
@ -27,7 +24,7 @@ defineComponent({ name: 'sidebar' });
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
width: 300px;
|
width: fit-content;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mcp-title">
|
<div class="mcp-title">
|
||||||
<div class="openmcp-logo" style="width: 48px; height: 48px; margin-right: 10px;"></div>
|
<div class="openmcp-logo" style="width: 48px; height: 48px; margin-top: 10px; margin-bottom: 15px; margin-right: 10px;"></div>
|
||||||
<div>OpenMCP</div>
|
<!-- <div>OpenMCP</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sidebar-item-container">
|
<div class="sidebar-item-container">
|
||||||
<div
|
<div v-for="(item, index) of sidebarItems" :key="index">
|
||||||
class="sidebar-option-item"
|
<el-tooltip :content="t(item.ident)" placement="right">
|
||||||
:class="{'active': isActive(item.ident)}"
|
<div class="sidebar-option-item" :class="{ 'active': isActive(item.ident) }"
|
||||||
v-for="(item, index) of sidebarItems"
|
@click="gotoOption(item.ident)">
|
||||||
:key="index"
|
<span :class="`iconfont ${item.icon}`"></span>
|
||||||
@click="gotoOption(item.ident)"
|
</div>
|
||||||
>
|
</el-tooltip>
|
||||||
<span :class="`iconfont ${item.icon}`"></span>
|
|
||||||
<span>{{ t(item.ident) }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -43,6 +41,7 @@ function gotoOption(ident: string) {
|
|||||||
.sidebar-option-item {
|
.sidebar-option-item {
|
||||||
margin: 7px;
|
margin: 7px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
width: fit-content;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 5px 12px;
|
padding: 5px 12px;
|
||||||
@ -58,8 +57,11 @@ function gotoOption(ident: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-option-item .iconfont {
|
.sidebar-option-item .iconfont {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
|
width: 13px;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,5 +69,4 @@ function gotoOption(ident: string) {
|
|||||||
background-color: var(--main-light-color);
|
background-color: var(--main-light-color);
|
||||||
transition: var(--animation-3s);
|
transition: var(--animation-3s);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -6,7 +6,7 @@ export const sidebarItems = reactive([
|
|||||||
ident: 'debug'
|
ident: 'debug'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'icon-plugin',
|
icon: 'icon-connect',
|
||||||
ident: 'connect'
|
ident: 'connect'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -162,5 +162,26 @@ export function doReconnect() {
|
|||||||
|
|
||||||
export const connectionResult = reactive({
|
export const connectionResult = reactive({
|
||||||
success: false,
|
success: false,
|
||||||
logString: ''
|
logString: '',
|
||||||
|
serverInfo: {
|
||||||
|
name: '',
|
||||||
|
version: ''
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function getServerVersion() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const bridge = useMessageBridge();
|
||||||
|
bridge.addCommandListener('server/version', data => {
|
||||||
|
if (data.code === 200) {
|
||||||
|
resolve(data.msg);
|
||||||
|
} else {
|
||||||
|
reject(data.msg);
|
||||||
|
}
|
||||||
|
}, { once: true });
|
||||||
|
|
||||||
|
bridge.postMessage({
|
||||||
|
command: 'server/version',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -72,9 +72,14 @@ export class MCPClient {
|
|||||||
console.log(`Connected to MCP server via ${this.options.connectionType}`);
|
console.log(`Connected to MCP server via ${this.options.connectionType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getServerVersion() {
|
||||||
|
return this.client.getServerVersion();
|
||||||
|
}
|
||||||
|
|
||||||
// 断开连接
|
// 断开连接
|
||||||
public async disconnect(): Promise<void> {
|
public async disconnect(): Promise<void> {
|
||||||
await this.client.close();
|
await this.client.close();
|
||||||
|
|
||||||
console.log('Disconnected from MCP server');
|
console.log('Disconnected from MCP server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,3 +253,32 @@ export async function callTool(
|
|||||||
webview.postMessage({ command: 'tools/call', data: result });
|
webview.postMessage({ command: 'tools/call', data: result });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getServerVersion(
|
||||||
|
client: MCPClient | undefined,
|
||||||
|
webview: PostMessageble
|
||||||
|
) {
|
||||||
|
if (!client) {
|
||||||
|
const connectResult = {
|
||||||
|
code: 501,
|
||||||
|
msg:'mcp client 尚未连接'
|
||||||
|
};
|
||||||
|
webview.postMessage({ command: 'server/version', data: connectResult });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const version = client.getServerVersion();
|
||||||
|
const result = {
|
||||||
|
code: 200,
|
||||||
|
msg: version
|
||||||
|
};
|
||||||
|
webview.postMessage({ command:'server/version', data: result });
|
||||||
|
} catch (error) {
|
||||||
|
const result = {
|
||||||
|
code: 500,
|
||||||
|
msg: (error as any).toString()
|
||||||
|
};
|
||||||
|
webview.postMessage({ command:'server/version', data: result });
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import { PostMessageble } from '../adapter';
|
import { PostMessageble } from '../adapter';
|
||||||
import { connect, MCPClient, type MCPOptions } from './connect';
|
import { connect, MCPClient, type MCPOptions } from './connect';
|
||||||
import { callTool, getPrompt, listPrompts, listResources, listResourceTemplates, listTools, readResource } from './handler';
|
import { callTool, getPrompt, getServerVersion, listPrompts, listResources, listResourceTemplates, listTools, readResource } from './handler';
|
||||||
import { chatCompletionHandler } from './llm';
|
import { chatCompletionHandler } from './llm';
|
||||||
import { panelLoadHandler, panelSaveHandler } from './panel';
|
import { panelLoadHandler, panelSaveHandler } from './panel';
|
||||||
import { settingLoadHandler, settingSaveHandler } from './setting';
|
import { settingLoadHandler, settingSaveHandler } from './setting';
|
||||||
@ -42,6 +42,10 @@ export function messageController(command: string, data: any, webview: PostMessa
|
|||||||
connectHandler(data, webview);
|
connectHandler(data, webview);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'server/version':
|
||||||
|
getServerVersion(client, webview);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'prompts/list':
|
case 'prompts/list':
|
||||||
listPrompts(client, webview);
|
listPrompts(client, webview);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user