mcp-fs-shell-windows 0.2.19 → 0.2.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +2 -1
  2. package/README.md +352 -190
  3. package/dist/analyze_project/handler.js +62 -0
  4. package/dist/analyze_project/schema.js +5 -0
  5. package/dist/browser/browserActions.js +128 -0
  6. package/dist/browser/fuzzySearch.js +49 -0
  7. package/dist/browser/handler.js +227 -0
  8. package/dist/browser/launcher.js +103 -0
  9. package/dist/browser/schema.js +37 -0
  10. package/dist/browser/session.js +14 -0
  11. package/dist/compat/handler.js +254 -0
  12. package/dist/compat/schema.js +97 -0
  13. package/dist/gh/handler.js +406 -0
  14. package/dist/gh/schema.js +36 -0
  15. package/dist/git/handler.js +209 -0
  16. package/dist/git/schema.js +23 -0
  17. package/dist/launch_file/handler.js +3 -1
  18. package/dist/query_database/handler.js +27 -0
  19. package/dist/query_database/schema.js +5 -0
  20. package/dist/rag/handler.js +103 -0
  21. package/dist/rag/helpers.js +126 -0
  22. package/dist/rag/schema.js +16 -0
  23. package/dist/read_document/handler.js +61 -0
  24. package/dist/read_document/schema.js +4 -0
  25. package/dist/run_javascript/handler.js +124 -0
  26. package/dist/run_javascript/schema.js +28 -0
  27. package/dist/server.js +885 -1
  28. package/dist/shell/handler.js +14 -6
  29. package/dist/subagent/handler.js +752 -0
  30. package/dist/subagent/handoffMessage.js +56 -0
  31. package/dist/subagent/schema.js +18 -0
  32. package/dist/subagent/subAgentToolCallParser.js +491 -0
  33. package/dist/subagent/toolCallValidator.js +97 -0
  34. package/dist/system/handler.js +239 -0
  35. package/dist/system/schema.js +21 -0
  36. package/dist/web/ddgParse.js +51 -0
  37. package/dist/web/handler.js +286 -0
  38. package/dist/web/schema.js +18 -0
  39. package/package.json +22 -2
package/dist/server.js CHANGED
@@ -42,6 +42,32 @@ import { ShellCancelArgsSchema } from "./shell/schema.js";
42
42
  import { ShellTerminalArgsSchema } from "./shell/schema.js";
43
43
  import { ShellPythonArgsSchema } from "./shell/schema.js";
44
44
  import { ShellCwdArgsSchema } from "./shell/schema.js";
45
+ import { RunJavascriptFreeArgsSchema } from "./run_javascript/schema.js";
46
+ import { GitStatusArgsSchema } from "./git/schema.js";
47
+ import { GitDiffArgsSchema } from "./git/schema.js";
48
+ import { GitCommitArgsSchema } from "./git/schema.js";
49
+ import { GitLogArgsSchema } from "./git/schema.js";
50
+ import { GitAddArgsSchema } from "./git/schema.js";
51
+ import { GitCheckoutArgsSchema } from "./git/schema.js";
52
+ import { GhAuthArgsSchema } from "./gh/schema.js";
53
+ import { GhCreateIssueArgsSchema } from "./gh/schema.js";
54
+ import { GhListIssuesArgsSchema } from "./gh/schema.js";
55
+ import { GhViewCommentsArgsSchema } from "./gh/schema.js";
56
+ import { GhCreatePrArgsSchema } from "./gh/schema.js";
57
+ import { GhListPrsArgsSchema } from "./gh/schema.js";
58
+ import { GhViewPrDiffArgsSchema } from "./gh/schema.js";
59
+ import { GhPushArgsSchema } from "./gh/schema.js";
60
+ import { GetSystemInfoArgsSchema } from "./system/schema.js";
61
+ import { ReadClipboardArgsSchema } from "./system/schema.js";
62
+ import { WriteClipboardArgsSchema } from "./system/schema.js";
63
+ import { SendNotificationArgsSchema } from "./system/schema.js";
64
+ import { OpenFileArgsSchema } from "./system/schema.js";
65
+ import { PreviewHtmlArgsSchema } from "./system/schema.js";
66
+ import { ReadDocumentArgsSchema } from "./read_document/schema.js";
67
+ import { QueryDatabaseArgsSchema } from "./query_database/schema.js";
68
+ import { AnalyzeProjectArgsSchema } from "./analyze_project/schema.js";
69
+ import { WebSearchArgsSchema, FetchWebContentArgsSchema, WikipediaSearchArgsSchema, } from "./web/schema.js";
70
+ import { RagLocalFilesArgsSchema, RagWebContentArgsSchema } from "./rag/schema.js";
45
71
  // Import all handlers
46
72
  import { handleReadFiles } from "./read_files/handler.js";
47
73
  import { handleWriteNewFiles } from "./write_new_files/handler.js";
@@ -81,6 +107,38 @@ import { handleShellCancel } from "./shell/handler.js";
81
107
  import { handleShellTerminal } from "./shell/handler.js";
82
108
  import { handleShellPython } from "./shell/handler.js";
83
109
  import { handleShellCwd } from "./shell/handler.js";
110
+ import { handleRunJavascriptFree } from "./run_javascript/handler.js";
111
+ import { handleGitStatus } from "./git/handler.js";
112
+ import { handleGitDiff } from "./git/handler.js";
113
+ import { handleGitCommit } from "./git/handler.js";
114
+ import { handleGitLog } from "./git/handler.js";
115
+ import { handleGitAdd } from "./git/handler.js";
116
+ import { handleGitCheckout } from "./git/handler.js";
117
+ import { handleGhAuth } from "./gh/handler.js";
118
+ import { handleGhCreateIssue } from "./gh/handler.js";
119
+ import { handleGhListIssues } from "./gh/handler.js";
120
+ import { handleGhViewComments } from "./gh/handler.js";
121
+ import { handleGhCreatePr } from "./gh/handler.js";
122
+ import { handleGhListPrs } from "./gh/handler.js";
123
+ import { handleGhViewPrDiff } from "./gh/handler.js";
124
+ import { handleGhPush } from "./gh/handler.js";
125
+ import { handleGetSystemInfo } from "./system/handler.js";
126
+ import { handleReadClipboard } from "./system/handler.js";
127
+ import { handleWriteClipboard } from "./system/handler.js";
128
+ import { handleSendNotification } from "./system/handler.js";
129
+ import { handleOpenFile } from "./system/handler.js";
130
+ import { handlePreviewHtml } from "./system/handler.js";
131
+ import { handleReadDocument } from "./read_document/handler.js";
132
+ import { handleQueryDatabase } from "./query_database/handler.js";
133
+ import { handleAnalyzeProject } from "./analyze_project/handler.js";
134
+ import { handleWebSearch, handleFetchWebContent, handleWikipediaSearch, } from "./web/handler.js";
135
+ import { handleRagLocalFiles, handleRagWebContent } from "./rag/handler.js";
136
+ import { BrowserSessionOpenArgsSchema, BrowserSessionControlArgsSchema, BrowserSessionCloseArgsSchema, BrowserOpenPageArgsSchema, } from "./browser/schema.js";
137
+ import { handleBrowserSessionOpen, handleBrowserSessionControl, handleBrowserSessionClose, handleBrowserOpenPage, } from "./browser/handler.js";
138
+ import { ExecuteCommandArgsSchema, RunInTerminalArgsSchema, RunTestCommandArgsSchema, RunBackgroundCommandArgsSchema, CheckBackgroundCommandArgsSchema, CancelBackgroundCommandArgsSchema, RunPythonArgsSchema, RunJavascriptArgsSchema, SaveMemoryArgsSchema, } from "./compat/schema.js";
139
+ import { handleExecuteCommand, handleRunInTerminal, handleRunTestCommand, handleRunBackgroundCommand, handleCheckBackgroundCommand, handleCancelBackgroundCommand, handleRunPython, handleRunJavascript, handleSaveMemory, } from "./compat/handler.js";
140
+ import { ConsultSecondaryAgentArgsSchema } from "./subagent/schema.js";
141
+ import { handleConsultSecondaryAgent } from "./subagent/handler.js";
84
142
  const ToolInputSchema = ToolSchema.shape.inputSchema;
