write mcp logs to the log file
This commit is contained in:
@@ -234,6 +234,18 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
return c.text('OK')
|
return c.text('OK')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.post('/mcp-log', async (c) => {
|
||||||
|
try {
|
||||||
|
const { level, args } = await c.req.json()
|
||||||
|
const logFn = (logger as any)[level] || logger.log
|
||||||
|
const prefix = chalk.red(`[MCP] [${level.toUpperCase()}]`)
|
||||||
|
logFn(prefix, ...args)
|
||||||
|
return c.json({ ok: true })
|
||||||
|
} catch {
|
||||||
|
return c.json({ ok: false }, 400)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
app.get('/cdp/:clientId?', upgradeWebSocket((c) => {
|
app.get('/cdp/:clientId?', upgradeWebSocket((c) => {
|
||||||
const clientId = c.req.param('clientId') || 'default'
|
const clientId = c.req.param('clientId') || 'default'
|
||||||
|
|
||||||
|
|||||||
+41
-24
@@ -67,7 +67,7 @@ type VMContextWithGlobals = VMContext & typeof usefulGlobals
|
|||||||
|
|
||||||
type SelectorGenerator = typeof import('@mizchi/selector-generator')
|
type SelectorGenerator = typeof import('@mizchi/selector-generator')
|
||||||
|
|
||||||
const mcpState: State = {
|
const state: State = {
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
page: null,
|
page: null,
|
||||||
browser: null,
|
browser: null,
|
||||||
@@ -88,10 +88,23 @@ function clearUserState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearConnectionState() {
|
function clearConnectionState() {
|
||||||
mcpState.isConnected = false
|
state.isConnected = false
|
||||||
mcpState.browser = null
|
state.browser = null
|
||||||
mcpState.page = null
|
state.page = null
|
||||||
mcpState.context = null
|
state.context = null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendLogToRelayServer(level: string, ...args: any[]) {
|
||||||
|
try {
|
||||||
|
await fetch(`http://localhost:${RELAY_PORT}/mcp-log`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ level, args }),
|
||||||
|
signal: AbortSignal.timeout(1000),
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
// Silently fail if relay server is not available
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isPortTaken(port: number): Promise<boolean> {
|
async function isPortTaken(port: number): Promise<boolean> {
|
||||||
@@ -136,8 +149,8 @@ async function ensureRelayServer(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
||||||
if (mcpState.isConnected && mcpState.browser && mcpState.page) {
|
if (state.isConnected && state.browser && state.page) {
|
||||||
return { browser: mcpState.browser, page: mcpState.page }
|
return { browser: state.browser, page: state.page }
|
||||||
}
|
}
|
||||||
|
|
||||||
await ensureRelayServer()
|
await ensureRelayServer()
|
||||||
@@ -162,10 +175,10 @@ async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
|||||||
// Set up console listener for all existing pages
|
// Set up console listener for all existing pages
|
||||||
context.pages().forEach(p => setupPageConsoleListener(p))
|
context.pages().forEach(p => setupPageConsoleListener(p))
|
||||||
|
|
||||||
mcpState.browser = browser
|
state.browser = browser
|
||||||
mcpState.page = page
|
state.page = page
|
||||||
mcpState.context = context
|
state.context = context
|
||||||
mcpState.isConnected = true
|
state.isConnected = true
|
||||||
|
|
||||||
return { browser, page }
|
return { browser, page }
|
||||||
}
|
}
|
||||||
@@ -237,12 +250,12 @@ function setupPageConsoleListener(page: Page) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getCurrentPage(timeout = 5000) {
|
async function getCurrentPage(timeout = 5000) {
|
||||||
if (mcpState.page) {
|
if (state.page) {
|
||||||
return mcpState.page
|
return state.page
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcpState.browser) {
|
if (state.browser) {
|
||||||
const contexts = mcpState.browser.contexts()
|
const contexts = state.browser.contexts()
|
||||||
if (contexts.length > 0) {
|
if (contexts.length > 0) {
|
||||||
const pages = contexts[0].pages()
|
const pages = contexts[0].pages()
|
||||||
|
|
||||||
@@ -259,9 +272,9 @@ async function getCurrentPage(timeout = 5000) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function resetConnection(): Promise<{ browser: Browser; page: Page; context: BrowserContext }> {
|
async function resetConnection(): Promise<{ browser: Browser; page: Page; context: BrowserContext }> {
|
||||||
if (mcpState.browser) {
|
if (state.browser) {
|
||||||
try {
|
try {
|
||||||
await mcpState.browser.close()
|
await state.browser.close()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error closing browser:', e)
|
console.error('Error closing browser:', e)
|
||||||
}
|
}
|
||||||
@@ -295,10 +308,10 @@ async function resetConnection(): Promise<{ browser: Browser; page: Page; contex
|
|||||||
// Set up console listener for all existing pages
|
// Set up console listener for all existing pages
|
||||||
context.pages().forEach(p => setupPageConsoleListener(p))
|
context.pages().forEach(p => setupPageConsoleListener(p))
|
||||||
|
|
||||||
mcpState.browser = browser
|
state.browser = browser
|
||||||
mcpState.page = page
|
state.page = page
|
||||||
mcpState.context = context
|
state.context = context
|
||||||
mcpState.isConnected = true
|
state.isConnected = true
|
||||||
|
|
||||||
return { browser, page, context }
|
return { browser, page, context }
|
||||||
}
|
}
|
||||||
@@ -328,7 +341,7 @@ server.tool(
|
|||||||
await ensureConnection()
|
await ensureConnection()
|
||||||
|
|
||||||
const page = await getCurrentPage(timeout)
|
const page = await getCurrentPage(timeout)
|
||||||
const context = mcpState.context || page.context()
|
const context = state.context || page.context()
|
||||||
|
|
||||||
console.error('Executing code:', code)
|
console.error('Executing code:', code)
|
||||||
const consoleLogs: Array<{ method: string; args: any[] }> = []
|
const consoleLogs: Array<{ method: string; args: any[] }> = []
|
||||||
@@ -562,7 +575,10 @@ server.tool(
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('Error in execute tool, attempting reset:', error.message)
|
const errorStack = error.stack || error.message
|
||||||
|
console.error('Error in execute tool, attempting reset:', errorStack)
|
||||||
|
await sendLogToRelayServer('error', '[MCP] CRITICAL ERROR - Connection reset triggered:', errorStack)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await resetConnection()
|
await resetConnection()
|
||||||
return {
|
return {
|
||||||
@@ -574,11 +590,12 @@ server.tool(
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
} catch (resetError: any) {
|
} catch (resetError: any) {
|
||||||
|
await sendLogToRelayServer('error', '[MCP] CRITICAL ERROR - Reset failed:', resetError.stack || resetError.message)
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: 'text',
|
type: 'text',
|
||||||
text: `Error executing code: ${error.message}\n${error.stack || ''}`,
|
text: `Error executing code: ${error.message}\n${errorStack}`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
isError: true,
|
isError: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user