cade-cli 0.4.0__tar.gz → 0.7.0__tar.gz
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.
- cade_cli-0.7.0/LICENSE +21 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/PKG-INFO +26 -4
- {cade_cli-0.4.0 → cade_cli-0.7.0}/pyproject.toml +14 -7
- cade_cli-0.7.0/src/cade_mcp_local/__init__.py +72 -0
- cade_cli-0.7.0/src/cade_mcp_local/__main__.py +6 -0
- cade_cli-0.7.0/src/cade_mcp_local/config.py +68 -0
- cade_cli-0.7.0/src/cade_mcp_local/errors.py +122 -0
- cade_cli-0.7.0/src/cade_mcp_local/server.py +80 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/__init__.py +45 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/context.py +282 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/filesystem.py +359 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/git.py +374 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/search.py +228 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/shell.py +76 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/tool_results.py +220 -0
- cade_cli-0.7.0/src/cade_mcp_local/tools/tool_schemas.py +83 -0
- cade_cli-0.7.0/src/cade_mcp_local/utils.py +98 -0
- cade_cli-0.7.0/src/cadecoder/__init__.py +1 -0
- cade_cli-0.7.0/src/cadecoder/ai/prompts.py +182 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/auth.py +0 -31
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/chat.py +46 -7
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/context.py +11 -1
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/mcp.py +18 -2
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/thread.py +9 -1
- cade_cli-0.7.0/src/cadecoder/cli/commands/tools.py +318 -0
- cade_cli-0.7.0/src/cadecoder/core/git.py +64 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/execution/context_window.py +369 -17
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/execution/orchestrator.py +206 -24
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/execution/parallel.py +3 -1
- cade_cli-0.7.0/src/cadecoder/execution/tool_result_store.py +1147 -0
- cade_cli-0.7.0/src/cadecoder/execution/tool_schema_cache.py +257 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/providers/anthropic.py +31 -1
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/storage/threads.py +92 -2
- cade_cli-0.7.0/src/cadecoder/tools/__init__.py +41 -0
- cade_cli-0.7.0/src/cadecoder/tools/manager/composite.py +385 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/tools/manager/config.py +6 -2
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/tools/manager/mcp.py +139 -16
- cade_cli-0.7.0/src/cadecoder/tools/manager.py +765 -0
- cade_cli-0.7.0/src/cadecoder/ui/display.py +775 -0
- cade_cli-0.7.0/src/cadecoder/ui/input.py +193 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/ui/session.py +203 -129
- cade_cli-0.4.0/src/cadecoder/__init__.py +0 -1
- cade_cli-0.4.0/src/cadecoder/ai/prompts.py +0 -240
- cade_cli-0.4.0/src/cadecoder/cli/commands/tools.py +0 -339
- cade_cli-0.4.0/src/cadecoder/tools/__init__.py +0 -49
- cade_cli-0.4.0/src/cadecoder/tools/local/__init__.py +0 -78
- cade_cli-0.4.0/src/cadecoder/tools/local/filesystem.py +0 -364
- cade_cli-0.4.0/src/cadecoder/tools/local/git.py +0 -345
- cade_cli-0.4.0/src/cadecoder/tools/local/search.py +0 -356
- cade_cli-0.4.0/src/cadecoder/tools/local/shell.py +0 -123
- cade_cli-0.4.0/src/cadecoder/tools/manager/composite.py +0 -267
- cade_cli-0.4.0/src/cadecoder/ui/display.py +0 -370
- {cade_cli-0.4.0 → cade_cli-0.7.0}/.gitignore +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/README.md +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/ai/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/app.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/auth.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/cli/commands/model.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/config.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/constants.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/errors.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/logging.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/names.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/core/types.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/execution/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/providers/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/providers/base.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/providers/ollama.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/providers/openai.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/storage/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/templates/login_failed.html +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/templates/login_success.html +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/templates/styles.css +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/tools/manager/__init__.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/tools/manager/base.py +0 -0
- {cade_cli-0.4.0 → cade_cli-0.7.0}/src/cadecoder/ui/__init__.py +0 -0
cade_cli-0.7.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Arcade AI Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cade-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Cade - The CLI Agent from Arcade.dev
|
|
5
5
|
Project-URL: Homepage, https://arcade.dev
|
|
6
6
|
Project-URL: Documentation, https://docs.arcade.dev
|
|
@@ -8,7 +8,28 @@ Project-URL: Repository, https://github.com/arcadeai-labs/cade
|
|
|
8
8
|
Project-URL: Issues, https://github.com/arcadeai-labs/cade/issues
|
|
9
9
|
Project-URL: Changelog, https://github.com/arcadeai-labs/cade/releases
|
|
10
10
|
Author-email: "Arcade AI Inc." <dev@arcade.dev>
|
|
11
|
-
License: MIT
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2024 Arcade AI Inc.
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
12
33
|
Keywords: agent,ai,arcade,cli,coding-assistant,llm,mcp
|
|
13
34
|
Classifier: Development Status :: 4 - Beta
|
|
14
35
|
Classifier: Environment :: Console
|
|
@@ -27,14 +48,15 @@ Requires-Dist: arcade-core<5.0.0,>=4.1.0
|
|
|
27
48
|
Requires-Dist: arcade-mcp-server>=1.0.0
|
|
28
49
|
Requires-Dist: arcade-tdk>=2.0.0
|
|
29
50
|
Requires-Dist: authlib<2.0.0,>=1.6.0
|
|
51
|
+
Requires-Dist: filelock<4.0.0,>=3.0.0
|
|
30
52
|
Requires-Dist: httpx<1.0.0,>=0.27.0
|
|
31
53
|
Requires-Dist: openai<2.0.0,>=1.0.0
|
|
32
|
-
Requires-Dist: prompt-toolkit
|
|
54
|
+
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
|
|
33
55
|
Requires-Dist: pydantic[email]<3.0.0,>=2.0.0
|
|
34
56
|
Requires-Dist: pyperclip<2.0.0,>=1.8.0
|
|
35
57
|
Requires-Dist: pyyaml<7.0.0,>=6.0
|
|
36
58
|
Requires-Dist: rich<14.0.0,>=13.0.0
|
|
37
|
-
Requires-Dist: tiktoken
|
|
59
|
+
Requires-Dist: tiktoken<1.0.0,>=0.11.0
|
|
38
60
|
Requires-Dist: toml<1.0.0,>=0.10.0
|
|
39
61
|
Requires-Dist: typer>0.10.0
|
|
40
62
|
Requires-Dist: ulid==1.1
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cade-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.7.0"
|
|
4
4
|
description = "Cade - The CLI Agent from Arcade.dev"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
|
-
license = {
|
|
7
|
+
license = {file = "LICENSE"}
|
|
8
8
|
authors = [
|
|
9
9
|
{ name = "Arcade AI Inc.", email = "dev@arcade.dev" },
|
|
10
10
|
]
|
|
@@ -36,9 +36,10 @@ dependencies = [
|
|
|
36
36
|
"arcade-core>=4.1.0,<5.0.0",
|
|
37
37
|
"authlib>=1.6.0,<2.0.0",
|
|
38
38
|
"pyperclip>=1.8.0,<2.0.0",
|
|
39
|
-
"prompt-toolkit>=3.0.52",
|
|
40
|
-
"tiktoken>=0.11.0",
|
|
39
|
+
"prompt-toolkit>=3.0.52,<4.0.0",
|
|
40
|
+
"tiktoken>=0.11.0,<1.0.0",
|
|
41
41
|
"httpx>=0.27.0,<1.0.0",
|
|
42
|
+
"filelock>=3.0.0,<4.0.0",
|
|
42
43
|
]
|
|
43
44
|
|
|
44
45
|
[project.urls]
|
|
@@ -50,6 +51,7 @@ Changelog = "https://github.com/arcadeai-labs/cade/releases"
|
|
|
50
51
|
|
|
51
52
|
[project.scripts]
|
|
52
53
|
cade = "cadecoder.cli.app:app"
|
|
54
|
+
cade-mcp-local = "cade_mcp_local:main"
|
|
53
55
|
|
|
54
56
|
[project.optional-dependencies]
|
|
55
57
|
dev = [
|
|
@@ -75,10 +77,15 @@ build-backend = "hatchling.build"
|
|
|
75
77
|
allow-direct-references = true
|
|
76
78
|
|
|
77
79
|
[tool.hatch.build.targets.sdist]
|
|
78
|
-
include = ["src/cadecoder"]
|
|
80
|
+
include = ["src/cadecoder", "src/cade_mcp_local"]
|
|
79
81
|
|
|
80
82
|
[tool.hatch.build.targets.wheel]
|
|
81
|
-
packages = ["src/cadecoder"]
|
|
83
|
+
packages = ["src/cadecoder", "src/cade_mcp_local"]
|
|
84
|
+
|
|
85
|
+
[tool.pytest.ini_options]
|
|
86
|
+
testpaths = ["tests"]
|
|
87
|
+
asyncio_mode = "auto"
|
|
88
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
82
89
|
|
|
83
90
|
[tool.ruff]
|
|
84
91
|
line-length = 100
|
|
@@ -110,7 +117,7 @@ disable_error_code = [
|
|
|
110
117
|
"return-value",
|
|
111
118
|
"annotation-unchecked",
|
|
112
119
|
]
|
|
113
|
-
files = ["src/cadecoder"]
|
|
120
|
+
files = ["src/cadecoder", "src/cade_mcp_local"]
|
|
114
121
|
|
|
115
122
|
[tool.mypy-ulid]
|
|
116
123
|
ignore_missing_imports = true
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Local MCP server for Cade CLI.
|
|
2
|
+
|
|
3
|
+
This package provides local filesystem, git, search, and shell tools
|
|
4
|
+
served via the MCP (Model Context Protocol) over stdio.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
# As a command-line tool (entry point)
|
|
8
|
+
$ cade-mcp-local
|
|
9
|
+
|
|
10
|
+
# As a Python module
|
|
11
|
+
$ python -m cade_mcp_local
|
|
12
|
+
|
|
13
|
+
# Programmatically
|
|
14
|
+
from cade_mcp_local import main
|
|
15
|
+
main()
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from cade_mcp_local.config import (
|
|
19
|
+
DEFAULT_IGNORE_PATTERNS,
|
|
20
|
+
DEFAULT_TIMEOUT,
|
|
21
|
+
MAX_LIST_DEPTH,
|
|
22
|
+
MAX_LIST_RESULTS,
|
|
23
|
+
MAX_PREVIEW_BYTES,
|
|
24
|
+
get_project_root,
|
|
25
|
+
reset_config,
|
|
26
|
+
)
|
|
27
|
+
from cade_mcp_local.errors import (
|
|
28
|
+
CommandExecutionError,
|
|
29
|
+
CommandTimeoutError,
|
|
30
|
+
FileOperationError,
|
|
31
|
+
GitOperationError,
|
|
32
|
+
InvalidInputError,
|
|
33
|
+
PathNotFoundError,
|
|
34
|
+
PathSecurityError,
|
|
35
|
+
SearchError,
|
|
36
|
+
)
|
|
37
|
+
from cade_mcp_local.server import app, create_app
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def main() -> None:
|
|
41
|
+
"""Run the MCP server.
|
|
42
|
+
|
|
43
|
+
This is the entry point for the `cade-mcp-local` command.
|
|
44
|
+
"""
|
|
45
|
+
app.run()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
# Entry point
|
|
50
|
+
"main",
|
|
51
|
+
"app",
|
|
52
|
+
"create_app",
|
|
53
|
+
# Configuration
|
|
54
|
+
"get_project_root",
|
|
55
|
+
"reset_config",
|
|
56
|
+
"DEFAULT_IGNORE_PATTERNS",
|
|
57
|
+
"DEFAULT_TIMEOUT",
|
|
58
|
+
"MAX_LIST_DEPTH",
|
|
59
|
+
"MAX_LIST_RESULTS",
|
|
60
|
+
"MAX_PREVIEW_BYTES",
|
|
61
|
+
# Errors
|
|
62
|
+
"PathNotFoundError",
|
|
63
|
+
"PathSecurityError",
|
|
64
|
+
"InvalidInputError",
|
|
65
|
+
"CommandTimeoutError",
|
|
66
|
+
"CommandExecutionError",
|
|
67
|
+
"GitOperationError",
|
|
68
|
+
"SearchError",
|
|
69
|
+
"FileOperationError",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
__version__ = "0.7.0"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Runtime configuration for the local MCP server.
|
|
2
|
+
|
|
3
|
+
Configuration is resolved lazily at runtime, not at import time.
|
|
4
|
+
This allows proper testing and correct behavior when installed as a package.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import pathlib
|
|
9
|
+
from functools import lru_cache
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@lru_cache(maxsize=1)
|
|
13
|
+
def get_project_root() -> pathlib.Path:
|
|
14
|
+
"""Get the project root directory.
|
|
15
|
+
|
|
16
|
+
Resolution order:
|
|
17
|
+
1. CADE_PROJECT_ROOT environment variable (set by parent process)
|
|
18
|
+
2. Current working directory
|
|
19
|
+
|
|
20
|
+
This is cached for performance but can be reset with reset_config().
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
Resolved path to the project root directory.
|
|
24
|
+
"""
|
|
25
|
+
if root := os.environ.get("CADE_PROJECT_ROOT"):
|
|
26
|
+
return pathlib.Path(root).resolve()
|
|
27
|
+
return pathlib.Path.cwd().resolve()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def reset_config() -> None:
|
|
31
|
+
"""Clear cached configuration.
|
|
32
|
+
|
|
33
|
+
Call this when:
|
|
34
|
+
- The working directory has changed
|
|
35
|
+
- CADE_PROJECT_ROOT environment variable has changed
|
|
36
|
+
- During testing to ensure isolation
|
|
37
|
+
"""
|
|
38
|
+
get_project_root.cache_clear()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Default ignore patterns for file listings and searches
|
|
42
|
+
DEFAULT_IGNORE_PATTERNS: list[str] = [
|
|
43
|
+
".git",
|
|
44
|
+
"__pycache__",
|
|
45
|
+
"node_modules",
|
|
46
|
+
".venv",
|
|
47
|
+
"venv",
|
|
48
|
+
".mypy_cache",
|
|
49
|
+
".pytest_cache",
|
|
50
|
+
"*.pyc",
|
|
51
|
+
".DS_Store",
|
|
52
|
+
"*.egg-info",
|
|
53
|
+
"dist",
|
|
54
|
+
"build",
|
|
55
|
+
".tox",
|
|
56
|
+
".coverage",
|
|
57
|
+
"htmlcov",
|
|
58
|
+
".idea",
|
|
59
|
+
".vscode",
|
|
60
|
+
".cursor",
|
|
61
|
+
".claude",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
# File operation limits
|
|
65
|
+
MAX_LIST_DEPTH: int = 10
|
|
66
|
+
MAX_LIST_RESULTS: int = 1000
|
|
67
|
+
MAX_PREVIEW_BYTES: int = 100_000
|
|
68
|
+
DEFAULT_TIMEOUT: int = 60
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Error types for the local MCP server.
|
|
2
|
+
|
|
3
|
+
Uses the arcade-tdk error hierarchy:
|
|
4
|
+
- FatalToolError: Non-recoverable errors (bad input, missing files, security)
|
|
5
|
+
- RetryableToolError: Transient errors that may succeed on retry (timeouts)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from arcade_tdk.errors import FatalToolError, RetryableToolError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PathNotFoundError(FatalToolError):
|
|
12
|
+
"""Raised when a requested path does not exist.
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
- File to read doesn't exist
|
|
16
|
+
- Directory to list doesn't exist
|
|
17
|
+
- Working directory for command doesn't exist
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, path: str, message: str | None = None):
|
|
21
|
+
self.path = path
|
|
22
|
+
super().__init__(message or f"Path not found: {path}")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class PathSecurityError(FatalToolError):
|
|
26
|
+
"""Raised when a path operation is denied for security reasons.
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
- Attempting to write outside project root
|
|
30
|
+
- Attempting to access restricted paths
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, path: str, reason: str | None = None):
|
|
34
|
+
self.path = path
|
|
35
|
+
msg = f"Access denied: {path}"
|
|
36
|
+
if reason:
|
|
37
|
+
msg += f" ({reason})"
|
|
38
|
+
super().__init__(msg)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class InvalidInputError(FatalToolError):
|
|
42
|
+
"""Raised when tool input is invalid.
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
- Empty search pattern
|
|
46
|
+
- Invalid line number
|
|
47
|
+
- Malformed arguments
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self, parameter: str, message: str):
|
|
51
|
+
self.parameter = parameter
|
|
52
|
+
super().__init__(f"Invalid {parameter}: {message}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class CommandTimeoutError(RetryableToolError):
|
|
56
|
+
"""Raised when a command or operation times out.
|
|
57
|
+
|
|
58
|
+
This is retryable because timeouts may be transient.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(self, command: str, timeout_seconds: int):
|
|
62
|
+
self.command = command
|
|
63
|
+
self.timeout_seconds = timeout_seconds
|
|
64
|
+
super().__init__(f"Command timed out after {timeout_seconds}s: {command[:50]}...")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CommandExecutionError(FatalToolError):
|
|
68
|
+
"""Raised when command execution fails.
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
- Shell command returns non-zero exit code with error
|
|
72
|
+
- Command binary not found
|
|
73
|
+
- Permission denied
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __init__(self, command: str, message: str, exit_code: int | None = None):
|
|
77
|
+
self.command = command
|
|
78
|
+
self.exit_code = exit_code
|
|
79
|
+
detail = f" (exit code: {exit_code})" if exit_code is not None else ""
|
|
80
|
+
super().__init__(f"Command failed{detail}: {message}")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class GitOperationError(FatalToolError):
|
|
84
|
+
"""Raised when a git operation fails.
|
|
85
|
+
|
|
86
|
+
Examples:
|
|
87
|
+
- Not a git repository
|
|
88
|
+
- Branch doesn't exist
|
|
89
|
+
- Merge conflict
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
def __init__(self, operation: str, message: str):
|
|
93
|
+
self.operation = operation
|
|
94
|
+
super().__init__(f"Git {operation} failed: {message}")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class SearchError(FatalToolError):
|
|
98
|
+
"""Raised when a search operation fails.
|
|
99
|
+
|
|
100
|
+
Examples:
|
|
101
|
+
- Invalid regex pattern
|
|
102
|
+
- Search tool not installed
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
def __init__(self, tool: str, message: str):
|
|
106
|
+
self.tool = tool
|
|
107
|
+
super().__init__(f"Search failed ({tool}): {message}")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class FileOperationError(FatalToolError):
|
|
111
|
+
"""Raised when a file operation fails.
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
- Cannot read file (encoding issues)
|
|
115
|
+
- Cannot write file (permissions)
|
|
116
|
+
- Edit operation failed
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
def __init__(self, operation: str, path: str, message: str):
|
|
120
|
+
self.operation = operation
|
|
121
|
+
self.path = path
|
|
122
|
+
super().__init__(f"Failed to {operation} '{path}': {message}")
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""MCP server setup for local tools.
|
|
2
|
+
|
|
3
|
+
This module creates and configures the MCP server with all local tools.
|
|
4
|
+
These tools operate ONLY on the local filesystem and system where the cade
|
|
5
|
+
process is running.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Suppress arcade_mcp_server DEBUG logs (e.g. "Added tool: X") before the library loads.
|
|
9
|
+
# When run via stdio subprocess, parent may also pass LOGURU_LEVEL in env.
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
os.environ.setdefault("LOGURU_LEVEL", "WARNING")
|
|
13
|
+
|
|
14
|
+
from arcade_mcp_server import MCPApp
|
|
15
|
+
|
|
16
|
+
from cade_mcp_local.tools import (
|
|
17
|
+
bash_tool,
|
|
18
|
+
edit_tool,
|
|
19
|
+
git_tool,
|
|
20
|
+
list_files_tool,
|
|
21
|
+
read_file_tool,
|
|
22
|
+
retrieve_tool_result_tool,
|
|
23
|
+
search_recent_context_tool,
|
|
24
|
+
search_tool,
|
|
25
|
+
tool_schema_tool,
|
|
26
|
+
write_file_tool,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Server instructions explaining when to use Local tools
|
|
30
|
+
SERVER_INSTRUCTIONS = """
|
|
31
|
+
Local tools operate ONLY on the local filesystem and system where the cade process
|
|
32
|
+
is running. Use these tools when you need to:
|
|
33
|
+
|
|
34
|
+
- Read, write, or edit files on the same machine as the running cade process
|
|
35
|
+
- Search code in the local project directory
|
|
36
|
+
- Execute shell commands or bash scripts locally
|
|
37
|
+
- Check git status, diff, log, or branches of the local repository
|
|
38
|
+
- Search compacted context backups stored locally
|
|
39
|
+
|
|
40
|
+
Do NOT use these tools for operations on remote systems, cloud resources, or
|
|
41
|
+
external services. For those, use the appropriate remote/cloud tools instead.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def create_app() -> MCPApp:
|
|
46
|
+
"""Create and configure the MCP application with all local tools."""
|
|
47
|
+
app = MCPApp("Local", "stdio", log_level="info")
|
|
48
|
+
|
|
49
|
+
# Set server instructions
|
|
50
|
+
app.instructions = SERVER_INSTRUCTIONS
|
|
51
|
+
|
|
52
|
+
# Filesystem tools
|
|
53
|
+
app.add_tool(list_files_tool)
|
|
54
|
+
app.add_tool(read_file_tool)
|
|
55
|
+
app.add_tool(write_file_tool)
|
|
56
|
+
app.add_tool(edit_tool)
|
|
57
|
+
|
|
58
|
+
# Shell tool
|
|
59
|
+
app.add_tool(bash_tool)
|
|
60
|
+
|
|
61
|
+
# Search tool (consolidated: ripgrep with grep fallback)
|
|
62
|
+
app.add_tool(search_tool)
|
|
63
|
+
|
|
64
|
+
# Git tool (consolidated: status, diff, log, branch)
|
|
65
|
+
app.add_tool(git_tool)
|
|
66
|
+
|
|
67
|
+
# Context tools
|
|
68
|
+
app.add_tool(search_recent_context_tool)
|
|
69
|
+
|
|
70
|
+
# Tool result retrieval (consolidated: full, search, summarize, lines, json, list)
|
|
71
|
+
app.add_tool(retrieve_tool_result_tool)
|
|
72
|
+
|
|
73
|
+
# Tool schema tool (consolidated: list + get)
|
|
74
|
+
app.add_tool(tool_schema_tool)
|
|
75
|
+
|
|
76
|
+
return app
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# Global app instance for the entry point
|
|
80
|
+
app = create_app()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Local MCP tools for filesystem, git, search, shell, and context operations.
|
|
2
|
+
|
|
3
|
+
These tools operate ONLY on the local filesystem and system where the cade process
|
|
4
|
+
is running. Use these tools when you need to read, write, search, or execute
|
|
5
|
+
commands on the same machine as the running cade process.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from cade_mcp_local.tools.context import search_recent_context_tool
|
|
9
|
+
from cade_mcp_local.tools.tool_results import retrieve_tool_result_tool
|
|
10
|
+
from cade_mcp_local.tools.tool_schemas import tool_schema_tool
|
|
11
|
+
from cade_mcp_local.tools.filesystem import (
|
|
12
|
+
edit_tool,
|
|
13
|
+
list_files_tool,
|
|
14
|
+
read_file_tool,
|
|
15
|
+
write_file_tool,
|
|
16
|
+
)
|
|
17
|
+
from cade_mcp_local.tools.git import (
|
|
18
|
+
get_current_branch_name,
|
|
19
|
+
get_status,
|
|
20
|
+
git_tool,
|
|
21
|
+
)
|
|
22
|
+
from cade_mcp_local.tools.search import search_tool
|
|
23
|
+
from cade_mcp_local.tools.shell import bash_tool
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
# Filesystem
|
|
27
|
+
"list_files_tool",
|
|
28
|
+
"read_file_tool",
|
|
29
|
+
"write_file_tool",
|
|
30
|
+
"edit_tool",
|
|
31
|
+
# Git
|
|
32
|
+
"git_tool",
|
|
33
|
+
"get_current_branch_name",
|
|
34
|
+
"get_status",
|
|
35
|
+
# Search
|
|
36
|
+
"search_tool",
|
|
37
|
+
# Shell
|
|
38
|
+
"bash_tool",
|
|
39
|
+
# Context
|
|
40
|
+
"search_recent_context_tool",
|
|
41
|
+
# Tool Results
|
|
42
|
+
"retrieve_tool_result_tool",
|
|
43
|
+
# Tool Schemas
|
|
44
|
+
"tool_schema_tool",
|
|
45
|
+
]
|