85
143
  export class FilesystemServer {
86
144
  server;
@@ -89,7 +147,7 @@ export class FilesystemServer {
89
147
  this.allowedDirectories = allowedDirectories;
90
148
  this.server = new Server({
91
149
  name: "secure-filesystem-server",
92
- version: "0.2.19",
150
+ version: "0.2.29",
93
151
  }, {
94
152
  capabilities: {
95
153
  tools: {},
@@ -467,6 +525,388 @@ export class FilesystemServer {
467
525
  "Only works within allowed directories.",
468
526
  inputSchema: zodToJsonSchema(WaitForFileArgsSchema),
469
527
  },
528
+ {
529
+ name: "run_javascript_free",
530
+ description: "Run a JavaScript/TypeScript code snippet on the Deno runtime with UNRESTRICTED permissions: full filesystem read/write (any drive or UNC path the server user can reach), network access, environment variables, child processes, and arbitrary imports (node:*, npm:*, https:*) - unlike the other run_javascript tools, there is no working-directory sandbox. " +
531
+ "The code is written to a temp .ts file and run; returns exit code, stdout, and stderr. " +
532
+ "Default 5 s timeout, max 60 s; optional cwd (defaults to the shell_cwd default). " +
533
+ "Non-zero exit or timeout returns an error that still includes the captured output. " +
534
+ "Requires a Deno binary: $DENO_PATH, <LM Studio home>/.internal/utils/deno(.exe) (found by walking up from the server CWD or the user home), or deno on PATH.",
535
+ inputSchema: zodToJsonSchema(RunJavascriptFreeArgsSchema),
536
+ },
537
+ {
538
+ name: "git_status",
539
+ description: "Get the current git status of the repository at the server process's current working directory (the directory the server was launched in, e.g. the chat working directory; no path argument). " +
540
+ "Returns JSON text: {current (branch name; null for detached HEAD), tracking (upstream branch or null), ahead, behind, isClean, staged: [], notStaged: [], untracked: [], files: [{path, index, working_dir}]}. " +
541
+ "If the working directory is not inside a git repository, returns a clear {error} string (not a crash).",
542
+ inputSchema: zodToJsonSchema(GitStatusArgsSchema),
543
+ },
544
+ {
545
+ name: "git_diff",
546
+ description: "Get the git diff of the repository at the server process's current working directory or specific files. " +
547
+ "file_path (optional): path to a specific file to diff, resolved relative to the working directory. " +
548
+ "cached (optional): show staged changes only (git diff --cached). " +
549
+ "Returns JSON text: {diff} with the unified diff (\"No changes.\" when there is nothing to show), or a clear {error} string if the working directory is not inside a git repository.",
550
+ inputSchema: zodToJsonSchema(GitDiffArgsSchema),
551
+ },
552
+ {
553
+ name: "git_commit",
554
+ description: "Commit staged changes to the git repository at the server process's current working directory. " +
555
+ "Standard git behavior: commits only what is staged (stage first with git_add). " +
556
+ "Returns JSON text: {success: true, summary: {changed, insertions, deletions}}, or a clear {error} string (e.g. when nothing is staged).",
557
+ inputSchema: zodToJsonSchema(GitCommitArgsSchema),
558
+ },
559
+ {
560
+ name: "git_log",
561
+ description: "Get recent git commit history from the repository at the server process's current working directory. " +
562
+ "max_count (optional): max number of commits to return (default: 10). " +
563
+ "Returns JSON text: {history: ['<hash> <subject> (<author>, <date relative>)', ...]}, newest first, or a clear {error} string (e.g. when the repo has no commits).",
564
+ inputSchema: zodToJsonSchema(GitLogArgsSchema),
565
+ },
566
+ {
567
+ name: "git_add",
568
+ description: "Stage specific files or all changes for the next commit, in the repository at the server process's current working directory. " +
569
+ "paths (optional): specific file paths to stage, resolved relative to the working directory; if omitted, stages all changes (git add .). " +
570
+ "Returns JSON text: {success: true, message}, or a clear {error} string.",
571
+ inputSchema: zodToJsonSchema(GitAddArgsSchema),
572
+ },
573
+ {
574
+ name: "git_checkout",
575
+ description: "Switch to an existing branch, or create and switch to a new one, in the repository at the server process's current working directory. " +
576
+ "branch_name: name of the branch to checkout. " +
577
+ "create_new (optional, default false): if true, creates the branch if it doesn't exist (like git checkout -b). " +
578
+ "Returns JSON text: {success: true, message}, or a clear {error} string (e.g. branch does not exist, or uncommitted changes would be overwritten).",
579
+ inputSchema: zodToJsonSchema(GitCheckoutArgsSchema),
580
+ },
581
+ {
582
+ name: "gh_auth",
583
+ description: "Check GitHub authentication status. If not authenticated, opens a detached terminal window (cmd /k) for the user to sign in. " +
584
+ "Runs `gh auth status`; on failure spawns `cmd.exe /c start ... cmd.exe /k \"<gh> auth login --git-protocol=https & exit\"` detached with ignored stdio, so the window outlives the tool call and stays open for interactive sign-in (the resolved absolute gh path is used, so the window works even when gh is not on the server's PATH). " +
585
+ "Returns JSON text: {success: true, message} (\"Already authenticated with GitHub.\" or \"Opened a terminal window for GitHub authentication. Please sign in there.\"), or a clear {error} string (e.g. the gh CLI is not installed).",
586
+ inputSchema: zodToJsonSchema(GhAuthArgsSchema),
587
+ },
588
+ {
589
+ name: "gh_create_issue",
590
+ description: "Create a new GitHub issue in the repository at the server process's current working directory (no path argument; the repo is resolved from the working directory's git remote, exactly as the reference tools do). " +
591
+ "title: the issue title. " +
592
+ "body (optional): the issue body — written to a temp file in the working directory and passed via --body-file (always cleaned up). " +
593
+ "labels (optional): label names, each added as -l. " +
594
+ "Returns JSON text: {success: true, url} with the new issue's URL, or a clear {error} string (e.g. repository not found, not authenticated).",
595
+ inputSchema: zodToJsonSchema(GhCreateIssueArgsSchema),
596
+ },
597
+ {
598
+ name: "gh_list_issues",
599
+ description: "List issues in the repository at the server process's current working directory. " +
600
+ "state (optional, default \"open\"): \"open\" or \"closed\". " +
601
+ "labels (optional): filter by label names (each added as -l). " +
602
+ "limit (optional, default 10, max 50): maximum number of issues to return. " +
603
+ "Returns JSON text: {issues: [{number, title, state, url, labels}]}, an empty array when there are no matches, or a clear {error} string.",
604
+ inputSchema: zodToJsonSchema(GhListIssuesArgsSchema),
605
+ },
606
+ {
607
+ name: "gh_view_comments",
608
+ description: "View comments on a specific issue or pull request in the repository at the server process's current working directory. " +
609
+ "number: the issue or PR number. " +
610
+ "type (optional, default \"issue\"): \"issue\" or \"pr\". " +
611
+ "Returns JSON text: {comments: [...]} with the GitHub comment objects, or a clear {error} string.",
612
+ inputSchema: zodToJsonSchema(GhViewCommentsArgsSchema),
613
+ },
614
+ {
615
+ name: "gh_create_pr",
616
+ description: "Create a new pull request in the repository at the server process's current working directory (no path argument; the repo is resolved from the working directory's git remote). " +
617
+ "title: the PR title. " +
618
+ "head_branch: the branch containing your changes. " +
619
+ "base_branch (optional, default \"main\"): the branch to merge into (e.g. main, master). " +
620
+ "body (optional): the PR description — written to a temp file in the working directory and passed via --body-file (always cleaned up). " +
621
+ "Returns JSON text: {success: true, url} with the new PR's URL, or a clear {error} string (e.g. head branch not found).",
622
+ inputSchema: zodToJsonSchema(GhCreatePrArgsSchema),
623
+ },
624
+ {
625
+ name: "gh_list_prs",
626
+ description: "List pull requests in the repository at the server process's current working directory. " +
627
+ "state (optional, default \"open\"): \"open\" or \"closed\". " +
628
+ "limit (optional, default 10, max 50): maximum number of PRs to return. " +
629
+ "Returns JSON text: {pull_requests: [{number, title, state, url, headRefName, baseRefName}]}, an empty array when there are no matches, or a clear {error} string.",
630
+ inputSchema: zodToJsonSchema(GhListPrsArgsSchema),
631
+ },
632
+ {
633
+ name: "gh_view_pr_diff",
634
+ description: "Fetch the diff/patch of a specific pull request in the repository at the server process's current working directory. " +
635
+ "number: the PR number. " +
636
+ "Returns JSON text: {diff} with the unified diff (truncated to 50,000 characters with a \"... (truncated)\" marker), or a clear {error} string.",
637
+ inputSchema: zodToJsonSchema(GhViewPrDiffArgsSchema),
638
+ },
639
+ {
640
+ name: "gh_push",
641
+ description: "Push local commits to the remote GitHub repository in the server process's current working directory (git push origin [branch]). " +
642
+ "branch (optional): the branch to push; defaults to the current branch. " +
643
+ "Returns JSON text: {success: true, message}, or a clear {error} string (e.g. remote not found, no upstream branch, authentication required).",
644
+ inputSchema: zodToJsonSchema(GhPushArgsSchema),
645
+ },
646
+ {
647
+ name: "get_system_info",
648
+ description: "Get information about the system (OS, CPU, Memory). No parameters. " +
649
+ "Returns JSON text: {platform, arch, release, hostname, total_memory, free_memory, cpus, node_version} " +
650
+ "(memory in bytes; cpus = number of logical CPUs; node_version = the Node.js version running this server).",
651
+ inputSchema: zodToJsonSchema(GetSystemInfoArgsSchema),
652
+ },
653
+ {
654
+ name: "read_clipboard",
655
+ description: "Read text content from the system clipboard. No parameters. " +
656
+ "On Windows uses `powershell -command Get-Clipboard` (macOS: pbpaste; other: xclip) with a 5-second timeout. " +
657
+ "An empty clipboard returns content \"\" (not an error). " +
658
+ "Returns JSON text: {content}, or a clear error if the read fails or times out.",
659
+ inputSchema: zodToJsonSchema(ReadClipboardArgsSchema),
660
+ },
661
+ {
662
+ name: "write_clipboard",
663
+ description: "Write text content to the system clipboard. content: the text to store (UTF-8). " +
664
+ "On Windows the content is base64-encoded into the PowerShell command line and Set-Clipboard stores the decoded text, " +
665
+ "so quotes, newlines, and Unicode need no escaping. " +
666
+ "macOS: pbcopy; other: xclip via stdin. 5-second timeout. " +
667
+ "Returns JSON text: {success: true}, or a clear error if the write fails or times out.",
668
+ inputSchema: zodToJsonSchema(WriteClipboardArgsSchema),
669
+ },
670
+ {
671
+ name: "send_notification",
672
+ description: "Send a system notification to the user (a Windows toast via the bundled snoretoast on this machine; node-notifier backends elsewhere). " +
673
+ "title: the notification title. message: the notification body. " +
674
+ "Dispatched fire-and-forget (sound: true, wait: false). " +
675
+ "Returns JSON text: {success: true, message}.",
676
+ inputSchema: zodToJsonSchema(SendNotificationArgsSchema),
677
+ },
678
+ {
679
+ name: "open_file",
680
+ description: "Open a file path or http(s) URL in the system's default application (the OS default: e.g. VLC for .mkv/.mp4, Explorer for folders, the default browser for web links). " +
681
+ "target: file path or URL. " +
682
+ "The Beledarian-named equivalent of launch_file - it delegates to the same internal launch helper: " +
683
+ "filesystem targets are subject to the allowed-roots policy and checked for existence; " +
684
+ "only http:// and https:// links are launched as URLs (every other scheme is rejected). " +
685
+ "Returns JSON text: {success: true, message}, or a clear error (e.g. path does not exist, unsupported URL scheme).",
686
+ inputSchema: zodToJsonSchema(OpenFileArgsSchema),
687
+ },
688
+ {
689
+ name: "preview_html",
690
+ description: "Render and preview HTML content in the system's default browser. " +
691
+ "html_content: the HTML to render. " +
692
+ "file_name (optional): name for the temp file (default: a timestamped preview_<ts>.html; " +
693
+ "only the final path segment is used - the file always lands in the system temp dir, and an existing file of that name is overwritten). " +
694
+ "The temp file is written, launched in the default browser (same detached opener as launch_file), and left on disk. " +
695
+ "Returns JSON text: {success: true, path, message} with the temp file path.",
696
+ inputSchema: zodToJsonSchema(PreviewHtmlArgsSchema),
697
+ },
698
+ {
699
+ name: "read_document",
700
+ description: "Read content from PDF or DOCX files. " +
701
+ "PDF via pdf-parse v2 class-based API (new PDFParse({data}), getText/getInfo/destroy) returning JSON text: {content, metadata}; " +
702
+ "DOCX via mammoth extractRawText returning {content, messages}. " +
703
+ "Unsupported extensions return the error 'Unsupported document format. Use read_file for text files.' " +
704
+ "Other failures are wrapped as {error: 'Failed to read document: ...'}. " +
705
+ "Only works within allowed directories.",
706
+ inputSchema: zodToJsonSchema(ReadDocumentArgsSchema),
707
+ },
708
+ {
709
+ name: "query_database",
710
+ description: "Execute a read-only query on a SQLite database file. " +
711
+ "Implemented on Node's built-in node:sqlite (DatabaseSync opened with readOnly: true) - no native dependency. " +
712
+ "Write statements (INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/REPLACE) are blocked up-front with the error 'Only SELECT/read queries are allowed for safety.' " +
713
+ "Returns JSON text: {results} (array of row objects from prepare().all()), or {error: 'Database query failed: ...'}. " +
714
+ "Only works within allowed directories.",
715
+ inputSchema: zodToJsonSchema(QueryDatabaseArgsSchema),
716
+ },
717
+ {
718
+ name: "analyze_project",
719
+ description: "Run project-wide analysis (linting) to find errors and warnings. " +
720
+ "Operates in the current working directory (the shell_cwd default CWD). " +
721
+ "Detection ladder: if package.json has scripts.lint -> 'npm run lint' (type npm-script); " +
722
+ "else if eslint is in (dev)dependencies -> 'npx eslint . --format json' (type eslint); " +
723
+ "else if any .py file is present (only when package.json is absent/unreadable) -> 'pylint .' (type python-lint). " +
724
+ "No detection returns the error 'Could not detect a supported linter (ESLint script or Python).' " +
725
+ "Spawns with shell:true and a 60 s timeout; returns JSON text: {tool, type, report} (report = stdout+stderr capped at 10000 chars), or {error}.",
726
+ inputSchema: zodToJsonSchema(AnalyzeProjectArgsSchema),
727
+ },
728
+ {
729
+ name: "web_search",
730
+ description: "Search the web using multiple providers (DuckDuckGo, Google, Bing). " +
731
+ "Uses no-key, no-Chrome providers first, then browser providers as fallback. " +
732
+ "Default fallback chain (when providers is omitted): duckduckgo-fetch -> duckduckgo-api -> duckduckgo-html -> google -> bing; the chain stops at the first provider that returns results. " +
733
+ "When providers is given, each listed provider is tried in order and errors are collected per provider (not fatal). " +
734
+ "Browser-based providers (duckduckgo-html, google, bing) use puppeteer-core with the local Chrome-for-Testing build and are skipped in chain mode once Chrome is detected unavailable. " +
735
+ "Returns JSON text: {results: [{title, link, snippet, provider}], meta: {total_found, providers_used, no_api_key_required, trace}} or, when every provider fails, {error: 'All attempted search providers failed.', attempts: [...], trace: [...]}. " +
736
+ "Results are deduplicated by link.",
737
+ inputSchema: zodToJsonSchema(WebSearchArgsSchema),
738
+ },
739
+ {
740
+ name: "fetch_web_content",
741
+ description: "Fetch the clean, text-based content of a webpage URL. " +
742
+ "Fetches the URL, extracts the <title> when present, converts the HTML to plain text via html-to-text (wordwrap off, anchor hrefs ignored, images skipped), and truncates the content to 40000 chars (' (truncated)' marker when cut). " +
743
+ "Returns JSON text: {url, status, title?, content} or {error: 'Failed to fetch URL: ...'}.",
744
+ inputSchema: zodToJsonSchema(FetchWebContentArgsSchema),
745
+ },
746
+ {
747
+ name: "wikipedia_search",
748
+ description: "Search Wikipedia for a given query and return page summaries. " +
749
+ "Uses the MediaWiki API: list=search (top 3), then prop=extracts exintro explaintext per pageid; each summary is truncated to 2000 chars and each url is built from the page title. " +
750
+ "lang (optional): language code, default 'en'. " +
751
+ "Returns JSON text: {results: [{title, summary, url}]}, {results: 'No Wikipedia articles found.'}, or {error: 'Wikipedia search failed: ...'}.",
752
+ inputSchema: zodToJsonSchema(WikipediaSearchArgsSchema),
753
+ },
754
+ {
755
+ name: "rag_local_files",
756
+ description: "Perform RAG (Retrieval-Augmented Generation) on files in a directory. " +
757
+ "Recursively scans up to 50 text files under path (default: the server process's working directory), skipping binary extensions (.png/.jpg/.jpeg/.gif/.ico/.exe/.dll/.bin). " +
758
+ "file_pattern (optional) restricts the scan to files whose name or full path contains the pattern (e.g. '.ts' or 'src/'). " +
759
+ "Files are chunked by paragraph (chunks longer than 20 characters); the query and all chunks are embedded via LM Studio's /v1/embeddings endpoint (bundled nomic-embed-text v1.5; the model id can be overridden with the MCP_RAG_EMBED_MODEL environment variable). " +
760
+ "Chunks scoring above cosine similarity 0.4 against the query are kept, sorted by score, and the top 10 are returned. " +
761
+ "Returns JSON text: {query, results: [{file, score, content}]} or {error: 'Local RAG failed: ...'}. " +
762
+ "Only works within allowed directories.",
763
+ inputSchema: zodToJsonSchema(RagLocalFilesArgsSchema),
764
+ },
765
+ {
766
+ name: "rag_web_content",
767
+ description: "Fetch content from a URL, and then use RAG to find and return only the text chunks most relevant to a specific query. " +
768
+ "Fetches the URL, converts the HTML to plain text via html-to-text (wordwrap off, anchor hrefs ignored, images skipped), chunks it by paragraph (chunks longer than 20 characters), embeds the query and chunks via LM Studio's /v1/embeddings endpoint (bundled nomic-embed-text v1.5; the model id can be overridden with the MCP_RAG_EMBED_MODEL environment variable), and returns the top 5 chunks sorted by cosine similarity. " +
769
+ "Returns JSON text: {url, query, relevant_chunks: [{chunk, score}]} or {error: 'Failed during RAG web search: ...'}.",
770
+ inputSchema: zodToJsonSchema(RagWebContentArgsSchema),
771
+ },
772
+ {
773
+ name: "browser_session_open",
774
+ description: "Open a persistent browser session (single active page), navigate to URL, and return page text for context. " +
775
+ "Launches a headless Chrome-for-Testing instance via puppeteer-core (shared launcher: browser/launcher.ts; also used by web_search's browser legs). " +
776
+ "There is ONE active session per server process - re-opening replaces any existing session (closing its browser first). " +
777
+ "Navigation waits for networkidle0 with a 30s timeout. " +
778
+ "wait_for_selector: optional CSS selector to wait for after navigation (15s timeout). " +
779
+ "include_page_text: if true (default), returns full page text content (document.body.innerText) after opening. " +
780
+ "Returns JSON text: {success, session_active, url, title, text_content, text_length, message} or {error: 'Failed to open browser session: ...'}.",
781
+ inputSchema: zodToJsonSchema(BrowserSessionOpenArgsSchema),
782
+ },
783
+ {
784
+ name: "browser_session_control",
785
+ description: "Control the active persistent browser session. " +
786
+ "Supports actions, page reading, screenshot capture, and fuzzy finding in-page text/selectors. " +
787
+ "actions: array of {type: wait_for_selector | wait | click | type | press | select | hover | scroll | evaluate, selector?, text?, value?, key?, milliseconds?, x?, y?, script?} executed in order. " +
788
+ "click: native click with one retry, then DOM fallback (scrollIntoView + element.click); type: triple-clicks to select, clears, then types; evaluate: runs a JS snippet in page context. " +
789
+ "Missing required fields produce clear errors (e.g. \"Action 'click' requires 'selector'.\"). " +
790
+ "read_page: if true (default), returns page metadata (url + title). Full text is returned only on URL change or when full_read=true. " +
791
+ "full_read: if true, forces full page text output even when URL has not changed. " +
792
+ "screenshot_path: optional screenshot output path (must be within an allowed directory); full_page_screenshot: capture the full page. " +
793
+ "fuzzy_find: fuzzy-find query over in-page content/selectors (interactive + text nodes, deduped, capped at 400 candidates; ranked by text then selector similarity); max_results: max fuzzy results (default 5, max 20). " +
794
+ "Returns JSON text: {success, session_active, actions_executed, screenshot_saved, url_changed, url_change_notice, page, fuzzy_find_results} or {error: 'Browser session control failed: ...'}. " +
795
+ "Fails with a clear 'No active browser session. Call 'browser_session_open' first.' error when no session is open.",
796
+ inputSchema: zodToJsonSchema(BrowserSessionControlArgsSchema),
797
+ },
798
+ {
799
+ name: "browser_session_close",
800
+ description: "Close the active persistent browser session. " +
801
+ "Tears down the session's Chrome instance; subsequent browser_session_control calls fail with the clear no-session error. " +
802
+ "Idempotent: when no session is open it succeeds with session_active=false and message 'No active browser session.'. " +
803
+ "Returns JSON text: {success, session_active, message} or {error: 'Failed to close browser session: ...'}.",
804
+ inputSchema: zodToJsonSchema(BrowserSessionCloseArgsSchema),
805
+ },
806
+ {
807
+ name: "browser_open_page",
808
+ description: "Open a webpage in a headless browser (puppeteer-core), render it once, and return content. " +
809
+ "One-shot only; do not use for multi-step navigation. " +
810
+ "Stateless: uses its own browser instance (shared launcher: browser/launcher.ts) that is always closed on return, and never touches the persistent browser session. " +
811
+ "url: page to load (networkidle0, 30s timeout). " +
812
+ "wait_for_selector: CSS selector to wait for before returning (10s timeout). " +
813
+ "actions: optional scripted browser steps to run after navigation (same action schema as browser_session_control). " +
814
+ "screenshot_path: path to save a screenshot (must be within an allowed directory); full_page_screenshot: capture the full page. " +
815
+ "Returns JSON text: {url, title, text_content (max 5000 chars), screenshot_saved, actions_executed, url_changed, url_change_notice} or {error: 'Browser operation failed: ...'}.",
816
+ inputSchema: zodToJsonSchema(BrowserOpenPageArgsSchema),
817
+ },
818
+ {
819
+ name: "execute_command",
820
+ description: "Beledarian-compatible alias of shell_run (same bounded synchronous semantics, same result shape). " +
821
+ "Execute a shell command in the current working directory and return the stdout and stderr output of the command. " +
822
+ "You can optionally provide input to be piped to the command's stdin. " +
823
+ "IMPORTANT: The host operating system is 'win32' (Windows) - do NOT use 'bash' or 'sh' commands unless you are certain WSL is available; use standard Windows 'cmd' or 'powershell' syntax. " +
824
+ "timeout_seconds: default 5, max 60 (Beledarian's 60 s cap; the native shell_run caps at 28 s). " +
825
+ "Returns {command, exitCode, stdout, stderr, timedOut, duration_ms, cwd}; non-zero exit or timeout returns an error that still includes the captured output.",
826
+ inputSchema: zodToJsonSchema(ExecuteCommandArgsSchema),
827
+ },
828
+ {
829
+ name: "run_in_terminal",
830
+ description: "Beledarian-compatible alias of shell_terminal. " +
831
+ "Launch a command in a new, separate interactive terminal window. " +
832
+ "Use this for scripts that require user interaction (input/output) or to open a shell in a specific directory. " +
833
+ "(Currently optimized for Windows.) " +
834
+ "Returns the shell_terminal job JSON (including the job id); use cancel_background_command (or shell_cancel) to close the window.",
835
+ inputSchema: zodToJsonSchema(RunInTerminalArgsSchema),
836
+ },
837
+ {
838
+ name: "run_test_command",
839
+ description: "Beledarian-compatible alias of shell_test. " +
840
+ "Execute a test command (like 'npm test') and return the results as {command, exit_code, stdout, stderr, passed}. " +
841
+ "Specialized for capturing test output. Never errors on a failing test. Runs with CI=true. " +
842
+ "Host is Windows; use cmd.exe syntax. " +
843
+ "Bounded to 28 s by the MCP client timeout - for longer suites use run_background_command (shell_start) + check_background_command (shell_check).",
844
+ inputSchema: zodToJsonSchema(RunTestCommandArgsSchema),
845
+ },
846
+ {
847
+ name: "run_background_command",
848
+ description: "Beledarian-compatible alias of shell_start. " +
849
+ "Starts a long-running process in the background. The process is not blocked, allowing you to do other things. " +
850
+ "You MUST provide a descriptive name. timeout_hours: optional, default 10, max 10 (auto-kill). " +
851
+ "Host is Windows; use cmd.exe syntax. " +
852
+ "Returns the shell_start job JSON (including the job id); poll with check_background_command (shell_check) and kill with cancel_background_command (shell_cancel). " +
853
+ "Job ids live in this MCP server process's registry (same lifetime as Beledarian's per-process backgroundCommands map - lost when the server restarts).",
854
+ inputSchema: zodToJsonSchema(RunBackgroundCommandArgsSchema),
855
+ },
856
+ {
857
+ name: "check_background_command",
858
+ description: "Beledarian-compatible alias of shell_check. " +
859
+ "Check the status, stdout, and stderr of a running or completed background command started with run_background_command (or run_in_terminal). " +
860
+ "Returns {id, name, status, exitCode, duration_seconds, stdout_tail, stderr_tail, logFile}. " +
861
+ "Status values: running, completed, error, cancelled, timeout.",
862
+ inputSchema: zodToJsonSchema(CheckBackgroundCommandArgsSchema),
863
+ },
864
+ {
865
+ name: "cancel_background_command",
866
+ description: "Beledarian-compatible alias of shell_cancel. " +
867
+ "Kills a running background command (job from run_background_command or run_in_terminal). " +
868
+ "Kills the whole process tree.",
869
+ inputSchema: zodToJsonSchema(CancelBackgroundCommandArgsSchema),
870
+ },
871
+ {
872
+ name: "run_python",
873
+ description: "Beledarian-compatible alias of shell_python (keeps Beledarian's 60 s cap). " +
874
+ "Run a Python code snippet. You cannot import external modules but you have read/write access to the current working directory. " +
875
+ "Pass the code you wish to run as a string in the 'python' parameter. " +
876
+ "By default, the code will timeout in 5 seconds. You can extend this timeout by setting the 'timeout_seconds' parameter to a higher value in seconds, up to a maximum of 60 seconds. " +
877
+ "You will get the stdout and stderr output of the code execution, thus please print the output you wish to return using 'print()'. " +
878
+ "Requires system Python on PATH. Optional cwd overrides the default working directory (see shell_cwd). " +
879
+ "Returns {exitCode, stdout, stderr, timedOut, duration_ms}; non-zero exit or timeout returns an error that still includes the captured output.",
880
+ inputSchema: zodToJsonSchema(RunPythonArgsSchema),
881
+ },
882
+ {
883
+ name: "run_javascript",
884
+ description: "Beledarian-compatible alias of the fork's run_javascript - the CONFINED variant (NOT an alias of run_javascript_free). " +
885
+ "Run a JavaScript/TypeScript code snippet using deno. You cannot import external modules but you have read/write access to the current working directory. " +
886
+ "Pass the code you wish to run as a string in the 'javascript' parameter. " +
887
+ "By default, the code will timeout in 5 seconds. You can extend this timeout by setting the 'timeout_seconds' parameter to a higher value in seconds, up to a maximum of 60 seconds. " +
888
+ "You will get the stdout and stderr output of the code execution, thus please print the output you wish to return using 'console.log' or 'console.error'. " +
889
+ "The snippet runs with Deno permissions --allow-read=. --allow-write=. --no-prompt --deny-net --deny-env --deny-sys --deny-run --deny-ffi; cwd defaults to the shell_cwd default. " +
890
+ "Returns {stdout, stderr}; non-zero exit returns an error that includes the stderr. " +
891
+ "Requires a Deno binary (same resolution as run_javascript_free).",
892
+ inputSchema: zodToJsonSchema(RunJavascriptArgsSchema),
893
+ },
894
+ {
895
+ name: "save_memory",
896
+ description: "Save a specific piece of information or fact to long-term memory. " +
897
+ "This information will be available in future interactions if memory is enabled. " +
898
+ "Use this for user preferences, important facts, or context that should persist. " +
899
+ "Standalone tool (no fork equivalent - NOT an alias): appends '- [ISO timestamp] fact' to the memory file, creating it with a '# Long-Term Memory' header if missing. " +
900
+ "Memory file path = env MCP_MEMORY_FILE if set, else the reference workspace memory.md (C:\\Users\\Gerar\\.beledarians-llm-toolbox\\workspace\\memory.md) if present, else <cwd>/memory.md. " +
901
+ "Unlike Beledarian's there is no enable gate (the fork has no such setting). " +
902
+ "Returns {success, message} or {error}.",
903
+ inputSchema: zodToJsonSchema(SaveMemoryArgsSchema),
904
+ },
905
+ {
906
+ name: "consult_secondary_agent",
907
+ description: "Delegate a task to a secondary agent. IMPORTANT: If the task is 'coding' or 'writing files', the secondary agent will AUTOMATICALLY CREATE AND SAVE the files to the disk. You do NOT need to save them yourself. The tool returns a list of generated files. Trust this list.",
908
+ inputSchema: zodToJsonSchema(ConsultSecondaryAgentArgsSchema),
909
+ },
470
910
  ],
471
911
  };
472
912
  });
@@ -869,6 +1309,450 @@ export class FilesystemServer {
869
1309
  content: [{ type: "text", text: result }],
870
1310
  };
871
1311
  }
