mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-06-05 22:23:50 +00:00
5ad975ee7a
* v2.0: token-optimization overhaul Additive (backward-compatible flags): - file_read: skeleton mode, strip (imports/license/block_comments), compact_line_numbers, 8-char etag with prefix-match compat - ast_query: format=verbose|compact|location, pagination cursor - file_search: cluster mode, pagination cursor - lsp_query (references): compact output Breaking (v2): - Preambles removed; opt-in verbose=true restores - edit_apply: response=count|diff|none, default count - ping tool removed - symbol_at/find_definition/find_references merged into lsp_query - Tool descriptions trimmed -83%, help moved to filepuff://help/<tool> - Batch file_read dedups by etag Protocol: - ResourceLink returned for file_read >64 KiB (force_inline override) - OnAfterInitialize hook reads capabilities.experimental.filepuff for session defaults (default_format, default_max_results, default_cluster, compact_refs, line_numbers, resource_link_threshold) * fix: drop --max-total-count from ripgrep args The flag does not exist in stable ripgrep (confirmed up to 15.1.0 -- "unrecognized flag --max-total-count, similar flags that are available: --max-count"). Every file_search call failed on hosts with stock rg. --max-count is per-file, not a drop-in replacement, so rely on the in-process truncation in parseOutput that was already the documented safety net.
91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
)
|
|
|
|
func TestRegisterResources_AllToolsHaveResource(t *testing.T) {
|
|
// Verify that registerResources wires up without panicking.
|
|
_ = newTestServer(t, t.TempDir())
|
|
|
|
expectedURIs := []string{
|
|
"filepuff://help/file_read",
|
|
"filepuff://help/file_search",
|
|
"filepuff://help/ast_query",
|
|
"filepuff://help/lsp_query",
|
|
"filepuff://help/edit_apply",
|
|
}
|
|
|
|
for _, uri := range expectedURIs {
|
|
t.Run(uri, func(t *testing.T) {
|
|
handler := readHelpResource(uri)
|
|
contents, err := handler(context.Background(), mcp.ReadResourceRequest{})
|
|
if err != nil {
|
|
t.Fatalf("readHelpResource(%q) error = %v", uri, err)
|
|
}
|
|
if len(contents) == 0 {
|
|
t.Fatalf("readHelpResource(%q) returned empty contents", uri)
|
|
}
|
|
tc, ok := contents[0].(mcp.TextResourceContents)
|
|
if !ok {
|
|
t.Fatalf("readHelpResource(%q) contents[0] is not TextResourceContents", uri)
|
|
}
|
|
if tc.MIMEType != "text/markdown" {
|
|
t.Errorf("MIMEType = %q, want %q", tc.MIMEType, "text/markdown")
|
|
}
|
|
if len(tc.Text) == 0 {
|
|
t.Errorf("Text is empty for %q", uri)
|
|
}
|
|
if !strings.HasPrefix(tc.Text, "#") {
|
|
t.Errorf("expected markdown (# heading) for %q, got: %q", uri, tc.Text[:min(50, len(tc.Text))])
|
|
}
|
|
if tc.URI != uri {
|
|
t.Errorf("URI = %q, want %q", tc.URI, uri)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadHelpResource_UnknownTool(t *testing.T) {
|
|
handler := readHelpResource("filepuff://help/nonexistent")
|
|
_, err := handler(context.Background(), mcp.ReadResourceRequest{})
|
|
if err == nil {
|
|
t.Fatal("expected error for unknown tool, got nil")
|
|
}
|
|
}
|
|
|
|
func TestReadHelpResource_InvalidURI(t *testing.T) {
|
|
handler := readHelpResource("filepuff://help/")
|
|
_, err := handler(context.Background(), mcp.ReadResourceRequest{})
|
|
if err == nil {
|
|
t.Fatal("expected error for empty tool name, got nil")
|
|
}
|
|
}
|
|
|
|
func TestHelpContent_NotEmpty(t *testing.T) {
|
|
cases := map[string]string{
|
|
"file_read": helpFileRead,
|
|
"file_search": helpFileSearch,
|
|
"ast_query": helpASTQuery,
|
|
"lsp_query": helpLSPQuery,
|
|
"edit_apply": helpEditApply,
|
|
}
|
|
for name, content := range cases {
|
|
t.Run(name, func(t *testing.T) {
|
|
if len(content) == 0 {
|
|
t.Errorf("help content for %q is empty", name)
|
|
}
|
|
if !strings.Contains(content, "##") {
|
|
t.Errorf("expected markdown sections (##) in help content for %q", name)
|
|
}
|
|
if !strings.Contains(content, "```") {
|
|
t.Errorf("expected code fences in help content for %q", name)
|
|
}
|
|
})
|
|
}
|
|
}
|