Skip to content

Commit ac95406

Browse files
committed
update todos
1 parent 4f524d3 commit ac95406

File tree

2 files changed

+61
-52
lines changed

2 files changed

+61
-52
lines changed

internal/builtin/todo.go

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,36 @@ func (ts *TodoServer) getTodos() []TodoInfo {
8989
return todos
9090
}
9191

92+
// formatTodos returns a nice readable format for todos
93+
func formatTodos(todos []TodoInfo) string {
94+
if len(todos) == 0 {
95+
return "\n\nNo todos"
96+
}
97+
98+
var result strings.Builder
99+
result.WriteString("\n\n")
100+
for _, todo := range todos {
101+
var checkbox string
102+
switch todo.Status {
103+
case "completed":
104+
checkbox = "[X]"
105+
case "in_progress":
106+
checkbox = "[~]"
107+
default: // pending
108+
checkbox = "[ ]"
109+
}
110+
result.WriteString(fmt.Sprintf("%s %s\n", checkbox, todo.Content))
111+
}
112+
113+
// Remove trailing newline
114+
output := result.String()
115+
if len(output) > 0 {
116+
output = output[:len(output)-1]
117+
}
118+
119+
return output
120+
}
121+
92122
// setTodos stores todos in memory
93123
func (ts *TodoServer) setTodos(todos []TodoInfo) {
94124
ts.mutex.Lock()
@@ -136,24 +166,12 @@ func (ts *TodoServer) executeTodoWrite(ctx context.Context, request mcp.CallTool
136166
// Store todos in memory
137167
ts.setTodos(todos)
138168

139-
// Count non-completed todos
140-
activeTodos := 0
141-
for _, todo := range todos {
142-
if todo.Status != "completed" {
143-
activeTodos++
144-
}
145-
}
146-
147-
// Format output
148-
output, err := json.MarshalIndent(todos, "", " ")
149-
if err != nil {
150-
return mcp.NewToolResultError("failed to format todos"), nil
151-
}
169+
// Format output in readable format
170+
output := formatTodos(todos)
152171

153-
// Create result with metadata
154-
result := mcp.NewToolResultText(string(output))
172+
// Create result with formatted output
173+
result := mcp.NewToolResultText(output)
155174
result.Meta = map[string]any{
156-
"title": fmt.Sprintf("%d todos", activeTodos),
157175
"todos": todos,
158176
}
159177

@@ -165,24 +183,12 @@ func (ts *TodoServer) executeTodoRead(ctx context.Context, request mcp.CallToolR
165183
// Get todos from memory
166184
todos := ts.getTodos()
167185

168-
// Count non-completed todos
169-
activeTodos := 0
170-
for _, todo := range todos {
171-
if todo.Status != "completed" {
172-
activeTodos++
173-
}
174-
}
175-
176-
// Format output
177-
output, err := json.MarshalIndent(todos, "", " ")
178-
if err != nil {
179-
return mcp.NewToolResultError("failed to format todos"), nil
180-
}
186+
// Format output in readable format
187+
output := formatTodos(todos)
181188

182-
// Create result with metadata
183-
result := mcp.NewToolResultText(string(output))
189+
// Create result with formatted output
190+
result := mcp.NewToolResultText(output)
184191
result.Meta = map[string]any{
185-
"title": fmt.Sprintf("%d todos", activeTodos),
186192
"todos": todos,
187193
}
188194

internal/builtin/todo_test.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package builtin
22

33
import (
44
"context"
5-
"encoding/json"
65
"testing"
76

87
"github.com/mark3labs/mcp-go/mcp"
@@ -102,13 +101,11 @@ func TestTodoWrite(t *testing.T) {
102101
t.Errorf("Expected 2 todos, got %d", len(storedTodos))
103102
}
104103

105-
// Verify the content
104+
// Verify the content is in readable format
106105
if textContent, ok := mcp.AsTextContent(result.Content[0]); ok {
107-
var resultTodos []TodoInfo
108-
if err := json.Unmarshal([]byte(textContent.Text), &resultTodos); err != nil {
109-
t.Errorf("Failed to parse result JSON: %v", err)
110-
} else if len(resultTodos) != 2 {
111-
t.Errorf("Expected 2 todos in result, got %d", len(resultTodos))
106+
expectedOutput := "\n\n[ ] Test task 1\n[~] Test task 2"
107+
if textContent.Text != expectedOutput {
108+
t.Errorf("Expected formatted output:\n%s\nGot:\n%s", expectedOutput, textContent.Text)
112109
}
113110
} else {
114111
t.Error("Expected text content")
@@ -148,15 +145,11 @@ func TestTodoRead(t *testing.T) {
148145
t.Fatal("Expected result to have content")
149146
}
150147

151-
// Verify the content
148+
// Verify the content is in readable format
152149
if textContent, ok := mcp.AsTextContent(result.Content[0]); ok {
153-
var resultTodos []TodoInfo
154-
if err := json.Unmarshal([]byte(textContent.Text), &resultTodos); err != nil {
155-
t.Errorf("Failed to parse result JSON: %v", err)
156-
} else if len(resultTodos) != 1 {
157-
t.Errorf("Expected 1 todo in result, got %d", len(resultTodos))
158-
} else if resultTodos[0].Content != "Existing task" {
159-
t.Errorf("Expected 'Existing task', got '%s'", resultTodos[0].Content)
150+
expectedOutput := "\n\n[ ] Existing task"
151+
if textContent.Text != expectedOutput {
152+
t.Errorf("Expected formatted output:\n%s\nGot:\n%s", expectedOutput, textContent.Text)
160153
}
161154
} else {
162155
t.Error("Expected text content")
@@ -282,17 +275,27 @@ func TestTodoActiveCounting(t *testing.T) {
282275
t.Fatalf("Failed to execute todowrite: %v", err)
283276
}
284277

285-
// Check metadata for correct active count (should be 3: 2 pending + 1 in_progress)
278+
// Check that metadata contains todos
286279
if result.Meta == nil {
287280
t.Fatal("Expected metadata to be non-nil")
288281
}
289282

290-
title, ok := result.Meta["title"].(string)
283+
metaTodos, ok := result.Meta["todos"].([]TodoInfo)
291284
if !ok {
292-
t.Fatal("Expected title in metadata")
285+
t.Fatal("Expected todos in metadata")
293286
}
294287

295-
if title != "3 todos" {
296-
t.Errorf("Expected '3 todos', got '%s'", title)
288+
if len(metaTodos) != 4 {
289+
t.Errorf("Expected 4 todos in metadata, got %d", len(metaTodos))
290+
}
291+
292+
// Verify the content is in readable format
293+
if textContent, ok := mcp.AsTextContent(result.Content[0]); ok {
294+
expectedOutput := "\n\n[ ] Task 1\n[~] Task 2\n[X] Task 3\n[ ] Task 4"
295+
if textContent.Text != expectedOutput {
296+
t.Errorf("Expected formatted output:\n%s\nGot:\n%s", expectedOutput, textContent.Text)
297+
}
298+
} else {
299+
t.Error("Expected text content")
297300
}
298301
}

0 commit comments

Comments
 (0)