1312
+ case "run_javascript_free": {
1313
+ const parsed = RunJavascriptFreeArgsSchema.safeParse(args);
1314
+ if (!parsed.success) {
1315
+ throw new Error(`Invalid arguments for run_javascript_free: ${parsed.error}`);
1316
+ }
1317
+ const result = await handleRunJavascriptFree(parsed.data.javascript, parsed.data.timeout_seconds, parsed.data.cwd);
1318
+ return {
1319
+ content: [{ type: "text", text: result }],
1320
+ };
1321
+ }
1322
+ case "git_status": {
1323
+ const parsed = GitStatusArgsSchema.safeParse(args);
1324
+ if (!parsed.success) {
1325
+ throw new Error(`Invalid arguments for git_status: ${parsed.error}`);
1326
+ }
1327
+ const result = await handleGitStatus();
1328
+ return {
1329
+ content: [{ type: "text", text: result }],
1330
+ };
1331
+ }
1332
+ case "git_diff": {
1333
+ const parsed = GitDiffArgsSchema.safeParse(args);
1334
+ if (!parsed.success) {
1335
+ throw new Error(`Invalid arguments for git_diff: ${parsed.error}`);
1336
+ }
1337
+ const result = await handleGitDiff(parsed.data.file_path, parsed.data.cached);
1338
+ return {
1339
+ content: [{ type: "text", text: result }],
1340
+ };
1341
+ }
1342
+ case "git_commit": {
1343
+ const parsed = GitCommitArgsSchema.safeParse(args);
1344
+ if (!parsed.success) {
1345
+ throw new Error(`Invalid arguments for git_commit: ${parsed.error}`);
1346
+ }
1347
+ const result = await handleGitCommit(parsed.data.message);
1348
+ return {
1349
+ content: [{ type: "text", text: result }],
1350
+ };
1351
+ }
1352
+ case "git_log": {
1353
+ const parsed = GitLogArgsSchema.safeParse(args);
1354
+ if (!parsed.success) {
1355
+ throw new Error(`Invalid arguments for git_log: ${parsed.error}`);
1356
+ }
1357
+ const result = await handleGitLog(parsed.data.max_count);
1358
+ return {
1359
+ content: [{ type: "text", text: result }],
1360
+ };
1361
+ }
1362
+ case "git_add": {
1363
+ const parsed = GitAddArgsSchema.safeParse(args);
1364
+ if (!parsed.success) {
1365
+ throw new Error(`Invalid arguments for git_add: ${parsed.error}`);
1366
+ }
1367
+ const result = await handleGitAdd(parsed.data.paths);
1368
+ return {
1369
+ content: [{ type: "text", text: result }],
1370
+ };
1371
+ }
1372
+ case "git_checkout": {
1373
+ const parsed = GitCheckoutArgsSchema.safeParse(args);
1374
+ if (!parsed.success) {
1375
+ throw new Error(`Invalid arguments for git_checkout: ${parsed.error}`);
1376
+ }
1377
+ const result = await handleGitCheckout(parsed.data.branch_name, parsed.data.create_new);
1378
+ return {
1379
+ content: [{ type: "text", text: result }],
1380
+ };
1381
+ }
1382
+ case "gh_auth": {
1383
+ const parsed = GhAuthArgsSchema.safeParse(args);
1384
+ if (!parsed.success) {
1385
+ throw new Error(`Invalid arguments for gh_auth: ${parsed.error}`);
1386
+ }
1387
+ const result = await handleGhAuth();
1388
+ return {
1389
+ content: [{ type: "text", text: result }],
1390
+ };
1391
+ }
1392
+ case "gh_create_issue": {
1393
+ const parsed = GhCreateIssueArgsSchema.safeParse(args);
1394
+ if (!parsed.success) {
1395
+ throw new Error(`Invalid arguments for gh_create_issue: ${parsed.error}`);
1396
+ }
1397
+ const result = await handleGhCreateIssue(parsed.data.title, parsed.data.body, parsed.data.labels);
1398
+ return {
1399
+ content: [{ type: "text", text: result }],
1400
+ };
1401
+ }
1402
+ case "gh_list_issues": {
1403
+ const parsed = GhListIssuesArgsSchema.safeParse(args);
1404
+ if (!parsed.success) {
1405
+ throw new Error(`Invalid arguments for gh_list_issues: ${parsed.error}`);
1406
+ }
1407
+ const result = await handleGhListIssues(parsed.data.state, parsed.data.labels, parsed.data.limit);
1408
+ return {
1409
+ content: [{ type: "text", text: result }],
1410
+ };
1411
+ }
1412
+ case "gh_view_comments": {
1413
+ const parsed = GhViewCommentsArgsSchema.safeParse(args);
1414
+ if (!parsed.success) {
1415
+ throw new Error(`Invalid arguments for gh_view_comments: ${parsed.error}`);
1416
+ }
1417
+ const result = await handleGhViewComments(parsed.data.number, parsed.data.type);
1418
+ return {
1419
+ content: [{ type: "text", text: result }],
1420
+ };
1421
+ }
1422
+ case "gh_create_pr": {
1423
+ const parsed = GhCreatePrArgsSchema.safeParse(args);
1424
+ if (!parsed.success) {
1425
+ throw new Error(`Invalid arguments for gh_create_pr: ${parsed.error}`);
1426
+ }
1427
+ const result = await handleGhCreatePr(parsed.data.title, parsed.data.body, parsed.data.head_branch, parsed.data.base_branch);
1428
+ return {
1429
+ content: [{ type: "text", text: result }],
1430
+ };
1431
+ }
1432
+ case "gh_list_prs": {
1433
+ const parsed = GhListPrsArgsSchema.safeParse(args);
1434
+ if (!parsed.success) {
1435
+ throw new Error(`Invalid arguments for gh_list_prs: ${parsed.error}`);
1436
+ }
1437
+ const result = await handleGhListPrs(parsed.data.state, parsed.data.limit);
1438
+ return {
1439
+ content: [{ type: "text", text: result }],
1440
+ };
1441
+ }
1442
+ case "gh_view_pr_diff": {
1443
+ const parsed = GhViewPrDiffArgsSchema.safeParse(args);
1444
+ if (!parsed.success) {
1445
+ throw new Error(`Invalid arguments for gh_view_pr_diff: ${parsed.error}`);
1446
+ }
1447
+ const result = await handleGhViewPrDiff(parsed.data.number);
1448
+ return {
1449
+ content: [{ type: "text", text: result }],
1450
+ };
1451
+ }
1452
+ case "gh_push": {
1453
+ const parsed = GhPushArgsSchema.safeParse(args);
1454
+ if (!parsed.success) {
1455
+ throw new Error(`Invalid arguments for gh_push: ${parsed.error}`);
1456
+ }
1457
+ const result = await handleGhPush(parsed.data.branch);
1458
+ return {
1459
+ content: [{ type: "text", text: result }],
1460
+ };
1461
+ }
1462
+ case "get_system_info": {
1463
+ const parsed = GetSystemInfoArgsSchema.safeParse(args);
1464
+ if (!parsed.success) {
1465
+ throw new Error(`Invalid arguments for get_system_info: ${parsed.error}`);
1466
+ }
1467
+ const result = await handleGetSystemInfo();
1468
+ return {
1469
+ content: [{ type: "text", text: result }],
1470
+ };
1471
+ }
1472
+ case "read_clipboard": {
1473
+ const parsed = ReadClipboardArgsSchema.safeParse(args);
1474
+ if (!parsed.success) {
1475
+ throw new Error(`Invalid arguments for read_clipboard: ${parsed.error}`);
1476
+ }
1477
+ const result = await handleReadClipboard();
1478
+ return {
1479
+ content: [{ type: "text", text: result }],
1480
+ };
1481
+ }
1482
+ case "write_clipboard": {
1483
+ const parsed = WriteClipboardArgsSchema.safeParse(args);
1484
+ if (!parsed.success) {
1485
+ throw new Error(`Invalid arguments for write_clipboard: ${parsed.error}`);
1486
+ }
1487
+ const result = await handleWriteClipboard(parsed.data.content);
1488
+ return {
1489
+ content: [{ type: "text", text: result }],
1490
+ };
1491
+ }
1492
+ case "send_notification": {
1493
+ const parsed = SendNotificationArgsSchema.safeParse(args);
1494
+ if (!parsed.success) {
1495
+ throw new Error(`Invalid arguments for send_notification: ${parsed.error}`);
1496
+ }
1497
+ const result = await handleSendNotification(parsed.data.title, parsed.data.message);
1498
+ return {
1499
+ content: [{ type: "text", text: result }],
1500
+ };
1501
+ }
1502
+ case "open_file": {
1503
+ const parsed = OpenFileArgsSchema.safeParse(args);
1504
+ if (!parsed.success) {
1505
+ throw new Error(`Invalid arguments for open_file: ${parsed.error}`);
1506
+ }
1507
+ const result = await handleOpenFile(parsed.data.target, this.allowedDirectories);
1508
+ return {
1509
+ content: [{ type: "text", text: result }],
1510
+ };
1511
+ }
1512
+ case "preview_html": {
1513
+ const parsed = PreviewHtmlArgsSchema.safeParse(args);
1514
+ if (!parsed.success) {
1515
+ throw new Error(`Invalid arguments for preview_html: ${parsed.error}`);
1516
+ }
1517
+ const result = await handlePreviewHtml(parsed.data.html_content, parsed.data.file_name);
1518
+ return {
1519
+ content: [{ type: "text", text: result }],
1520
+ };
1521
+ }
1522
+ case "read_document": {
1523
+ const parsed = ReadDocumentArgsSchema.safeParse(args);
1524
+ if (!parsed.success) {
1525
+ throw new Error(`Invalid arguments for read_document: ${parsed.error}`);
1526
+ }
1527
+ const result = await handleReadDocument(parsed.data.file_path, this.allowedDirectories);
1528
+ return {
1529
+ content: [{ type: "text", text: result }],
1530
+ };
1531
+ }
1532
+ case "query_database": {
1533
+ const parsed = QueryDatabaseArgsSchema.safeParse(args);
1534
+ if (!parsed.success) {
1535
+ throw new Error(`Invalid arguments for query_database: ${parsed.error}`);
1536
+ }
1537
+ const result = await handleQueryDatabase(parsed.data.db_path, parsed.data.query, this.allowedDirectories);
1538
+ return {
1539
+ content: [{ type: "text", text: result }],
1540
+ };
1541
+ }
1542
+ case "analyze_project": {
1543
+ const parsed = AnalyzeProjectArgsSchema.safeParse(args);
1544
+ if (!parsed.success) {
1545
+ throw new Error(`Invalid arguments for analyze_project: ${parsed.error}`);
1546
+ }
1547
+ const result = await handleAnalyzeProject();
1548
+ return {
1549
+ content: [{ type: "text", text: result }],
1550
+ };
1551
+ }
1552
+ case "web_search": {
1553
+ const parsed = WebSearchArgsSchema.safeParse(args);
1554
+ if (!parsed.success) {
1555
+ throw new Error(`Invalid arguments for web_search: ${parsed.error}`);
1556
+ }
1557
+ const result = await handleWebSearch(parsed.data.query, parsed.data.providers);
1558
+ return {
1559
+ content: [{ type: "text", text: result }],
1560
+ };
1561
+ }
1562
+ case "fetch_web_content": {
1563
+ const parsed = FetchWebContentArgsSchema.safeParse(args);
1564
+ if (!parsed.success) {
1565
+ throw new Error(`Invalid arguments for fetch_web_content: ${parsed.error}`);
1566
+ }
1567
+ const result = await handleFetchWebContent(parsed.data.url);
1568
+ return {
1569
+ content: [{ type: "text", text: result }],
1570
+ };
1571
+ }
1572
+ case "wikipedia_search": {
1573
+ const parsed = WikipediaSearchArgsSchema.safeParse(args);
1574
+ if (!parsed.success) {
1575
+ throw new Error(`Invalid arguments for wikipedia_search: ${parsed.error}`);
1576
+ }
1577
+ const result = await handleWikipediaSearch(parsed.data.query, parsed.data.lang);
1578
+ return {
1579
+ content: [{ type: "text", text: result }],
1580
+ };
1581
+ }
1582
+ case "rag_local_files": {
1583
+ const parsed = RagLocalFilesArgsSchema.safeParse(args);
1584
+ if (!parsed.success) {
1585
+ throw new Error(`Invalid arguments for rag_local_files: ${parsed.error}`);
1586
+ }
1587
+ const result = await handleRagLocalFiles(parsed.data.query, parsed.data.path, parsed.data.file_pattern, this.allowedDirectories);
1588
+ return {
1589
+ content: [{ type: "text", text: result }],
1590
+ };
1591
+ }
1592
+ case "rag_web_content": {
1593
+ const parsed = RagWebContentArgsSchema.safeParse(args);
1594
+ if (!parsed.success) {
1595
+ throw new Error(`Invalid arguments for rag_web_content: ${parsed.error}`);
1596
+ }
1597
+ const result = await handleRagWebContent(parsed.data.url, parsed.data.query);
1598
+ return {
1599
+ content: [{ type: "text", text: result }],
1600
+ };
1601
+ }
1602
+ case "browser_session_open": {
1603
+ const parsed = BrowserSessionOpenArgsSchema.safeParse(args);
1604
+ if (!parsed.success) {
1605
+ throw new Error(`Invalid arguments for browser_session_open: ${parsed.error}`);
1606
+ }
1607
+ const result = await handleBrowserSessionOpen(parsed.data.url, parsed.data.wait_for_selector, parsed.data.include_page_text);
1608
+ return {
1609
+ content: [{ type: "text", text: result }],
1610
+ };
1611
+ }
1612
+ case "browser_session_control": {
1613
+ const parsed = BrowserSessionControlArgsSchema.safeParse(args);
1614
+ if (!parsed.success) {
1615
+ throw new Error(`Invalid arguments for browser_session_control: ${parsed.error}`);
1616
+ }
1617
+ const result = await handleBrowserSessionControl({
1618
+ actions: parsed.data.actions,
1619
+ read_page: parsed.data.read_page,
1620
+ full_read: parsed.data.full_read,
1621
+ screenshot_path: parsed.data.screenshot_path,
1622
+ full_page_screenshot: parsed.data.full_page_screenshot,
1623
+ fuzzy_find: parsed.data.fuzzy_find,
1624
+ max_results: parsed.data.max_results,
1625
+ }, this.allowedDirectories);
1626
+ return {
1627
+ content: [{ type: "text", text: result }],
1628
+ };
1629
+ }
1630
+ case "browser_session_close": {
1631
+ const parsed = BrowserSessionCloseArgsSchema.safeParse(args);
1632
+ if (!parsed.success) {
1633
+ throw new Error(`Invalid arguments for browser_session_close: ${parsed.error}`);
1634
+ }
1635
+ const result = await handleBrowserSessionClose();
1636
+ return {
1637
+ content: [{ type: "text", text: result }],
1638
+ };
1639
+ }
1640
+ case "browser_open_page": {
1641
+ const parsed = BrowserOpenPageArgsSchema.safeParse(args);
1642
+ if (!parsed.success) {
1643
+ throw new Error(`Invalid arguments for browser_open_page: ${parsed.error}`);
1644
+ }
1645
+ const result = await handleBrowserOpenPage({
1646
+ url: parsed.data.url,
1647
+ screenshot_path: parsed.data.screenshot_path,
1648
+ wait_for_selector: parsed.data.wait_for_selector,
1649
+ full_page_screenshot: parsed.data.full_page_screenshot,
1650
+ actions: parsed.data.actions,
1651
+ }, this.allowedDirectories);
1652
+ return {
1653
+ content: [{ type: "text", text: result }],
1654
+ };
1655
+ }
1656
+ case "execute_command": {
1657
+ const parsed = ExecuteCommandArgsSchema.safeParse(args);
1658
+ if (!parsed.success) {
1659
+ throw new Error(`Invalid arguments for execute_command: ${parsed.error}`);
1660
+ }
1661
+ const result = await handleExecuteCommand(parsed.data.command, parsed.data.input, parsed.data.timeout_seconds);
1662
+ return {
1663
+ content: [{ type: "text", text: result }],
1664
+ };
1665
+ }
1666
+ case "run_in_terminal": {
1667
+ const parsed = RunInTerminalArgsSchema.safeParse(args);
1668
+ if (!parsed.success) {
1669
+ throw new Error(`Invalid arguments for run_in_terminal: ${parsed.error}`);
1670
+ }
1671
+ const result = await handleRunInTerminal(parsed.data.command);
1672
+ return {
1673
+ content: [{ type: "text", text: result }],
1674
+ };
1675
+ }
1676
+ case "run_test_command": {
1677
+ const parsed = RunTestCommandArgsSchema.safeParse(args);
1678
+ if (!parsed.success) {
1679
+ throw new Error(`Invalid arguments for run_test_command: ${parsed.error}`);
1680
+ }
1681
+ const result = await handleRunTestCommand(parsed.data.command);
1682
+ return {
1683
+ content: [{ type: "text", text: result }],
1684
+ };
1685
+ }
1686
+ case "run_background_command": {
1687
+ const parsed = RunBackgroundCommandArgsSchema.safeParse(args);
1688
+ if (!parsed.success) {
1689
+ throw new Error(`Invalid arguments for run_background_command: ${parsed.error}`);
1690
+ }
1691
+ const result = await handleRunBackgroundCommand(parsed.data.command, parsed.data.name, parsed.data.timeout_hours, parsed.data.cwd);
1692
+ return {
1693
+ content: [{ type: "text", text: result }],
1694
+ };
1695
+ }
1696
+ case "check_background_command": {
1697
+ const parsed = CheckBackgroundCommandArgsSchema.safeParse(args);
1698
+ if (!parsed.success) {
1699
+ throw new Error(`Invalid arguments for check_background_command: ${parsed.error}`);
1700
+ }
1701
+ const result = await handleCheckBackgroundCommand(parsed.data.id);
1702
+ return {
1703
+ content: [{ type: "text", text: result }],
1704
+ };
1705
+ }
1706
+ case "cancel_background_command": {
1707
+ const parsed = CancelBackgroundCommandArgsSchema.safeParse(args);
1708
+ if (!parsed.success) {
1709
+ throw new Error(`Invalid arguments for cancel_background_command: ${parsed.error}`);
1710
+ }
1711
+ const result = await handleCancelBackgroundCommand(parsed.data.id);
1712
+ return {
1713
+ content: [{ type: "text", text: result }],
1714
+ };
1715
+ }
1716
+ case "run_python": {
1717
+ const parsed = RunPythonArgsSchema.safeParse(args);
1718
+ if (!parsed.success) {
1719
+ throw new Error(`Invalid arguments for run_python: ${parsed.error}`);
1720
+ }
1721
+ const result = await handleRunPython(parsed.data.python, parsed.data.timeout_seconds, parsed.data.cwd);
1722
+ return {
1723
+ content: [{ type: "text", text: result }],
1724
+ };
1725
+ }
1726
+ case "run_javascript": {
1727
+ const parsed = RunJavascriptArgsSchema.safeParse(args);
1728
+ if (!parsed.success) {
1729
+ throw new Error(`Invalid arguments for run_javascript: ${parsed.error}`);
1730
+ }
1731
+ const result = await handleRunJavascript(parsed.data.javascript, parsed.data.timeout_seconds);
1732
+ return {
1733
+ content: [{ type: "text", text: result }],
1734
+ };
1735
+ }
1736
+ case "save_memory": {
1737
+ const parsed = SaveMemoryArgsSchema.safeParse(args);
1738
+ if (!parsed.success) {
1739
+ throw new Error(`Invalid arguments for save_memory: ${parsed.error}`);
1740
+ }
1741
+ const result = await handleSaveMemory(parsed.data.fact);
1742
+ return {
1743
+ content: [{ type: "text", text: result }],
1744
+ };
1745
+ }
1746
+ case "consult_secondary_agent": {
1747
+ const parsed = ConsultSecondaryAgentArgsSchema.safeParse(args);
1748
+ if (!parsed.success) {
1749
+ throw new Error(`Invalid arguments for consult_secondary_agent: ${parsed.error}`);
1750
+ }
1751
+ const result = await handleConsultSecondaryAgent(parsed.data.task, parsed.data.agent_role, parsed.data.context, parsed.data.allow_tools, this.allowedDirectories);
1752
+ return {
1753
+ content: [{ type: "text", text: result }],
1754
+ };
1755
+ }
872
1756
  default:
873
1757
  throw new Error(`Unknown tool: ${name}`);
874
1758
  }