Skip to content

Commit 0481043

Browse files
committed
Markdown data retrieval returns error text instead of failure
1 parent d2ca178 commit 0481043

5 files changed

Lines changed: 54 additions & 7 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ src/mcps/wttr/mai-mcp-wttr
55
src/mcps/pipe/mai-mcp-pipe
66
src/mcps/gemcode/mai-mcp-gemcode
77
src/mcps/code/mai-mcp-code
8+
src/mcps/markdown/mai-mcp-markdown

prompts/tool.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ When it is required to call a tool, respond only in JSON without any explanation
5454
"next_step": "What should happen next.",
5555
"action": "Solve | Think | Iterate | Error",
5656
"tool_required": true,
57-
"tool": "tool_provider/tool_name",
57+
"tool": "tool_name",
5858
"tool_params": {
5959
"param1": "value1",
6060
"param2": "value2"

src/mcps/markdown/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Below is a detailed list of tools designed to facilitate interaction with markdo
3535
5. **search(query or queries)**:
3636
- **Function**: Locates and returns sections corresponding to a search query or a list of search queries.
3737
- **Use Case**: Effective for finding multiple terms or keywords without scanning the entire document.
38+
- **Notes**: Search is case-insensitive and supports multi-word phrases as a single query (e.g., `{"query": "multi-word phrase"}`).
3839

3940
6. **summarize(section)**:
4041
- **Function**: Generates a concise summary of a specified section.

src/mcps/markdown/mdown.go

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"regexp"
99
"strings"
10+
"unicode"
1011

1112
"mcplib"
1213
)
@@ -119,7 +120,7 @@ func (s *MDownService) GetTools() []mcplib.Tool {
119120
},
120121
{
121122
Name: "search",
122-
Description: "Locates and returns sections that correspond to a search query or list of search queries.",
123+
Description: "Locates and returns sections that correspond to a search query or list of search queries. If there are no results try with less words",
123124
InputSchema: map[string]any{
124125
"type": "object",
125126
"properties": map[string]any{
@@ -156,16 +157,54 @@ func (s *MDownService) handleListSections(args map[string]any) (any, error) {
156157
return map[string]any{"sections": out}, nil
157158
}
158159

160+
// normalizeSectionName trims surrounding whitespace and punctuation and lowercases the name
161+
func normalizeSectionName(s string) string {
162+
s = strings.TrimSpace(s)
163+
s = strings.TrimFunc(s, func(r rune) bool {
164+
return unicode.IsSpace(r) || unicode.IsPunct(r)
165+
})
166+
return strings.ToLower(s)
167+
}
168+
169+
// handleGetContents retrieves the full content of a given section,
170+
// matching names case-insensitively and ignoring surrounding punctuation.
159171
func (s *MDownService) handleGetContents(args map[string]any) (any, error) {
160172
name, ok := args["section"].(string)
161173
if !ok || name == "" {
162174
return nil, fmt.Errorf("section is required")
163175
}
164176
content, ok := s.sectionContent[name]
165177
if !ok {
178+
norm := normalizeSectionName(name)
179+
// try normalized exact match
180+
for secName, secContent := range s.sectionContent {
181+
if normalizeSectionName(secName) == norm {
182+
content = secContent
183+
ok = true
184+
break
185+
}
186+
}
187+
}
188+
if !ok {
189+
norm := normalizeSectionName(name)
190+
// try normalized substring match
191+
for secName, secContent := range s.sectionContent {
192+
if strings.Contains(normalizeSectionName(secName), norm) {
193+
content = secContent
194+
ok = true
195+
break
196+
}
197+
}
198+
}
199+
if !ok {
200+
return "Section not found", nil
166201
return nil, fmt.Errorf("section %q not found", name)
167202
}
168-
return map[string]any{"content": content}, nil
203+
res := map[string]any{"content": content}
204+
if res != nil {
205+
return res, nil
206+
}
207+
return "", fmt.Errorf("Cannot find contents")
169208
}
170209

171210
func (s *MDownService) handleShowContents(args map[string]any) (any, error) {
@@ -174,8 +213,10 @@ func (s *MDownService) handleShowContents(args map[string]any) (any, error) {
174213
return nil, err
175214
}
176215
content := res.(map[string]any)["content"].(string)
177-
fmt.Println(content)
178-
return nil, nil
216+
if content != "" {
217+
return content, nil
218+
}
219+
return nil, fmt.Errorf("Cannot find contents")
179220
}
180221

181222
func (s *MDownService) handleShowTree(args map[string]any) (any, error) {
@@ -204,8 +245,12 @@ func (s *MDownService) handleSearch(args map[string]any) (any, error) {
204245
}
205246
var matches []string
206247
for name, content := range s.sectionContent {
248+
// Perform case-insensitive matching for search terms, supporting multi-word phrases.
249+
lowerName := strings.ToLower(name)
250+
lowerContent := strings.ToLower(content)
207251
for _, term := range terms {
208-
if strings.Contains(name, term) || strings.Contains(content, term) {
252+
lowerTerm := strings.ToLower(term)
253+
if strings.Contains(lowerName, lowerTerm) || strings.Contains(lowerContent, lowerTerm) {
209254
matches = append(matches, name)
210255
break
211256
}

src/repl/conf.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func NewConfigOptions() *ConfigOptions {
5656
co.RegisterOption("stream", BooleanOption, "Enable streaming mode", "true")
5757
co.RegisterOption("include_replies", BooleanOption, "Include assistant replies in context", "true")
5858
co.RegisterOption("logging", BooleanOption, "Enable conversation logging", "true")
59-
co.RegisterOption("reasoning", BooleanOption, "Enable AI reasoning", "true")
59+
co.RegisterOption("reasoning", BooleanOption, "Enable AI reasoning", "false")
6060
co.RegisterOption("markdown", BooleanOption, "Enable markdown rendering with colors", "false")
6161
co.RegisterOption("max_tokens", NumberOption, "Maximum tokens for AI response", "5128")
6262
co.RegisterOption("temperature", NumberOption, "Temperature for AI response (0.0-1.0)", "0.7")

0 commit comments

Comments
 (0)