Skip to content

Commit 6f59ab8

Browse files
committed
return path translation logs to agent
Signed-off-by: Praful Khanduri <holiodin@gmail.com>
1 parent c44939c commit 6f59ab8

File tree

4 files changed

+72
-24
lines changed

4 files changed

+72
-24
lines changed

pkg/mcp/toolset/filesystem.go

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func (ts *ToolSet) ListDirectory(ctx context.Context,
2323
if ts.inst == nil {
2424
return nil, nil, errors.New("instance not registered")
2525
}
26-
guestPath, err := ts.TranslateHostPath(args.Path)
26+
guestPath, logs, err := ts.TranslateHostPath(args.Path)
2727
if err != nil {
2828
return nil, nil, err
2929
}
@@ -41,9 +41,15 @@ func (ts *ToolSet) ListDirectory(ctx context.Context,
4141
res.Entries[i].ModTime = ptr.Of(f.ModTime())
4242
res.Entries[i].IsDir = ptr.Of(f.IsDir())
4343
}
44-
return &mcp.CallToolResult{
44+
callToolRes := &mcp.CallToolResult{
4545
StructuredContent: res,
46-
}, res, nil
46+
}
47+
if logs != "" {
48+
callToolRes.Meta = map[string]any{
49+
"io.lima-vm/logs": []string{logs},
50+
}
51+
}
52+
return callToolRes, res, nil
4753
}
4854

