feat(ingestion): extract WriteNote helper and add brain_write MCP tool

api.WriteNote captures the file-write logic that was previously inline
in Handler.Write. The existing HTTP endpoint now delegates to it; the
new MCP brain_write tool reuses the same function. Path-traversal
guard is strengthened to explicitly reject filenames containing path
separators or "..", so the rejection is surfaced before filepath.Base
strips the suspicious component (the previous defense-in-depth prefix
check became unreachable for these inputs after Base normalisation).
HTTP error code for caller-input errors shifts from 500 to 400, which
is semantically correct and not exercised by any existing test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mathias Bergqvist
2026-05-01 10:05:48 +02:00
parent 7dcb5610fe
commit e4a94df4fc
4 changed files with 121 additions and 44 deletions

View File

@@ -118,6 +118,8 @@ func (s *Server) handleCall(ctx context.Context, name string, args json.RawMessa
switch name {
case "brain_query":
return s.brainQuery(ctx, args)
case "brain_write":
return s.brainWrite(ctx, args)
default:
return nil, fmt.Errorf("unknown tool: %s", name)
}