---
title: "Server Logging"
description: "Debug and monitor your MCP server with built-in logging"
icon: "scroll-text"
---

mcp-use provides comprehensive logging for MCP servers, making it easy to understand server activity, debug issues, and monitor production deployments.

## Log Levels

HTTP request logging is controlled by the `MCP_DEBUG_LEVEL` environment variable, which has three levels: `info` (default), `debug`, and `trace`.

### Info (Default)

One compact line per request  -  session, client, the MCP method, and the outcome:

```bash
node server.js
```

**Output:**

```
[19:44:56.927] POST /mcp [initialize: my-client/0.1.0] → session=92c4e0b OK (1ms)
[19:44:56.935] sess=92c4e0b POST /mcp [notifications/initialized] OK (1ms)
[19:44:56.943] sess=92c4e0b POST /mcp [tools/list] OK (1ms)
[19:44:56.950] sess=92c4e0b POST /mcp [tools/call: greet] OK (1ms)
[19:44:56.958] sess=92c4e0b POST /mcp [tools/call: divide] ERROR cannot divide by zero (0ms)
[19:44:56.965] sess=92c4e0b POST /mcp [tools/call: does-not-exist] ERROR MCP error -32602: Tool does-not-exist not found (0ms)
```

### Debug

Same as `info` but appends inline `args=<json>` for `tools/call` requests:

```bash
MCP_DEBUG_LEVEL=debug node server.js
```

**Output:**

```
[19:44:57.918] sess=f93f8b1 POST /mcp [tools/call: greet] args={"name":"Andrew","formal":true} OK (1ms)
[19:44:57.926] sess=f93f8b1 POST /mcp [tools/call: divide] args={"a":10,"b":0} ERROR cannot divide by zero (0ms)
```

### Trace

Full request and response dump (headers and bodies) following the summary line  -  useful for protocol-level debugging:

```bash
MCP_DEBUG_LEVEL=trace node server.js
```

## Built-in Logging System

<Info>
  **v1.12.0 Breaking Change**: mcp-use replaced `winston` with a built-in
  `SimpleConsoleLogger` that works in both Node.js and browser environments. See
  the [migration guide](#migration-from-winston) below.
</Info>

The server uses a lightweight logging system that provides structured logs without external dependencies. This logger works seamlessly in both server and browser environments.

### Logger Configuration API

Configure the logger programmatically using the `Logger` class:

```typescript
import { Logger } from "mcp-use/server";

// Configure logging level and format
Logger.configure({
  level: "debug", // Set log level
  format: "detailed", // Set output format
});

// Or set debug level using numeric values
Logger.setDebug(0); // Production mode (info level)
Logger.setDebug(1); // Debug mode (info level)
Logger.setDebug(2); // Verbose mode (debug level)
```

### Log Levels

The logger supports seven log levels (from least to most verbose):

| Level     | Use Case                                 |
| --------- | ---------------------------------------- |
| `error`   | Error conditions that need attention     |
| `warn`    | Warning messages for potential issues    |
| `info`    | General informational messages (default) |
| `http`    | HTTP request/response logging            |
| `verbose` | Verbose informational messages           |
| `debug`   | Detailed debugging information           |
| `silly`   | Very detailed debug information          |

### Log Formats

Choose from three output formats:

#### Minimal Format (Default)

Clean, simple output with timestamp and level:

```
14:23:45 [mcp-use] info: Server mounted at /mcp
14:23:46 [mcp-use] info: Session initialized: abc123
```

#### Detailed Format

More verbose output with full context:

```
14:23:45 [mcp-use] INFO: Server mounted at /mcp (Streamable HTTP Transport)
14:23:46 [mcp-use] INFO: Session initialized: abc123
```

### Using the Logger

Get a logger instance for custom logging:

```typescript
import { Logger } from "mcp-use/server";

const logger = Logger.get("my-component");

logger.info("Component initialized");
logger.debug("Processing request", { userId: 123 });
logger.error("Operation failed", new Error("Connection timeout"));
```

### Browser Compatibility

The built-in logger works in both Node.js and browser environments without any configuration changes. This is a key improvement over the previous winston-based system, which was Node.js-only.

```typescript
// Same logger works everywhere
import { Logger } from "mcp-use/server";

// In Node.js
Logger.configure({ level: "debug", format: "detailed" });

// In browser (exact same API)
Logger.configure({ level: "info", format: "minimal" });
```

### Migration from Winston

If you're upgrading from mcp-use < v1.12.0, replace winston with the new Logger:

**Before (winston - removed in v1.12.0):**

```typescript
import winston from "winston";

const logger = winston.createLogger({
  level: "info",
  transports: [new winston.transports.Console()],
});

logger.info("Server started");
```

**After (SimpleConsoleLogger):**

```typescript
import { Logger } from "mcp-use/server";

Logger.configure({
  level: "info",
  format: "minimal",
});

const logger = Logger.get();
logger.info("Server started");
```

## Tool Logging with ctx.log

Tools can send log messages directly to clients during execution using `ctx.log()`. This allows real-time visibility into what your tool is doing, which is especially useful for long-running operations or debugging tool behavior.

```typescript
server.tool(
  {
    name: "process_data",
    description: "Process data with progress logging",
    schema: z.object({
      items: z.array(z.string()),
    }),
  },
  async ({ items }, ctx) => {
    // Log the start of processing
    await ctx.log("info", "Starting data processing");

    // Debug-level logging for detailed information
    await ctx.log("debug", `Processing ${items.length} items`, "my-tool");

    for (const item of items) {
      // Log warnings when needed
      if (!item.trim()) {
        await ctx.log("warning", "Empty item found, skipping");
        continue;
      }

      try {
        await processItem(item);
      } catch (err) {
        // Log errors without throwing
        await ctx.log("error", `Failed to process item: ${err.message}`);
      }
    }

    await ctx.log("info", "Processing completed");
    return text("All items processed");
  }
);
```

### Log Levels

The `ctx.log()` function supports eight log levels, from least to most severe:

| Level       | Use Case                                              |
| ----------- | ----------------------------------------------------- |
| `debug`     | Detailed debugging information, verbose output        |
| `info`      | General informational messages about progress         |
| `notice`    | Normal but significant events                         |
| `warning`   | Warning messages for recoverable issues               |
| `error`     | Error messages for failures that don't stop execution |
| `critical`  | Critical conditions requiring immediate attention     |
| `alert`     | Action must be taken immediately                      |
| `emergency` | System is unusable                                    |

### Parameters

```typescript
ctx.log(level, message, logger?)
```

- **`level`** (required): One of the eight log levels listed above
- **`message`** (required): The log message content as a string
- **`logger`** (optional): Logger name for categorization (defaults to `'tool'`)

## Related

- [Client Logging](/typescript/client/logging) - Logging for MCP clients
- [Notifications](./notifications) - Send status updates to clients
- [Configuration](./configuration) - Configure server options
- [Tools Guide](./tools) - Building tools with proper error handling
