mirror of
https://github.com/navidrome/navidrome.git
synced 2025-05-05 21:01:08 +03:00
fix(mcp-agent): stream native mcp-server stderr to logs
The previous implementation buffered stderr from the native mcp-server process and only logged the full buffer content when the process exited. This prevented real-time viewing of logs from the server. This change modifies the native process startup logic (`startProcess_locked`) to use `cmd.StderrPipe()` instead of assigning `cmd.Stderr` to a buffer. A separate goroutine is now launched within the process monitoring goroutine. This new goroutine uses a `bufio.Scanner` to continuously read lines from the stderr pipe and logs them using the Navidrome logger (`log.Info`) with an `[MCP-SERVER]` prefix. This ensures logs from the native mcp-server appear in Navidrome's logs immediately as they are written. (Note: Also includes update to McpServerPath constant to point to the native binary.) Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
bcc3643c81
commit
c7d7ec306e
@ -24,6 +24,7 @@ const (
|
||||
McpAgentName = "mcp"
|
||||
initializationTimeout = 5 * time.Second
|
||||
// McpServerPath defines the location of the MCP server executable or WASM module.
|
||||
// McpServerPath = "./core/agents/mcp/mcp-server/mcp-server"
|
||||
McpServerPath = "./core/agents/mcp/mcp-server/mcp-server.wasm"
|
||||
McpToolNameGetBio = "get_artist_biography"
|
||||
McpToolNameGetURL = "get_artist_url"
|
||||
|
@ -1,6 +1,7 @@
|
||||
package mcp
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -197,12 +198,18 @@ func (n *MCPNative) startProcess_locked(ctx context.Context) (stdin io.WriteClos
|
||||
return nil, nil, nil, fmt.Errorf("native stdout pipe: %w", err)
|
||||
}
|
||||
|
||||
var stderrBuf strings.Builder
|
||||
cmd.Stderr = &stderrBuf
|
||||
// Get stderr pipe to stream logs
|
||||
stderrPipe, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
_ = stdinPipe.Close()
|
||||
_ = stdoutPipe.Close()
|
||||
return nil, nil, nil, fmt.Errorf("native stderr pipe: %w", err)
|
||||
}
|
||||
|
||||
if err = cmd.Start(); err != nil {
|
||||
_ = stdinPipe.Close()
|
||||
_ = stdoutPipe.Close()
|
||||
// stderrPipe gets closed implicitly if cmd.Start() fails
|
||||
return nil, nil, nil, fmt.Errorf("native start: %w", err)
|
||||
}
|
||||
|
||||
@ -210,12 +217,24 @@ func (n *MCPNative) startProcess_locked(ctx context.Context) (stdin io.WriteClos
|
||||
currentCmd := cmd // Capture the current cmd pointer for the goroutine
|
||||
log.Info(ctx, "Native MCP server process started", "pid", currentPid)
|
||||
|
||||
// Start monitoring goroutine
|
||||
// Start monitoring goroutine for process exit
|
||||
go func() {
|
||||
// Start separate goroutine to stream stderr
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stderrPipe)
|
||||
for scanner.Scan() {
|
||||
log.Info("[MCP-SERVER] " + scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Error("Error reading MCP server stderr", "pid", currentPid, "error", err)
|
||||
}
|
||||
log.Debug("MCP server stderr pipe closed", "pid", currentPid)
|
||||
}()
|
||||
|
||||
waitErr := currentCmd.Wait() // Wait for the specific process this goroutine monitors
|
||||
n.mu.Lock()
|
||||
stderrStr := stderrBuf.String()
|
||||
log.Warn("Native MCP server process exited", "pid", currentPid, "error", waitErr, "stderr", stderrStr)
|
||||
// Stderr is now streamed, so we don't capture it here anymore.
|
||||
log.Warn("Native MCP server process exited", "pid", currentPid, "error", waitErr)
|
||||
|
||||
// Critical: Check if the agent's current command is STILL the one we were monitoring.
|
||||
// If it's different, it means cleanup/restart already happened, so we shouldn't cleanup again.
|
||||
|
Loading…
x
Reference in New Issue
Block a user