misc fixes

This commit is contained in:
Andrew Pareles 2025-05-21 20:57:54 -07:00
parent 55691624dd
commit 72143608a1
4 changed files with 34 additions and 78 deletions

View file

@ -1,17 +1,7 @@
import { VoidSwitch } from '../util/inputs.js';
import { VoidSwitch, VoidButtonBgDarken } from '../util/inputs.js';
import { MCPConfigFileParseErrorResponse, MCPServerEventType, MCPServerEventResponse, MCPServerObject, MCPServerOfName } from '../../../../common/mcpServiceTypes.js';
import { useEffect, useState } from 'react';
import { useAccessor, useMCPServiceState } from '../util/services.js';
import { IDisposable } from '../../../../../../../base/common/lifecycle.js';
// Command display component
const CommandDisplay = ({ command }: { command: string }) => {
return (
<div className="px-2 py-1 bg-void-bg-3 text-xs font-mono overflow-x-auto whitespace-nowrap">
{command}
</div>
);
};
// MCP Server component
@ -44,7 +34,7 @@ const MCPServer = ({ name, server }: { name: string, server: MCPServerObject })
{/* Power toggle switch */}
<div className="ml-auto">
<VoidSwitch
value={server.isOn}
value={server.isOn ?? false}
disabled={server.status === 'error'}
onChange={handleChangeEvent}
/>
@ -70,11 +60,13 @@ const MCPServer = ({ name, server }: { name: string, server: MCPServerObject })
</div>
</div>
{/* Command display */}
{/* Command badge */}
{server.isOn && server.command && (
<div className="mt-2 mx-4">
<div className="text-xs text-gray-400">Command:</div>
<CommandDisplay command={server.command} />
<div className="px-2 py-1 bg-void-bg-3 text-xs font-mono overflow-x-auto whitespace-nowrap">
{server.command}
</div>
</div>
)}
@ -97,36 +89,8 @@ const MCPServer = ({ name, server }: { name: string, server: MCPServerObject })
const MCPServersList = () => {
const mcpServiceState = useMCPServiceState()
// const handleListeners = (e: MCPServerEventResponse | MCPConfigFileParseErrorResponse) => {
// if (e.response.type === 'config-file-error') {
// // Handle the config error event
// const { error } = e.response;
// setMCPConfigError(error);
// return;
// }
// if (e.response.type === 'add' || e.response.type === 'update' || e.response.type === 'loading') {
// // Handle the add event
// const { name, newServer } = e.response;
// setMCPServers(prevServers => ({
// ...prevServers,
// [name]: newServer
// }));
// return;
// }
// if (e.response.type === 'delete') {
// // Handle the delete event
// const { name, prevServer } = e.response;
// setMCPServers(prevServers => {
// const newServers = { ...prevServers };
// delete newServers[name];
// return newServers;
// });
// return;
// }
// throw new Error('Event not handled');
// }
const accessor = useAccessor();
const mcpService = accessor.get('IMCPService');
return (
<div className="text-white rounded-md py-4">

View file

@ -10,7 +10,6 @@ import { createDecorator } from '../../../../platform/instantiation/common/insta
import { IFileService } from '../../../../platform/files/common/files.js';
import { IPathService } from '../../../services/path/common/pathService.js';
import { IEditorService } from '../../../services/editor/common/editorService.js';
import { join } from '../../../../base/common/path.js';
import { IProductService } from '../../../../platform/product/common/productService.js';
import { VSBuffer } from '../../../../base/common/buffer.js';
import { IChannel } from '../../../../base/parts/ipc/common/ipc.js';
@ -148,10 +147,10 @@ class MCPService extends Disposable implements IMCPService {
this._onDidChangeState.fire();
}
private readonly _setHasError = async (hasError: string | undefined) => {
private readonly _setHasError = async (errMsg: string | undefined) => {
this.state = {
...this.state,
error: hasError ? `MCP config file not found` : undefined,
error: errMsg,
}
this._onDidChangeState.fire();
}
@ -165,32 +164,6 @@ class MCPService extends Disposable implements IMCPService {
await this.fileService.writeFile(mcpConfigUri, buffer);
}
private async _parseMCPConfigFile(): Promise<MCPConfigFileType | null> {
// TODO!!!!!!! double check this
// this._onConfigParsingError.fire({
// response: {
// type: 'config-file-error',
// error: null
// }
// });
// Process config file
const mcpConfigUri = await this._getMCPConfigFilePath();
try {
const fileContent = await this.fileService.readFile(mcpConfigUri);
const contentString = fileContent.value.toString();
const configJson = JSON.parse(contentString);
if (!configJson.mcpServers) {
throw new Error('Invalid MCP config file: missing mcpServers property');
}
return configJson as MCPConfigFileType;
} catch (error) {
const fullError = `Error parsing MCP config file: ${error}`;
this._setHasError(fullError)
return null;
}
}
private async _addMCPConfigFileWatcher(): Promise<void> {
const mcpConfigUri = await this._getMCPConfigFilePath();
@ -258,8 +231,8 @@ class MCPService extends Disposable implements IMCPService {
private async _getMCPConfigFilePath(): Promise<URI> {
const appName = this.productService.dataFolderName
const userHome = await this.pathService.userHome();
const mcpConfigPath = join(userHome.path, appName, MCP_CONFIG_FILE_NAME);
return URI.file(mcpConfigPath);
const uri = URI.joinPath(userHome, appName, MCP_CONFIG_FILE_NAME)
return uri
}
private async _configFileExists(mcpConfigUri: URI): Promise<boolean> {
@ -271,6 +244,25 @@ class MCPService extends Disposable implements IMCPService {
}
}
private async _parseMCPConfigFile(): Promise<MCPConfigFileType | null> {
const mcpConfigUri = await this._getMCPConfigFilePath();
try {
const fileContent = await this.fileService.readFile(mcpConfigUri);
const contentString = fileContent.value.toString();
const configFileJson = JSON.parse(contentString);
if (!configFileJson.mcpServers) {
throw new Error('Missing mcpServers property');
}
return configFileJson as MCPConfigFileType;
} catch (error) {
const fullError = `Error parsing MCP config file: ${error}`;
this._setHasError(fullError)
return null;
}
}
// Handle server state changes
private async _refreshMCPServers(): Promise<void> {
@ -285,7 +277,7 @@ class MCPService extends Disposable implements IMCPService {
const availableServers = Object.keys(mcpConfigFile.mcpServers);
// Handle added servers
const addedServers = availableServers.filter(serverName => !currMCPStateOfName[serverName].isOn);
const addedServers = availableServers.filter(serverName => !currMCPStateOfName[serverName]?.isOn);
const addedServersObject = addedServers.reduce((acc, serverName) => {
acc[serverName] = { isOn: true };
return acc;

View file

@ -138,7 +138,7 @@ export interface MCPServerObject {
// Command-based server properties
tools: MCPTool[],
status: 'loading' | 'error' | 'success' | 'offline',
isOn: boolean,
isOn: boolean | undefined,
command?: string,
error?: string,
}

View file

@ -495,7 +495,7 @@ export const defaultOverridesOfModel = overridesOfModel
export interface MCPServerStateOfName {
[serverName: string]: MCPServerState;
[serverName: string]: MCPServerState | undefined;
}
export interface MCPServerState {