ui: Linting & Formatting scripts (#26819)
This commit is contained in:
@@ -1,63 +1,63 @@
|
||||
import { Client } from '@modelcontextprotocol/sdk/client';
|
||||
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
||||
import {
|
||||
StreamableHTTPClientTransport,
|
||||
StreamableHTTPError
|
||||
} from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
||||
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
||||
import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/websocket.js';
|
||||
import type {
|
||||
Tool,
|
||||
Prompt,
|
||||
GetPromptResult,
|
||||
ListChangedHandlers
|
||||
} from '@modelcontextprotocol/sdk/types.js';
|
||||
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
import type {
|
||||
GetPromptResult,
|
||||
ListChangedHandlers,
|
||||
Prompt,
|
||||
Tool
|
||||
} from '@modelcontextprotocol/sdk/types.js';
|
||||
import {
|
||||
DEFAULT_MCP_CONFIG,
|
||||
CORS_PROXY_ENDPOINT,
|
||||
CORS_PROXY_HEADER_PREFIX,
|
||||
DEFAULT_CLIENT_VERSION,
|
||||
DEFAULT_IMAGE_MIME_TYPE,
|
||||
CORS_PROXY_HEADER_PREFIX,
|
||||
MCP_PARTIAL_REDACT_HEADERS,
|
||||
CORS_PROXY_ENDPOINT
|
||||
DEFAULT_MCP_CONFIG,
|
||||
MCP_PARTIAL_REDACT_HEADERS
|
||||
} from '$lib/constants';
|
||||
import {
|
||||
MCPConnectionPhase,
|
||||
MCPLogLevel,
|
||||
MCPTransportType,
|
||||
MCPContentType,
|
||||
MCPRefType
|
||||
MCPLogLevel,
|
||||
MCPRefType,
|
||||
MCPTransportType
|
||||
} from '$lib/enums';
|
||||
import type {
|
||||
MCPServerConfig,
|
||||
MCPResourceIcon,
|
||||
ToolCallParams,
|
||||
ToolExecutionResult,
|
||||
Implementation,
|
||||
ClientCapabilities,
|
||||
Implementation,
|
||||
MCPConnection,
|
||||
MCPPhaseCallback,
|
||||
MCPConnectionLog,
|
||||
MCPServerInfo,
|
||||
MCPPhaseCallback,
|
||||
MCPReadResourceResult,
|
||||
MCPResource,
|
||||
MCPResourceTemplate,
|
||||
MCPResourceContent,
|
||||
MCPReadResourceResult
|
||||
MCPResourceIcon,
|
||||
MCPResourceTemplate,
|
||||
MCPServerConfig,
|
||||
MCPServerInfo,
|
||||
ToolCallParams,
|
||||
ToolExecutionResult
|
||||
} from '$lib/types';
|
||||
import {
|
||||
buildProxiedUrl,
|
||||
buildProxiedHeaders,
|
||||
getAuthHeaders,
|
||||
sanitizeHeaders,
|
||||
throwIfAborted,
|
||||
isAbortError,
|
||||
buildProxiedUrl,
|
||||
createBase64DataUrl,
|
||||
getRequestUrl,
|
||||
getRequestMethod,
|
||||
getRequestBody,
|
||||
summarizeRequestBody,
|
||||
formatDiagnosticErrorMessage,
|
||||
extractJsonRpcMethods,
|
||||
type RequestBodySummary
|
||||
formatDiagnosticErrorMessage,
|
||||
getAuthHeaders,
|
||||
getRequestBody,
|
||||
getRequestMethod,
|
||||
getRequestUrl,
|
||||
isAbortError,
|
||||
type RequestBodySummary,
|
||||
sanitizeHeaders,
|
||||
summarizeRequestBody,
|
||||
throwIfAborted
|
||||
} from '$lib/utils';
|
||||
|
||||
interface ToolResultContentItem {
|
||||
@@ -101,11 +101,11 @@ export class MCPService {
|
||||
details?: unknown
|
||||
): MCPConnectionLog {
|
||||
return {
|
||||
timestamp: new Date(),
|
||||
phase,
|
||||
message,
|
||||
details,
|
||||
level,
|
||||
details
|
||||
message,
|
||||
phase,
|
||||
timestamp: new Date()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,12 +118,12 @@ export class MCPService {
|
||||
): DiagnosticRequestDetails {
|
||||
const body = getRequestBody(input, init);
|
||||
const details: DiagnosticRequestDetails = {
|
||||
url: getRequestUrl(input),
|
||||
method: getRequestMethod(input, init, baseInit).toUpperCase(),
|
||||
body: summarizeRequestBody(body),
|
||||
credentials: init?.credentials ?? baseInit.credentials,
|
||||
mode: init?.mode ?? baseInit.mode,
|
||||
headers: sanitizeHeaders(requestHeaders, extraRedactedHeaders, MCP_PARTIAL_REDACT_HEADERS),
|
||||
body: summarizeRequestBody(body)
|
||||
method: getRequestMethod(input, init, baseInit).toUpperCase(),
|
||||
mode: init?.mode ?? baseInit.mode,
|
||||
url: getRequestUrl(input)
|
||||
};
|
||||
const jsonRpcMethods = extractJsonRpcMethods(body);
|
||||
|
||||
@@ -144,6 +144,7 @@ export class MCPService {
|
||||
useProxy && !key.toLowerCase().startsWith(CORS_PROXY_HEADER_PREFIX)
|
||||
? `${CORS_PROXY_HEADER_PREFIX}${key}`
|
||||
: key;
|
||||
|
||||
requestHeaders.set(proxiedKey, value);
|
||||
}
|
||||
}
|
||||
@@ -151,12 +152,12 @@ export class MCPService {
|
||||
private static summarizeError(error: unknown): Record<string, unknown> {
|
||||
if (error instanceof Error) {
|
||||
return {
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
cause:
|
||||
error.cause instanceof Error
|
||||
? { name: error.cause.name, message: error.cause.message }
|
||||
? { message: error.cause.message, name: error.cause.name }
|
||||
: error.cause,
|
||||
message: error.message,
|
||||
name: error.name,
|
||||
stack: error.stack?.split('\n').slice(0, 6).join('\n')
|
||||
};
|
||||
}
|
||||
@@ -173,13 +174,13 @@ export class MCPService {
|
||||
}
|
||||
|
||||
return {
|
||||
isSecureContext: window.isSecureContext,
|
||||
location: window.location.href,
|
||||
origin: window.location.origin,
|
||||
protocol: window.location.protocol,
|
||||
isSecureContext: window.isSecureContext,
|
||||
sameOrigin: window.location.origin === targetUrl.origin,
|
||||
targetOrigin: targetUrl.origin,
|
||||
targetProtocol: targetUrl.protocol,
|
||||
sameOrigin: window.location.origin === targetUrl.origin,
|
||||
useProxy
|
||||
};
|
||||
}
|
||||
@@ -244,6 +245,7 @@ export class MCPService {
|
||||
disable: () => void;
|
||||
} {
|
||||
let enabled = true;
|
||||
|
||||
const logIfEnabled = (log: MCPConnectionLog) => {
|
||||
if (enabled) {
|
||||
onLog?.(log);
|
||||
@@ -251,9 +253,13 @@ export class MCPService {
|
||||
};
|
||||
|
||||
return {
|
||||
disable: () => {
|
||||
enabled = false;
|
||||
},
|
||||
fetch: async (input, init) => {
|
||||
if (useProxy && typeof window !== 'undefined') {
|
||||
let requestUrlStr = '';
|
||||
|
||||
if (typeof input === 'string') {
|
||||
requestUrlStr = input;
|
||||
} else if (input instanceof URL) {
|
||||
@@ -262,6 +268,7 @@ export class MCPService {
|
||||
|
||||
if (requestUrlStr) {
|
||||
const parsedRequestUrl = new URL(requestUrlStr, window.location.origin);
|
||||
|
||||
if (
|
||||
parsedRequestUrl.origin === window.location.origin &&
|
||||
!parsedRequestUrl.pathname.includes(CORS_PROXY_ENDPOINT)
|
||||
@@ -308,8 +315,8 @@ export class MCPService {
|
||||
`HTTP ${method} ${url}`,
|
||||
MCPLogLevel.INFO,
|
||||
{
|
||||
serverName,
|
||||
request
|
||||
request,
|
||||
serverName
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -324,11 +331,11 @@ export class MCPService {
|
||||
MCPLogLevel.INFO,
|
||||
{
|
||||
response: {
|
||||
url,
|
||||
durationMs: 0,
|
||||
isFake: true,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
durationMs: 0,
|
||||
isFake: true
|
||||
url
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -353,11 +360,11 @@ export class MCPService {
|
||||
response.ok ? MCPLogLevel.INFO : MCPLogLevel.WARN,
|
||||
{
|
||||
response: {
|
||||
url,
|
||||
durationMs,
|
||||
headers: sanitizeHeaders(response.headers, undefined, MCP_PARTIAL_REDACT_HEADERS),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: sanitizeHeaders(response.headers, undefined, MCP_PARTIAL_REDACT_HEADERS),
|
||||
durationMs
|
||||
url
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -373,21 +380,18 @@ export class MCPService {
|
||||
`HTTP ${method} ${url} failed: ${formatDiagnosticErrorMessage(error)}`,
|
||||
MCPLogLevel.ERROR,
|
||||
{
|
||||
serverName,
|
||||
request,
|
||||
error: this.summarizeError(error),
|
||||
browser: this.getBrowserContext(targetUrl, useProxy),
|
||||
durationMs,
|
||||
error: this.summarizeError(error),
|
||||
hints: this.getConnectionHints(targetUrl, config, error),
|
||||
durationMs
|
||||
request,
|
||||
serverName
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
disable: () => {
|
||||
enabled = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -463,15 +467,15 @@ export class MCPService {
|
||||
}
|
||||
|
||||
return {
|
||||
stopPhaseLogging: () => {},
|
||||
transport: new WebSocketClientTransport(url),
|
||||
type: MCPTransportType.WEBSOCKET,
|
||||
stopPhaseLogging: () => {}
|
||||
type: MCPTransportType.WEBSOCKET
|
||||
};
|
||||
}
|
||||
|
||||
if (config.transport === MCPTransportType.SSE) {
|
||||
const url = useProxy ? buildProxiedUrl(config.url) : new URL(config.url);
|
||||
const { fetch: diagnosticFetch, disable: stopPhaseLogging } = this.createDiagnosticFetch(
|
||||
const { disable: stopPhaseLogging, fetch: diagnosticFetch } = this.createDiagnosticFetch(
|
||||
serverName,
|
||||
config,
|
||||
requestInit,
|
||||
@@ -485,18 +489,18 @@ export class MCPService {
|
||||
}
|
||||
|
||||
return {
|
||||
stopPhaseLogging,
|
||||
transport: new SSEClientTransport(url, {
|
||||
requestInit,
|
||||
eventSourceInit: { fetch: diagnosticFetch },
|
||||
fetch: diagnosticFetch,
|
||||
eventSourceInit: { fetch: diagnosticFetch }
|
||||
requestInit
|
||||
}),
|
||||
type: MCPTransportType.SSE,
|
||||
stopPhaseLogging
|
||||
type: MCPTransportType.SSE
|
||||
};
|
||||
}
|
||||
|
||||
const url = useProxy ? buildProxiedUrl(config.url) : new URL(config.url);
|
||||
const { fetch: diagnosticFetch, disable: stopPhaseLogging } = this.createDiagnosticFetch(
|
||||
const { disable: stopPhaseLogging, fetch: diagnosticFetch } = this.createDiagnosticFetch(
|
||||
serverName,
|
||||
config,
|
||||
requestInit,
|
||||
@@ -515,25 +519,25 @@ export class MCPService {
|
||||
}
|
||||
|
||||
return {
|
||||
stopPhaseLogging,
|
||||
transport: new StreamableHTTPClientTransport(url, {
|
||||
requestInit,
|
||||
fetch: diagnosticFetch
|
||||
fetch: diagnosticFetch,
|
||||
requestInit
|
||||
}),
|
||||
type: MCPTransportType.STREAMABLE_HTTP,
|
||||
stopPhaseLogging
|
||||
type: MCPTransportType.STREAMABLE_HTTP
|
||||
};
|
||||
} catch (httpError) {
|
||||
console.warn(`[MCPService] StreamableHTTP failed, trying SSE transport...`, httpError);
|
||||
|
||||
try {
|
||||
return {
|
||||
stopPhaseLogging,
|
||||
transport: new SSEClientTransport(url, {
|
||||
requestInit,
|
||||
eventSourceInit: { fetch: diagnosticFetch },
|
||||
fetch: diagnosticFetch,
|
||||
eventSourceInit: { fetch: diagnosticFetch }
|
||||
requestInit
|
||||
}),
|
||||
type: MCPTransportType.SSE,
|
||||
stopPhaseLogging
|
||||
type: MCPTransportType.SSE
|
||||
};
|
||||
} catch (sseError) {
|
||||
const httpMsg = httpError instanceof Error ? httpError.message : String(httpError);
|
||||
@@ -557,17 +561,17 @@ export class MCPService {
|
||||
}
|
||||
|
||||
return {
|
||||
name: impl.name,
|
||||
version: impl.version,
|
||||
title: impl.title,
|
||||
description: impl.description,
|
||||
websiteUrl: impl.websiteUrl,
|
||||
icons: impl.icons?.map((icon: MCPResourceIcon) => ({
|
||||
src: icon.src,
|
||||
mimeType: icon.mimeType,
|
||||
sizes: icon.sizes,
|
||||
src: icon.src,
|
||||
theme: icon.theme
|
||||
}))
|
||||
})),
|
||||
name: impl.name,
|
||||
title: impl.title,
|
||||
version: impl.version,
|
||||
websiteUrl: impl.websiteUrl
|
||||
};
|
||||
}
|
||||
|
||||
@@ -617,9 +621,9 @@ export class MCPService {
|
||||
}
|
||||
|
||||
const {
|
||||
stopPhaseLogging,
|
||||
transport,
|
||||
type: transportType,
|
||||
stopPhaseLogging
|
||||
type: transportType
|
||||
} = this.createTransport(serverName, serverConfig, (log) => onPhase?.(log.phase, log));
|
||||
|
||||
// Setup WebSocket reconnection handler
|
||||
@@ -650,7 +654,6 @@ export class MCPService {
|
||||
listChanged: listChangedHandlers
|
||||
}
|
||||
);
|
||||
|
||||
const runtimeErrorHandler = (error: Error) => {
|
||||
// the SDK reports any post initialize error here, including the abort we trigger
|
||||
// ourselves on the next health check cycle, on tab unload, or on server teardown.
|
||||
@@ -661,7 +664,9 @@ export class MCPService {
|
||||
if (isAbortError(error)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const msg = error?.message ?? '';
|
||||
|
||||
if (
|
||||
/SSE stream disconnected:.*AbortError/i.test(msg) ||
|
||||
/AbortError: .*aborted/i.test(msg) ||
|
||||
@@ -669,6 +674,7 @@ export class MCPService {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(`[MCPService][${serverName}] Protocol error after initialize:`, error);
|
||||
};
|
||||
|
||||
@@ -701,6 +707,7 @@ export class MCPService {
|
||||
|
||||
try {
|
||||
let handshakeTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const handshakeDeadline = new Promise<never>((_, reject) => {
|
||||
handshakeTimer = setTimeout(() => {
|
||||
void transport.close().catch(() => {});
|
||||
@@ -736,21 +743,21 @@ export class MCPService {
|
||||
}`,
|
||||
MCPLogLevel.ERROR,
|
||||
{
|
||||
error: this.summarizeError(error),
|
||||
browser: this.getBrowserContext(url, serverConfig.useProxy ?? false),
|
||||
config: {
|
||||
serverName,
|
||||
configuredUrl: serverConfig.url,
|
||||
credentials: serverConfig.credentials,
|
||||
effectiveUrl: url.href,
|
||||
transportType,
|
||||
useProxy: serverConfig.useProxy ?? false,
|
||||
headers: sanitizeHeaders(
|
||||
serverConfig.headers,
|
||||
Object.keys(serverConfig.headers ?? {}),
|
||||
MCP_PARTIAL_REDACT_HEADERS
|
||||
),
|
||||
credentials: serverConfig.credentials
|
||||
serverName,
|
||||
transportType,
|
||||
useProxy: serverConfig.useProxy ?? false
|
||||
},
|
||||
browser: this.getBrowserContext(url, serverConfig.useProxy ?? false),
|
||||
error: this.summarizeError(error),
|
||||
hints: this.getConnectionHints(url, serverConfig, error)
|
||||
}
|
||||
)
|
||||
@@ -777,10 +784,10 @@ export class MCPService {
|
||||
}
|
||||
),
|
||||
{
|
||||
serverInfo,
|
||||
serverCapabilities,
|
||||
clientCapabilities: effectiveCapabilities,
|
||||
instructions
|
||||
instructions,
|
||||
serverCapabilities,
|
||||
serverInfo
|
||||
}
|
||||
);
|
||||
|
||||
@@ -796,15 +803,14 @@ export class MCPService {
|
||||
|
||||
const tools = await this.listTools({
|
||||
client,
|
||||
transport,
|
||||
tools: [],
|
||||
serverName,
|
||||
transportType,
|
||||
connectionTimeMs: 0,
|
||||
requestTimeoutMs:
|
||||
serverConfig.requestTimeoutMs ?? DEFAULT_MCP_CONFIG.requestTimeoutSeconds * 1000
|
||||
serverConfig.requestTimeoutMs ?? DEFAULT_MCP_CONFIG.requestTimeoutSeconds * 1000,
|
||||
serverName,
|
||||
tools: [],
|
||||
transport,
|
||||
transportType
|
||||
});
|
||||
|
||||
const connectionTimeMs = Math.round(performance.now() - startTime);
|
||||
|
||||
// Phase: Connected
|
||||
@@ -815,6 +821,7 @@ export class MCPService {
|
||||
`Connection established with ${tools.length} tools (${connectionTimeMs}ms)`
|
||||
)
|
||||
);
|
||||
|
||||
if (import.meta.env.DEV && import.meta.env.VITE_DEBUG) {
|
||||
console.log(
|
||||
`[MCPService][${serverName}] Initialization complete with ${tools.length} tools in ${connectionTimeMs}ms`
|
||||
@@ -823,18 +830,18 @@ export class MCPService {
|
||||
|
||||
return {
|
||||
client,
|
||||
transport,
|
||||
tools,
|
||||
serverName,
|
||||
transportType,
|
||||
serverInfo,
|
||||
serverCapabilities,
|
||||
clientCapabilities: effectiveCapabilities,
|
||||
protocolVersion: DEFAULT_MCP_CONFIG.protocolVersion,
|
||||
instructions,
|
||||
connectionTimeMs,
|
||||
instructions,
|
||||
protocolVersion: DEFAULT_MCP_CONFIG.protocolVersion,
|
||||
requestTimeoutMs:
|
||||
serverConfig.requestTimeoutMs ?? DEFAULT_MCP_CONFIG.requestTimeoutSeconds * 1000
|
||||
serverConfig.requestTimeoutMs ?? DEFAULT_MCP_CONFIG.requestTimeoutSeconds * 1000,
|
||||
serverCapabilities,
|
||||
serverInfo,
|
||||
serverName,
|
||||
tools,
|
||||
transport,
|
||||
transportType
|
||||
};
|
||||
}
|
||||
|
||||
@@ -861,6 +868,7 @@ export class MCPService {
|
||||
// by not setting onerror, but since we use it for protocol logging,
|
||||
// we must clear it before disconnect.
|
||||
connection.client.onerror = undefined;
|
||||
|
||||
if (connection.transport.onclose) {
|
||||
connection.transport.onclose = undefined;
|
||||
}
|
||||
@@ -936,7 +944,7 @@ export class MCPService {
|
||||
args?: Record<string, string>
|
||||
): Promise<GetPromptResult> {
|
||||
try {
|
||||
return await connection.client.getPrompt({ name, arguments: args });
|
||||
return await connection.client.getPrompt({ arguments: args, name });
|
||||
} catch (error) {
|
||||
console.error(`[MCPService][${connection.serverName}] Failed to get prompt:`, error);
|
||||
|
||||
@@ -964,7 +972,7 @@ export class MCPService {
|
||||
|
||||
try {
|
||||
const result = await connection.client.callTool(
|
||||
{ name: params.name, arguments: params.arguments },
|
||||
{ arguments: params.arguments, name: params.name },
|
||||
undefined,
|
||||
{ signal, timeout: connection.requestTimeoutMs }
|
||||
);
|
||||
@@ -1001,6 +1009,7 @@ export class MCPService {
|
||||
*/
|
||||
private static formatToolResult(result: ToolCallResult): string {
|
||||
const content = result.content;
|
||||
|
||||
if (!Array.isArray(content)) return '';
|
||||
|
||||
return content
|
||||
@@ -1022,6 +1031,7 @@ export class MCPService {
|
||||
const resource = content.resource;
|
||||
|
||||
if (resource.text) return resource.text;
|
||||
|
||||
if (resource.blob) return resource.blob;
|
||||
|
||||
return JSON.stringify(resource);
|
||||
@@ -1058,8 +1068,8 @@ export class MCPService {
|
||||
): Promise<{ values: string[]; total?: number; hasMore?: boolean } | null> {
|
||||
try {
|
||||
const result = await connection.client.complete({
|
||||
ref,
|
||||
argument
|
||||
argument,
|
||||
ref
|
||||
});
|
||||
|
||||
return result.completion;
|
||||
@@ -1092,8 +1102,8 @@ export class MCPService {
|
||||
const result = await connection.client.listResources(cursor ? { cursor } : undefined);
|
||||
|
||||
return {
|
||||
resources: (result.resources ?? []) as MCPResource[],
|
||||
nextCursor: result.nextCursor
|
||||
nextCursor: result.nextCursor,
|
||||
resources: (result.resources ?? []) as MCPResource[]
|
||||
};
|
||||
} catch (error) {
|
||||
if (this.isSessionExpiredError(error)) {
|
||||
@@ -1113,10 +1123,12 @@ export class MCPService {
|
||||
*/
|
||||
static async listAllResources(connection: MCPConnection): Promise<MCPResource[]> {
|
||||
const allResources: MCPResource[] = [];
|
||||
|
||||
let cursor: string | undefined;
|
||||
|
||||
do {
|
||||
const result = await this.listResources(connection, cursor);
|
||||
|
||||
allResources.push(...result.resources);
|
||||
cursor = result.nextCursor;
|
||||
} while (cursor);
|
||||
@@ -1138,8 +1150,8 @@ export class MCPService {
|
||||
const result = await connection.client.listResourceTemplates(cursor ? { cursor } : undefined);
|
||||
|
||||
return {
|
||||
resourceTemplates: (result.resourceTemplates ?? []) as MCPResourceTemplate[],
|
||||
nextCursor: result.nextCursor
|
||||
nextCursor: result.nextCursor,
|
||||
resourceTemplates: (result.resourceTemplates ?? []) as MCPResourceTemplate[]
|
||||
};
|
||||
} catch (error) {
|
||||
if (this.isSessionExpiredError(error)) {
|
||||
@@ -1162,10 +1174,12 @@ export class MCPService {
|
||||
*/
|
||||
static async listAllResourceTemplates(connection: MCPConnection): Promise<MCPResourceTemplate[]> {
|
||||
const allTemplates: MCPResourceTemplate[] = [];
|
||||
|
||||
let cursor: string | undefined;
|
||||
|
||||
do {
|
||||
const result = await this.listResourceTemplates(connection, cursor);
|
||||
|
||||
allTemplates.push(...result.resourceTemplates);
|
||||
cursor = result.nextCursor;
|
||||
} while (cursor);
|
||||
@@ -1187,8 +1201,8 @@ export class MCPService {
|
||||
const result = await connection.client.readResource({ uri });
|
||||
|
||||
return {
|
||||
contents: (result.contents ?? []) as MCPResourceContent[],
|
||||
_meta: result._meta
|
||||
_meta: result._meta,
|
||||
contents: (result.contents ?? []) as MCPResourceContent[]
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`[MCPService][${connection.serverName}] Failed to read resource:`, error);
|
||||
|
||||
Reference in New Issue
Block a user