mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-12 04:54:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f62b7e0019 | ||
|
|
e98ec6032c | ||
|
|
5c9b0f967f | ||
|
|
cefd6ba7b1 | ||
|
|
d82479c02e | ||
|
|
f6ba02e892 | ||
|
|
2344b38d59 | ||
|
|
2158228ddb | ||
|
|
f4f5135ac2 | ||
|
|
964e987776 | ||
|
|
a7fde76871 | ||
|
|
ed8611d07b | ||
|
|
700c6e818c | ||
|
|
25ee197acd | ||
|
|
a7dcab5146 | ||
|
|
d9d8332f77 | ||
|
|
a4bfdefdab | ||
|
|
32b0a7f69a | ||
|
|
76316de768 | ||
|
|
9abab7a550 |
@@ -1,4 +1,4 @@
|
||||
name: Autoupdate go.mod and go.sum
|
||||
name: Update dependencies
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -6,16 +6,16 @@ on:
|
||||
- cron: "0 3 * * *"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
autoupdate:
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/go-autoupdate.yaml@main
|
||||
update:
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/renovate-autoupdate.yaml@main
|
||||
with:
|
||||
go-version: ">=1.24"
|
||||
release-workflow: "release.yaml"
|
||||
node: false
|
||||
release-workflow: release.yaml
|
||||
lfs: true
|
||||
secrets: inherit
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25'
|
||||
go-version: '1.26'
|
||||
cache: true
|
||||
|
||||
- name: Run golangci-lint
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
release:
|
||||
uses: lukaszraczylo/shared-actions/.github/workflows/go-release-cgo.yaml@main
|
||||
with:
|
||||
go-version: "1.25"
|
||||
go-version: "1.26"
|
||||
rolling-release-tag: "v1"
|
||||
platforms: >-
|
||||
[
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.25'
|
||||
go-version: '1.26'
|
||||
cache: true
|
||||
|
||||
- name: Install govulncheck
|
||||
|
||||
+14
-20
@@ -2,7 +2,7 @@ version: "2"
|
||||
|
||||
run:
|
||||
timeout: 5m
|
||||
go: '1.25'
|
||||
go: '1.26'
|
||||
|
||||
linters:
|
||||
enable:
|
||||
@@ -13,32 +13,26 @@ linters:
|
||||
- unused # Check for unused code
|
||||
- gocyclo # Check cyclomatic complexity
|
||||
- misspell # Check for misspelled words
|
||||
settings:
|
||||
staticcheck:
|
||||
checks: ["all"]
|
||||
exclusions:
|
||||
rules:
|
||||
# Exclude some linters from running on tests
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gocyclo
|
||||
- errcheck
|
||||
- gosec
|
||||
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt # Check formatting
|
||||
|
||||
linters-settings:
|
||||
gocyclo:
|
||||
min-complexity: 15
|
||||
errcheck:
|
||||
check-blank: true
|
||||
govet:
|
||||
enable-all: true
|
||||
staticcheck:
|
||||
checks: ["all"]
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on tests
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gocyclo
|
||||
- errcheck
|
||||
- gosec
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
output:
|
||||
sort-results: true
|
||||
sort-order:
|
||||
- file
|
||||
|
||||
@@ -95,6 +95,24 @@ release:
|
||||
```
|
||||
|
||||
|
||||
homebrew_casks:
|
||||
- name: mcp-filepuff
|
||||
repository:
|
||||
owner: lukaszraczylo
|
||||
name: homebrew-taps
|
||||
token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
|
||||
directory: Casks
|
||||
homepage: https://github.com/lukaszraczylo/filepuff-mcp
|
||||
description: "AST-aware file operations and LSP integration MCP server for Claude Code"
|
||||
license: MIT
|
||||
hooks:
|
||||
post:
|
||||
install: |
|
||||
if OS.mac?
|
||||
system_command "/usr/bin/xattr",
|
||||
args: ["-dr", "com.apple.quarantine", "#{staged_path}/mcp-filepuff"]
|
||||
end
|
||||
|
||||
dockers:
|
||||
- image_templates:
|
||||
- "ghcr.io/lukaszraczylo/filepuff-mcp:{{ .Tag }}"
|
||||
|
||||
@@ -283,7 +283,7 @@ Search for text patterns in files using ripgrep.
|
||||
- `file_types`: File types to search (e.g., ["go", "ts", "py"])
|
||||
- `ignore_case`: Case insensitive search
|
||||
- `regex`: Treat pattern as regex (default: true)
|
||||
- `context_lines`: Number of context lines around matches (default: 2)
|
||||
- `context_lines`: Number of context lines around matches (default: 0)
|
||||
- `max_results`: Maximum number of results to return
|
||||
|
||||
---
|
||||
@@ -352,7 +352,7 @@ Search for AST patterns in code files using structural pattern matching.
|
||||
- `name_matches`: Regex pattern to filter by name
|
||||
- `name_exact`: Exact name to match
|
||||
- `kind_in`: Node types to match (e.g., function_declaration)
|
||||
- `max_results`: Maximum number of results (default: 100)
|
||||
- `max_results`: Maximum number of results (default: 50)
|
||||
|
||||
**Examples**:
|
||||
```json
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ Search for text patterns in files using ripgrep. Supports regex patterns, file t
|
||||
| `file_types` | `array[string]` | No | File types to search (e.g., ['go', 'ts', 'py']) |
|
||||
| `ignore_case` | `boolean` | No | Case insensitive search |
|
||||
| `regex` | `boolean` | No | Treat pattern as regex (default: true) |
|
||||
| `context_lines` | `number` | No | Number of context lines around matches (default: 2) |
|
||||
| `context_lines` | `number` | No | Number of context lines around matches (default: 0) |
|
||||
| `max_results` | `number` | No | Maximum number of results to return |
|
||||
|
||||
**Examples:**
|
||||
@@ -153,7 +153,7 @@ Search for AST patterns in code files. Use code patterns with $VAR placeholders
|
||||
| `name_matches` | `string` | No | Regex pattern to filter by name |
|
||||
| `name_exact` | `string` | No | Exact name to match |
|
||||
| `kind_in` | `array[string]` | No | Node types to match (e.g., function_declaration, class_declaration) |
|
||||
| `max_results` | `number` | No | Maximum number of results to return (default: 100) |
|
||||
| `max_results` | `number` | No | Maximum number of results to return (default: 50) |
|
||||
|
||||
**Examples:**
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
module github.com/lukaszraczylo/mcp-filepuff
|
||||
|
||||
go 1.25.5
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.3.0
|
||||
github.com/goccy/go-json v0.10.6
|
||||
github.com/goccy/go-json v0.11.2
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/mark3labs/mcp-go v0.55.0
|
||||
github.com/mark3labs/mcp-go v1.2.1
|
||||
github.com/sergi/go-diff v1.4.0
|
||||
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@@ -15,8 +15,8 @@ require (
|
||||
require (
|
||||
github.com/google/jsonschema-go v0.4.3 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.3 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
golang.org/x/text v0.38.0 // indirect
|
||||
golang.org/x/text v0.43.0 // indirect
|
||||
)
|
||||
|
||||
@@ -7,8 +7,8 @@ github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxK
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
||||
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-json v0.11.2 h1:jdZv93Tt4ioR8yW1CoNsvSxrcZlCXAUU1aZXN7gpXUA=
|
||||
github.com/goccy/go-json v0.11.2/go.mod h1:3NdmfEkZlB7YI5UFw/qdFKq8XN1aiWR0YyRPWZNQltY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
|
||||
@@ -24,14 +24,14 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mark3labs/mcp-go v0.55.0 h1:lJfz2aoctiwK+sI991+uIYwmKNIBciI+O7zsyDsa4U8=
|
||||
github.com/mark3labs/mcp-go v0.55.0/go.mod h1:+8WclSK1ZUweCP3hvktSji8n8ABG/95QaEkeVE/Uwas=
|
||||
github.com/mark3labs/mcp-go v1.2.1 h1:gd8VD3feMAVycwAM0x1nhv42Q1oLLjfOyowoUzHULB8=
|
||||
github.com/mark3labs/mcp-go v1.2.1/go.mod h1:r2fW4o3wsoJ7IMsx1Wuq5xeP8PRGXPDfNveoGAYbb/s=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.3 h1:1EYB5IzjZawrrnELUi78f9fPu57HuXjmddZPjrls/28=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.3/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 h1:6C8qej6f1bStuePVkLSFxoU22XBS165D3klxlzRg8F4=
|
||||
@@ -44,8 +44,10 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
|
||||
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
|
||||
golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc=
|
||||
golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s=
|
||||
golang.org/x/tools v0.51.0 h1:k4Xc/1Om9jwkBJBo4NVLMSARBoWtK10mx+W5BnXCeAI=
|
||||
golang.org/x/tools v0.51.0/go.mod h1:9eEncMayCV6zRMGhR5eZEC2iBx98qWcF1HZ9Z7wJOoA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -33,7 +33,7 @@ const (
|
||||
DefaultSearchTimeout = 30 * time.Second
|
||||
DefaultMaxFileSize = 10 * 1024 * 1024 // 10 MB
|
||||
DefaultMaxParseSize = 10 * 1024 * 1024 // 10 MB
|
||||
DefaultMaxSearchResults = 1000
|
||||
DefaultMaxSearchResults = 50
|
||||
DefaultMaxEditSize = 100 * 1024 // 100 KB
|
||||
DefaultResourceLinkThresholdBytes = 64 * 1024 // 64 KiB
|
||||
)
|
||||
|
||||
@@ -509,11 +509,15 @@ func formatResults(results []MatchResult, maxResults int, format string, offset
|
||||
case "compact":
|
||||
for i := 0; i < renderCount; i++ {
|
||||
r := results[i]
|
||||
firstLine := firstLineOf(r.Text, 80)
|
||||
if !verbose {
|
||||
fmt.Fprintf(&sb, "%s:%d %s\n", r.File, r.Location.Line, firstLine)
|
||||
continue
|
||||
}
|
||||
nodeType := "unknown"
|
||||
if r.Node != nil {
|
||||
nodeType = r.Node.Type()
|
||||
}
|
||||
firstLine := firstLineOf(r.Text, 80)
|
||||
fmt.Fprintf(&sb, "%s:%d (%s) %s\n", r.File, r.Location.Line, nodeType, firstLine)
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ func (s *Server) resolveASTQueryParams(request mcp.CallToolRequest) (*astQueryPa
|
||||
prefsMaxResults = sp.DefaultMaxResults
|
||||
prefsFormat = sp.ASTQueryFormat
|
||||
}
|
||||
p.maxResults = effectiveInt(request, "max_results", prefsMaxResults, 100)
|
||||
p.maxResults = effectiveInt(request, "max_results", prefsMaxResults, 50)
|
||||
|
||||
p.format = request.GetString("format", "")
|
||||
if p.format == "" {
|
||||
|
||||
@@ -51,7 +51,7 @@ func (s *Server) handleFileSearch(ctx context.Context, request mcp.CallToolReque
|
||||
fileTypes := request.GetStringSlice("file_types", nil)
|
||||
ignoreCase := request.GetBool("ignore_case", false)
|
||||
regex := request.GetBool("regex", true)
|
||||
contextLines := request.GetInt("context_lines", 2)
|
||||
contextLines := request.GetInt("context_lines", 0)
|
||||
|
||||
// Consult session prefs for max_results and cluster when not explicitly supplied.
|
||||
prefs := s.sessionPrefs.Load()
|
||||
|
||||
@@ -49,7 +49,7 @@ const helpFileSearch = "# file_search — flags and examples\n\n" +
|
||||
"| `cluster=true` | Coalesce consecutive match lines into ranges (`L12-14│ text`). Drops context lines for density. |\n" +
|
||||
"| `cursor` | Opaque pagination token from a previous truncated response — fetches next page. |\n" +
|
||||
"| `max_results` | Page size for pagination. Re-run with `cursor` to get next page. |\n" +
|
||||
"| `context_lines` | Number of context lines around matches (default: 2). |\n" +
|
||||
"| `context_lines` | Number of context lines around matches (default: 0). |\n" +
|
||||
"| `ignore_case` | Case-insensitive search. |\n" +
|
||||
"| `regex` | Treat pattern as regex (default: true). |\n" +
|
||||
"| `file_types` | Restrict to file extensions, e.g. `[\"go\", \"ts\"]`. |\n" +
|
||||
@@ -77,7 +77,7 @@ const helpASTQuery = "# ast_query — flags and examples\n\n" +
|
||||
"| `verbose=true` | Emit `Found N match(es):` preamble (v1 behaviour). Default: false. |\n" +
|
||||
"| `format` | `compact` (default, one line per match) \\| `verbose` (full code+captures) \\| `location` (file:line only) |\n" +
|
||||
"| `cursor` | Opaque pagination token from a previous truncated response — fetches next page. |\n" +
|
||||
"| `max_results` | Page size (default: 100). |\n" +
|
||||
"| `max_results` | Page size (default: 50). |\n" +
|
||||
"| `name_exact` | Exact symbol name to match. |\n" +
|
||||
"| `name_matches` | Regex pattern to filter by name. |\n" +
|
||||
"| `kind_in` | Node types to match (e.g. `function_declaration`, `class_declaration`). |\n" +
|
||||
|
||||
@@ -136,7 +136,7 @@ func (s *Server) registerTools() {
|
||||
mcp.Description("Treat pattern as regex (default: true)"),
|
||||
),
|
||||
mcp.WithNumber("context_lines",
|
||||
mcp.Description("Number of context lines around matches (default: 2)"),
|
||||
mcp.Description("Number of context lines around matches (default: 0)"),
|
||||
),
|
||||
mcp.WithNumber("max_results",
|
||||
mcp.Description("Maximum number of results to return (page size for pagination)"),
|
||||
@@ -252,7 +252,7 @@ func (s *Server) registerTools() {
|
||||
mcp.WithStringItems(),
|
||||
),
|
||||
mcp.WithNumber("max_results",
|
||||
mcp.Description("Maximum number of results to return (default: 100, page size for pagination)"),
|
||||
mcp.Description("Maximum number of results to return (default: 50, page size for pagination)"),
|
||||
),
|
||||
mcp.WithString("format",
|
||||
mcp.Description("Output format: \"compact\" (default, one line per match), \"verbose\" (full code+captures), \"location\" (file:line only)"),
|
||||
|
||||
Reference in New Issue
Block a user