vite-plugin-terminal-mcp
v1.4.2
Published
Log in the node terminal from the browser with MCP server integration
Maintainers
Readme
vite-plugin-terminal-mcp
Log in the node terminal from the browser with MCP (Model Context Protocol) server integration for AI assistants.
This is a fork of vite-plugin-terminal with added MCP server support, allowing AI assistants like Claude, Cursor, and Windsurf to query browser console logs in real-time.

Features
- 🖥️ Log to terminal from browser
- 🤖 MCP Server for AI assistant integration
- 🔍 Query console logs via MCP tools
- ⚛️ Works with React, Vue, Svelte, and all frameworks
- 🎯 Zero config - works out of the box
- 🌲 Tree-shakeable in production
Install
npm i -D vite-plugin-terminal-mcpOptional: Install MCP Dependencies
For MCP server support (AI assistant integration):
npm i @modelcontextprotocol/sdk zod patheQuick Start
Add plugin to your vite.config.ts:
// vite.config.ts
import Terminal from 'vite-plugin-terminal-mcp'
export default {
plugins: [
Terminal()
]
}With MCP Server (for AI Assistants)
// vite.config.ts
import Terminal from 'vite-plugin-terminal-mcp'
export default {
plugins: [
Terminal({
console: 'terminal',
mcp: {
maxLogs: 1000,
printUrl: true,
updateConfig: ['cursor'], // Auto-update Cursor MCP config
serverName: 'my-app-terminal',
}
})
]
}Usage
In your source code import terminal, and use it like you do with console.log.
import { terminal } from 'virtual:terminal'
terminal.log('Hey terminal! A message from the browser')The terminal log calls will be removed when building the app.
Types
There are two ways of telling typescript about the types of the virtual import:
In your
global.d.tsfile add the following line:/// <reference types="vite-plugin-terminal-mcp/client" />In your
tsconfig.jsonadd the following to yourcompilerOptions.typesarray:{ "compilerOptions": { "types": [ "vite-plugin-terminal-mcp/client" ] } }In your
tsconfig.jsonadd the following to yourcompilerOptions.typesarray:{ // ... "compilerOptions": { // ... "types": [ "vite-plugin-terminal-mcp/client" ] } }
API
Supported methods:
terminal.log(obj1 [, obj2, ..., objN])terminal.info(obj1 [, obj2, ..., objN])terminal.warn(obj1 [, obj2, ..., objN])terminal.error(obj1 [, obj2, ..., objN])terminal.assert(assertion, obj1 [, obj2, ..., objN])terminal.group()terminal.groupCollapsed()terminal.groupEnd()terminal.table(obj)terminal.time(id)terminal.timeLog(id, obj1 [, obj2, ..., objN])terminal.timeEnd(id)terminal.clear()terminal.count(label)terminal.countReset(label)terminal.dir(obj)terminal.dirxml(obj)
These methods will work but use the console
terminal.trace(...args: any[])terminal.profile(...args: any[])terminal.profileEnd(...args: any[])
Redirect console logs to the terminal
If you want the standard console logs to appear in the terminal, you can use the console: 'terminal' option in your vite.config.ts:
// vite.config.ts
import Terminal from 'vite-plugin-terminal-mcp'
export default {
plugins: [
Terminal({
console: 'terminal'
})
]
}In this case, you don't need to import the virtual terminal to use the plugin.
console.log('Hey terminal! A message from the browser')You can also overwrite it in your index.html head manually in case you would like more control.
<script type="module">
// Redirect console logs to the terminal
import terminal from 'virtual:terminal'
globalThis.console = terminal
</script>Check the Console playground for a full example.
Log in both the terminal and the console
You can use the output option to define where the terminal logs should be logged. Accepts terminal, console, or an array with both.
// vite.config.ts
import Terminal from 'vite-plugin-terminal-mcp'
export default {
plugins: [
Terminal({
output: ['terminal', 'console']
})
]
}Framework Examples
React
// vite.config.ts
import react from '@vitejs/plugin-react'
import Terminal from 'vite-plugin-terminal-mcp'
export default {
plugins: [
react(),
Terminal({
console: 'terminal',
mcp: {
maxLogs: 1000,
printUrl: true,
updateConfig: ['cursor'],
serverName: 'my-react-app',
}
})
]
}
// App.tsx
import { terminal } from 'virtual:terminal'
function App() {
const handleClick = () => {
terminal.log('Button clicked!')
terminal.error('Simulated error for debugging')
}
return <button onClick={handleClick}>Test Terminal</button>
}Vue
// vite.config.ts
import vue from '@vitejs/plugin-vue'
import Terminal from 'vite-plugin-terminal-mcp'
export default {
plugins: [
vue(),
Terminal({ console: 'terminal' })
]
}Vanilla JS
import { terminal } from 'virtual:terminal'
terminal.log('Hello from vanilla JS!')Playgrounds
- Basic - Vanilla JS using every available method
- Console - Redirect standard console logs to terminal
- Auto Import - Using unplugin-auto-import
- Vue - Vue 3 example
- React - React 18 example with MCP
Options
console
Type: 'terminal' | undefined
Default: undefined
Set to 'terminal' to make globalThis.console equal to the terminal object in your app.
output
Type: 'terminal' | 'console' | ['terminal', 'console']
Default: terminal
Define where the output for the logs.
strip
Type: boolean
Default: true
Strip terminal.*() when bundling for production.
include
Type: String | RegExp | Array[...String|RegExp]
Default: /.+\.(js|ts|mjs|cjs|mts|cts)/
Example: include: '**/*.(mjs|js)',
A pattern, or array of patterns, which specify the files in the build the plugin should operate on when removing calls for production.
exclude
Type: String | RegExp | Array[...String|RegExp]
Default: []
Example: exlude: 'tests/**/*',
A pattern, or array of patterns, which specify the files in the build the plugin should ignore when removing calls for production.
mcp
Type: boolean | MCPOptions
Default: false
Enable MCP (Model Context Protocol) server for AI assistant integration. Set to true for defaults or configure with an object:
{
mcp: {
maxLogs: 1000, // Max logs to store in memory
mcpPath: '/__terminal_mcp', // MCP endpoint path
printUrl: true, // Print MCP URL on startup
updateConfig: ['cursor'], // Auto-update AI config files
serverName: 'terminal', // Server name in config
levels: ['error', 'warn', 'info', 'log', 'debug', 'assert'], // Log levels to capture (default: all)
silent: false, // Only store in MCP without printing to terminal
}
}MCP Options
levels - Filter which log types are captured by MCP
- Type:
Array<'error' | 'warn' | 'info' | 'log' | 'debug' | 'assert'> - Default:
['error', 'warn', 'info', 'log', 'debug', 'assert'](all) - Example:
levels: ['error']- Only capture errors
updateConfig - Auto-update AI assistant config files
- Type:
'auto' | false | Array<'cursor' | 'vscode' | 'windsurf'> - Default:
'auto' 'auto'- Automatically updates config files if.cursor,.vscode, or~/.codeium/windsurfexistfalse- Don't update any config files['cursor', 'vscode']- Update specific config files only- Creates/updates:
- Cursor:
.cursor/mcp.json - VSCode:
.vscode/mcp.json - Windsurf:
~/.codeium/windsurf/mcp_config.json
- Cursor:
silent - Suppress terminal output for MCP-captured logs
- Type:
boolean - Default:
false - When
true, logs matchinglevelsare only stored in MCP, not printed to terminal - Non-matching logs still print normally
MCP Usage Examples
Capture only errors, hide them from terminal:
Terminal({
console: 'terminal',
mcp: {
levels: ['error'],
silent: true, // Errors only in MCP, not printed
}
})
// Result: Errors → MCP only, other logs → terminalCapture errors and warnings, print everything:
Terminal({
console: 'terminal',
mcp: {
levels: ['error', 'warn'],
silent: false, // Print to terminal too
}
})
// Result: Errors & warnings → MCP + terminal, other logs → terminalCapture everything, hide everything:
Terminal({
console: 'terminal',
mcp: {
silent: true, // All logs only in MCP
}
})
// Result: All logs → MCP only, nothing prints to terminalCapture everything, show everything:
Terminal({
console: 'terminal',
mcp: true // or { silent: false }
})
// Result: All logs → MCP + terminal (default behavior)MCP Tools Available
get-console-errors- Get recent console errorsget-console-logs- Get console logs with filteringget-console-logs-since- Get logs since timestampget-console-stats- Get console log statisticsclear-console-logs- Clear stored logs
Supported AI Assistants
- Cursor
- Claude Desktop (via MCP)
- Windsurf
- Any MCP-compatible client
Auto-Config Update
When updateConfig is enabled, the plugin will automatically update your AI assistant's configuration file (e.g., .cursor/mcp.json for Cursor) with the MCP server endpoint.
Common Scenarios
Scenario 1: Debug Production-Like Environment
Goal: Keep development clean, only let AI see errors
Terminal({
console: 'terminal',
mcp: {
levels: ['error'],
silent: true, // Errors only in MCP, not cluttering terminal
serverName: 'my-app-errors',
}
})Result:
- ✅ Errors captured by MCP (AI can query them)
- ✅ Terminal stays clean (no error spam)
- ✅ Other logs (warn, info, log) print normally
Scenario 2: AI-Assisted Debugging Session
Goal: Let AI see everything while you debug
Terminal({
console: 'terminal',
output: ['terminal', 'console'], // See logs everywhere
mcp: true, // AI can see everything too
})Result:
- ✅ All logs in terminal
- ✅ All logs in browser console
- ✅ All logs available to AI via MCP
Scenario 3: Silent Monitoring
Goal: Capture logs for AI without any terminal output
Terminal({
console: 'terminal',
mcp: {
silent: true, // Nothing prints
maxLogs: 5000,
serverName: 'background-monitor',
}
})Result:
- ✅ All logs captured by MCP
- ✅ Zero terminal output
- ✅ AI can query historical logs
Scenario 4: Error + Warning Tracking
Goal: Track errors and warnings, hide them from terminal
Terminal({
console: 'terminal',
mcp: {
levels: ['error', 'warn'],
silent: true,
serverName: 'issue-tracker',
}
})Result:
- ✅ Errors and warnings → MCP only
- ✅ Info and debug logs → Terminal
- ✅ Clean terminal, comprehensive error tracking
Scenario 5: Development with Live AI Assistant
Goal: Normal development with AI watching for issues
Terminal({
console: 'terminal',
mcp: {
levels: ['error', 'warn'],
silent: false, // Print errors/warnings too
updateConfig: ['cursor'],
printUrl: true,
}
})Result:
- ✅ Errors/warnings in terminal AND MCP
- ✅ AI can proactively notice issues
- ✅ You see everything in real-time
MCP Integration
The MCP server allows AI assistants to query your browser console logs in real-time. When enabled:
- Logs are captured from the browser and stored in memory
- MCP server exposes tools for querying these logs
- AI assistants can ask questions like:
- "What console errors happened?"
- "Show me the last 10 warnings"
- "Any errors in the last 5 minutes?"
How output and mcp.silent Work Together
The output option controls where logs are displayed, while mcp.silent controls whether MCP-captured logs are printed:
| Configuration | Errors | Warnings | Info/Log | Notes |
|--------------|--------|----------|----------|-------|
| output: 'terminal'mcp: { levels: ['error'], silent: true } | MCP only | Terminal | Terminal | Errors hidden from terminal |
| output: 'console'mcp: { levels: ['error'], silent: true } | MCP only | Browser console | Browser console | Errors not in browser console either |
| output: ['terminal', 'console']mcp: { levels: ['error'], silent: false } | MCP + Both | Both | Both | Everything everywhere |
| output: 'terminal'mcp: { silent: false } | MCP + Terminal | MCP + Terminal | MCP + Terminal | Default: capture and display |
Key Points:
mcp.silent: truesuppresses printing for logs matchingmcp.levels, regardless ofoutputsetting- Logs NOT in
mcp.levelsfollow theoutputsetting normally outputonly affects printing, not MCP storage
Example MCP Usage with Cursor
// .cursor/mcp.json (auto-generated)
{
"mcpServers": {
"my-app-terminal": {
"url": "http://localhost:5173/__terminal_mcp"
}
}
}Then in Cursor's AI chat:
- "Check the console for errors"
- "What's in the console logs?"
- "Clear the console logs"
Why This Fork?
This fork adds MCP server integration to the original vite-plugin-terminal, enabling:
- AI-assisted debugging - Let AI assistants query console logs
- Real-time log access - Query logs without switching to devtools
- Framework agnostic - Works with React, Vue, Svelte, etc.
- Zero browser extensions - No browser plugins needed
- Optional - MCP is opt-in, doesn't affect existing functionality
Credits
- Original plugin by Matias Capeletto - vite-plugin-terminal
- MCP integration by kiwina
- Original idea from Domenic Elm
- Project setup from @antfu's vite-plugin-inspect
- Bundling by unbuild
- Strip functions during build uses rollup-plugin-strip
License
MIT License © 2022-2024 Matias Capeletto, 2025-present kiwina