4955
func (ts *ToolSet) ReadFile(_ context.Context,
@@ -52,7 +58,7 @@ func (ts *ToolSet) ReadFile(_ context.Context,
5258
if ts.inst == nil {
5359
return nil, nil, errors.New("instance not registered")
5460
}
55-
guestPath, err := ts.TranslateHostPath(args.Path)
61+
guestPath, logs, err := ts.TranslateHostPath(args.Path)
5662
if err != nil {
5763
return nil, nil, err
5864
}
@@ -70,12 +76,18 @@ func (ts *ToolSet) ReadFile(_ context.Context,
7076
res := &msi.ReadFileResult{
7177
Content: string(b),
7278
}
73-
return &mcp.CallToolResult{
79+
callToolRes := &mcp.CallToolResult{
7480
// Gemini:
7581
// For text files: The file content, potentially prefixed with a truncation message
7682
// (e.g., [File content truncated: showing lines 1-100 of 500 total lines...]\nActual file content...).
7783
StructuredContent: res,
78-
}, res, nil
84+
}
85+
if logs != "" {
86+
callToolRes.Meta = map[string]any{
87+
"io.lima-vm/logs": []string{logs},
88+
}
89+
}
90+
return callToolRes, res, nil
7991
}
8092

8193
func (ts *ToolSet) WriteFile(_ context.Context,
@@ -84,7 +96,7 @@ func (ts *ToolSet) WriteFile(_ context.Context,
8496
if ts.inst == nil {
8597
return nil, nil, errors.New("instance not registered")
8698
}
87-
guestPath, err := ts.TranslateHostPath(args.Path)
99+
guestPath, logs, err := ts.TranslateHostPath(args.Path)
88100
if err != nil {
89101
return nil, nil, err
90102
}
@@ -103,12 +115,18 @@ func (ts *ToolSet) WriteFile(_ context.Context,
103115
return nil, nil, err
104116
}
105117
res := &msi.WriteFileResult{}
106-
return &mcp.CallToolResult{
118+
callToolRes := &mcp.CallToolResult{
107119
// Gemini:
108120
// A success message, e.g., `Successfully overwrote file: /path/to/your/file.txt`
109121
// or `Successfully created and wrote to new file: /path/to/new/file.txt.`
110122
StructuredContent: res,
111-
}, res, nil
123+
}
124+
if logs != "" {
125+
callToolRes.Meta = map[string]any{
126+
"io.lima-vm/logs": []string{logs},
127+
}
128+
}
129+
return callToolRes, res, nil
112130
}
113131

114132
func (ts *ToolSet) Glob(_ context.Context,
@@ -124,7 +142,7 @@ func (ts *ToolSet) Glob(_ context.Context,
124142
if args.Path != nil && *args.Path != "" {
125143
pathStr = *args.Path
126144
}
127-
guestPath, err := ts.TranslateHostPath(pathStr)
145+
guestPath, logs, err := ts.TranslateHostPath(pathStr)
128146
if err != nil {
129147
return nil, nil, err
130148
}
@@ -139,11 +157,17 @@ func (ts *ToolSet) Glob(_ context.Context,
139157
res := &msi.GlobResult{
140158
Matches: matches,
141159
}
142-
return &mcp.CallToolResult{
160+
callToolRes := &mcp.CallToolResult{
143161
// Gemini:
144162
// A message like: Found 5 file(s) matching "*.ts" within src, sorted by modification time (newest first):\nsrc/file1.ts\nsrc/subdir/file2.ts...
145163
StructuredContent: res,
146-
}, res, nil
164+
}
165+
if logs != "" {
166+
callToolRes.Meta = map[string]any{
167+
"io.lima-vm/logs": []string{logs},
168+
}
169+
}
170+
return callToolRes, res, nil
147171
}
148172

149173
func (ts *ToolSet) SearchFileContent(ctx context.Context,
@@ -159,7 +183,7 @@ func (ts *ToolSet) SearchFileContent(ctx context.Context,
159183
if args.Path != nil && *args.Path != "" {
160184
pathStr = *args.Path
161185
}
162-
guestPath, err := ts.TranslateHostPath(pathStr)
186+
guestPath, logs, err := ts.TranslateHostPath(pathStr)
163187
if err != nil {
164188
return nil, nil, err
165189
}
@@ -176,9 +200,15 @@ func (ts *ToolSet) SearchFileContent(ctx context.Context,
176200
res := &msi.SearchFileContentResult{
177201
GitGrepOutput: cmdRes.Stdout,
178202
}
179-
return &mcp.CallToolResult{
203+
callToolRes := &mcp.CallToolResult{
180204
// Gemini:
181205
// A message like: Found 10 matching lines for regex "function\\s+myFunction" in directory src:\nsrc/file1.js:10:function myFunction() {...}\nsrc/subdir/file2.ts:45: function myFunction(param) {...}...
182206
StructuredContent: res,
183-
}, res, nil
207+
}
208+
if logs != "" {
209+
callToolRes.Meta = map[string]any{
210+
"io.lima-vm/logs": []string{logs},
211+
}
212+
}
213+
return callToolRes, res, nil
184214
}

pkg/mcp/toolset/shell.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (ts *ToolSet) RunShellCommand(ctx context.Context,
2121
if ts.inst == nil {
2222
return nil, nil, errors.New("instance not registered")
2323
}
24-
guestPath, err := ts.TranslateHostPath(args.Directory)
24+
guestPath, logs, err := ts.TranslateHostPath(args.Directory)
2525
if err != nil {
2626
return nil, nil, err
2727
}
@@ -36,6 +36,7 @@ func (ts *ToolSet) RunShellCommand(ctx context.Context,
3636
Stdout: stdout.String(),
3737
Stderr: stderr.String(),
3838
}
39+
3940
if cmdErr == nil {
4041
res.ExitCode = ptr.Of(0)
4142
} else {
@@ -44,7 +45,13 @@ func (ts *ToolSet) RunShellCommand(ctx context.Context,
4445
res.ExitCode = ptr.Of(st.ExitCode())
4546
}
4647
}
47-
return &mcp.CallToolResult{
48+
callToolRes := &mcp.CallToolResult{
4849
StructuredContent: res,
49-
}, res, nil
50+
}
51+
if logs != "" {
52+
callToolRes.Meta = map[string]any{
53+
"io.lima-vm/logs": []string{logs},
54+
}
55+
}
56+
return callToolRes, res, nil
5057
}

pkg/mcp/toolset/toolset.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,20 @@ func (ts *ToolSet) Close() error {
103103
return err
104104
}
105105

106-
func (ts *ToolSet) TranslateHostPath(hostPath string) (string, error) {
106+
func (ts *ToolSet) TranslateHostPath(hostPath string) (guestPath, logs string, err error) {
107107
if hostPath == "" {
108-
return "", errors.New("path is empty")
108+
return "", "", errors.New("path is empty")
109109
}
110110
if !filepath.IsAbs(hostPath) {
111-
return "", fmt.Errorf("expected an absolute path, got a relative path: %q", hostPath)
111+
return "", "", fmt.Errorf("expected an absolute path, got a relative path: %q", hostPath)
112112
}
113113

114114
guestPath, isMounted := ts.translateToGuestPath(hostPath)
115115
if !isMounted {
116-
logrus.Warnf("path %q is not under any mounted directory, using as guest path", hostPath)
116+
logs = fmt.Sprintf("path %q is not under any mounted directory, using as guest path", hostPath)
117+
logrus.Info(logs)
117118
}
118-
return guestPath, nil
119+
return guestPath, logs, nil
119120
}
120121

121122
func (ts *ToolSet) translateToGuestPath(hostPath string) (string, bool) {

pkg/mcp/toolset/toolset_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func TestTranslateHostPath(t *testing.T) {
2020
hostPath string
2121
toolSet ToolSet
2222
wantGuestPath string
23+
wantLogs bool
2324
wantErr bool
2425
}{
2526
{
@@ -35,6 +36,7 @@ func TestTranslateHostPath(t *testing.T) {
3536
},
3637
},
3738
wantGuestPath: "/mnt/home-user/documents/file.txt",
39+
wantLogs: false,
3840
wantErr: false,
3941
},
4042
{
@@ -50,6 +52,7 @@ func TestTranslateHostPath(t *testing.T) {
5052
},
5153
},
5254
wantGuestPath: "/other/path/file.txt",
55+
wantLogs: true,
5356
wantErr: false,
5457
},
5558
{
@@ -65,6 +68,7 @@ func TestTranslateHostPath(t *testing.T) {
6568
},
6669
},
6770
wantGuestPath: "/home/user2/file.txt",
71+
wantLogs: true,
6872
wantErr: false,
6973
},
7074
{
@@ -81,18 +85,24 @@ func TestTranslateHostPath(t *testing.T) {
8185
},
8286
},
8387
wantGuestPath: "/mnt/tmp/myfile",
88+
wantLogs: false,
8489
wantErr: false,
8590
},
8691
}
8792

8893
for _, test := range tests {
8994
t.Run(test.name, func(t *testing.T) {
90-
got, err := test.toolSet.TranslateHostPath(test.hostPath)
95+
got, logs, err := test.toolSet.TranslateHostPath(test.hostPath)
9196
if test.wantErr {
9297
assert.Assert(t, err != nil)
9398
} else {
9499
assert.NilError(t, err)
95100
assert.Equal(t, test.wantGuestPath, got)
101+
if test.wantLogs {
102+
assert.Assert(t, logs != "")
103+
} else {
104+
assert.Equal(t, "", logs)
105+
}
96106
}
97107
})
98108
}

0 commit comments

Comments
 (0)