skydeckai-code 0.1.23__py3-none-any.whl
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.
- aidd/__init__.py +11 -0
- aidd/cli.py +141 -0
- aidd/server.py +54 -0
- aidd/tools/__init__.py +155 -0
- aidd/tools/base.py +18 -0
- aidd/tools/code_analysis.py +703 -0
- aidd/tools/code_execution.py +321 -0
- aidd/tools/directory_tools.py +289 -0
- aidd/tools/file_tools.py +784 -0
- aidd/tools/get_active_apps_tool.py +455 -0
- aidd/tools/get_available_windows_tool.py +395 -0
- aidd/tools/git_tools.py +687 -0
- aidd/tools/image_tools.py +127 -0
- aidd/tools/path_tools.py +86 -0
- aidd/tools/screenshot_tool.py +1029 -0
- aidd/tools/state.py +47 -0
- aidd/tools/system_tools.py +190 -0
- skydeckai_code-0.1.23.dist-info/METADATA +628 -0
- skydeckai_code-0.1.23.dist-info/RECORD +22 -0
- skydeckai_code-0.1.23.dist-info/WHEEL +4 -0
- skydeckai_code-0.1.23.dist-info/entry_points.txt +3 -0
- skydeckai_code-0.1.23.dist-info/licenses/LICENSE +201 -0
aidd/__init__.py
ADDED
aidd/cli.py
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
"""Command-line interface for the SkyDeckAI Code MCP server."""
|
2
|
+
|
3
|
+
import argparse
|
4
|
+
import asyncio
|
5
|
+
import json
|
6
|
+
import sys
|
7
|
+
import traceback
|
8
|
+
from contextlib import AsyncExitStack
|
9
|
+
from typing import Optional
|
10
|
+
|
11
|
+
from mcp.client.session import ClientSession
|
12
|
+
from mcp.client.stdio import StdioServerParameters, stdio_client
|
13
|
+
from mcp.types import CallToolResult, TextContent
|
14
|
+
|
15
|
+
|
16
|
+
class MCPClient:
|
17
|
+
"""Client for interacting with the SkyDeckAI Code MCP server."""
|
18
|
+
|
19
|
+
def __init__(self):
|
20
|
+
"""Initialize the client."""
|
21
|
+
self.session: Optional[ClientSession] = None
|
22
|
+
self.exit_stack = AsyncExitStack()
|
23
|
+
self.debug = False
|
24
|
+
|
25
|
+
async def connect(self):
|
26
|
+
"""Connect to the SkyDeckAI Code server."""
|
27
|
+
server_params = StdioServerParameters(command="skydeckai-code", args=[], env=None)
|
28
|
+
transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
|
29
|
+
self.session = await self.exit_stack.enter_async_context(ClientSession(*transport))
|
30
|
+
await self.session.initialize()
|
31
|
+
|
32
|
+
async def list_tools(self):
|
33
|
+
"""List all available tools."""
|
34
|
+
|
35
|
+
response = await self.session.list_tools()
|
36
|
+
print("\nAvailable tools:")
|
37
|
+
for tool in sorted(response.tools, key=lambda x: x.name):
|
38
|
+
print(f"\n{tool.name}:")
|
39
|
+
print(f" Description: {tool.description}")
|
40
|
+
print(" Arguments:")
|
41
|
+
if tool.inputSchema and "properties" in tool.inputSchema:
|
42
|
+
for prop_name, prop_info in tool.inputSchema["properties"].items():
|
43
|
+
required = (
|
44
|
+
"required" in tool.inputSchema
|
45
|
+
and prop_name in tool.inputSchema["required"]
|
46
|
+
)
|
47
|
+
req_str = "(required)" if required else "(optional)"
|
48
|
+
desc = prop_info.get("description", "No description available")
|
49
|
+
print(f" {prop_name} {req_str}: {desc}")
|
50
|
+
else:
|
51
|
+
print(" No arguments required")
|
52
|
+
|
53
|
+
async def call_tool(self, tool_name: str, args_str: Optional[str] = None) -> None:
|
54
|
+
"""Call a specific tool with arguments.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
tool_name: Name of the tool to call
|
58
|
+
args_str: JSON string of tool arguments
|
59
|
+
"""
|
60
|
+
if not self.session:
|
61
|
+
raise RuntimeError("Not connected to server")
|
62
|
+
|
63
|
+
args = {}
|
64
|
+
if args_str:
|
65
|
+
try:
|
66
|
+
args = json.loads(args_str)
|
67
|
+
except json.JSONDecodeError as e:
|
68
|
+
print(f"Error parsing arguments: {e}")
|
69
|
+
return
|
70
|
+
|
71
|
+
try:
|
72
|
+
result = await self.session.call_tool(tool_name, args or {})
|
73
|
+
if isinstance(result, CallToolResult):
|
74
|
+
for content in result.content:
|
75
|
+
if isinstance(content, TextContent):
|
76
|
+
print(content.text)
|
77
|
+
except Exception as e:
|
78
|
+
print(f"Result type: {type(result)}")
|
79
|
+
print(f"Error calling tool: {e}")
|
80
|
+
if self.debug:
|
81
|
+
traceback.print_exc()
|
82
|
+
|
83
|
+
async def cleanup(self):
|
84
|
+
"""Clean up resources."""
|
85
|
+
await self.exit_stack.aclose()
|
86
|
+
|
87
|
+
|
88
|
+
def main():
|
89
|
+
"""Main entry point for the CLI."""
|
90
|
+
parser = argparse.ArgumentParser(
|
91
|
+
description="CLI for the SkyDeckAI Code MCP server",
|
92
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
93
|
+
epilog="""
|
94
|
+
Examples:
|
95
|
+
# List all available tools
|
96
|
+
skydeckai-code-cli --list-tools
|
97
|
+
|
98
|
+
# List directory contents
|
99
|
+
skydeckai-code-cli --tool list_directory --args '{"path": "."}'
|
100
|
+
|
101
|
+
# Update allowed directory
|
102
|
+
skydeckai-code-cli --tool update_allowed_directory --args '{"directory": "~/Code/project"}'
|
103
|
+
|
104
|
+
# Read a file
|
105
|
+
skydeckai-code-cli --tool read_file --args '{"path": "README.md"}'
|
106
|
+
|
107
|
+
# Enable debug output
|
108
|
+
skydeckai-code-cli --debug --tool read_file --args '{"path": "README.md"}'""")
|
109
|
+
parser.add_argument("--list-tools", action="store_true", help="List available tools")
|
110
|
+
parser.add_argument("--tool", help="Tool to call")
|
111
|
+
parser.add_argument("--args", help='Tool arguments in JSON format (e.g. \'{"directory":"/path/to/dir"}\')')
|
112
|
+
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
|
113
|
+
|
114
|
+
async def run(args):
|
115
|
+
client = MCPClient()
|
116
|
+
client.debug = args.debug
|
117
|
+
try:
|
118
|
+
async with AsyncExitStack() as _:
|
119
|
+
await client.connect()
|
120
|
+
if args.list_tools:
|
121
|
+
await client.list_tools()
|
122
|
+
elif args.tool:
|
123
|
+
if args.debug and args.args:
|
124
|
+
print(f"Parsing JSON arguments: {args.args}")
|
125
|
+
await client.call_tool(args.tool, args.args)
|
126
|
+
else:
|
127
|
+
parser.print_help()
|
128
|
+
finally:
|
129
|
+
await client.cleanup()
|
130
|
+
|
131
|
+
try:
|
132
|
+
args = parser.parse_args()
|
133
|
+
except Exception as e:
|
134
|
+
print(f"Error: {e}", file=sys.stderr)
|
135
|
+
|
136
|
+
asyncio.run(run(args))
|
137
|
+
return 0
|
138
|
+
|
139
|
+
|
140
|
+
if __name__ == "__main__":
|
141
|
+
sys.exit(main())
|
aidd/server.py
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
import asyncio
|
2
|
+
|
3
|
+
import mcp.server.stdio
|
4
|
+
import mcp.types as types
|
5
|
+
from mcp.server import NotificationOptions, Server
|
6
|
+
from mcp.server.models import InitializationOptions
|
7
|
+
|
8
|
+
from .tools import TOOL_DEFINITIONS, TOOL_HANDLERS
|
9
|
+
|
10
|
+
server = Server("skydeckai-code")
|
11
|
+
|
12
|
+
@server.list_tools()
|
13
|
+
async def handle_list_tools() -> list[types.Tool]:
|
14
|
+
"""
|
15
|
+
List available tools.
|
16
|
+
Each tool specifies its arguments using JSON Schema validation.
|
17
|
+
"""
|
18
|
+
return [types.Tool(**tool) for tool in TOOL_DEFINITIONS]
|
19
|
+
|
20
|
+
@server.call_tool()
|
21
|
+
async def handle_call_tool(
|
22
|
+
name: str, arguments: dict | None
|
23
|
+
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
|
24
|
+
"""
|
25
|
+
Handle tool execution requests.
|
26
|
+
"""
|
27
|
+
if not arguments:
|
28
|
+
arguments = {}
|
29
|
+
|
30
|
+
handler = TOOL_HANDLERS.get(name)
|
31
|
+
if not handler:
|
32
|
+
raise ValueError(f"Unknown tool: {name}")
|
33
|
+
|
34
|
+
return await handler(arguments)
|
35
|
+
|
36
|
+
async def main():
|
37
|
+
# Run the server using stdin/stdout streams
|
38
|
+
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
|
39
|
+
await server.run(
|
40
|
+
read_stream,
|
41
|
+
write_stream,
|
42
|
+
InitializationOptions(
|
43
|
+
server_name="skydeckai-code",
|
44
|
+
server_version="0.1.0",
|
45
|
+
capabilities=server.get_capabilities(
|
46
|
+
notification_options=NotificationOptions(),
|
47
|
+
experimental_capabilities={},
|
48
|
+
),
|
49
|
+
),
|
50
|
+
)
|
51
|
+
|
52
|
+
# This is needed if you'd like to connect to a custom client
|
53
|
+
if __name__ == "__main__":
|
54
|
+
asyncio.run(main())
|
aidd/tools/__init__.py
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
from .code_analysis import handle_codebase_mapper, codebase_mapper_tool
|
2
|
+
from .code_execution import (
|
3
|
+
execute_code_tool,
|
4
|
+
execute_shell_script_tool,
|
5
|
+
handle_execute_code,
|
6
|
+
handle_execute_shell_script,
|
7
|
+
)
|
8
|
+
from .directory_tools import (
|
9
|
+
create_directory_tool,
|
10
|
+
directory_tree_tool,
|
11
|
+
handle_create_directory,
|
12
|
+
handle_directory_tree,
|
13
|
+
handle_list_directory,
|
14
|
+
list_directory_tool,
|
15
|
+
)
|
16
|
+
from .file_tools import (
|
17
|
+
delete_file_tool,
|
18
|
+
edit_file_tool,
|
19
|
+
get_file_info_tool,
|
20
|
+
handle_delete_file,
|
21
|
+
handle_edit_file,
|
22
|
+
handle_get_file_info,
|
23
|
+
handle_move_file,
|
24
|
+
handle_read_file,
|
25
|
+
handle_read_multiple_files,
|
26
|
+
handle_search_files,
|
27
|
+
handle_write_file,
|
28
|
+
move_file_tool,
|
29
|
+
read_file_tool,
|
30
|
+
read_multiple_files_tool,
|
31
|
+
search_files_tool,
|
32
|
+
write_file_tool,
|
33
|
+
)
|
34
|
+
from .get_active_apps_tool import get_active_apps_tool, handle_get_active_apps
|
35
|
+
from .get_available_windows_tool import get_available_windows_tool, handle_get_available_windows
|
36
|
+
from .git_tools import (
|
37
|
+
git_add_tool,
|
38
|
+
git_checkout_tool,
|
39
|
+
git_commit_tool,
|
40
|
+
git_create_branch_tool,
|
41
|
+
git_diff_staged_tool,
|
42
|
+
git_diff_tool,
|
43
|
+
git_diff_unstaged_tool,
|
44
|
+
git_init_tool,
|
45
|
+
git_log_tool,
|
46
|
+
git_reset_tool,
|
47
|
+
git_show_tool,
|
48
|
+
git_status_tool,
|
49
|
+
handle_git_add,
|
50
|
+
handle_git_checkout,
|
51
|
+
handle_git_commit,
|
52
|
+
handle_git_create_branch,
|
53
|
+
handle_git_diff,
|
54
|
+
handle_git_diff_staged,
|
55
|
+
handle_git_diff_unstaged,
|
56
|
+
handle_git_init,
|
57
|
+
handle_git_log,
|
58
|
+
handle_git_reset,
|
59
|
+
handle_git_show,
|
60
|
+
handle_git_status,
|
61
|
+
)
|
62
|
+
from .image_tools import read_image_file_tool, handle_read_image_file
|
63
|
+
from .path_tools import (
|
64
|
+
get_allowed_directory_tool,
|
65
|
+
handle_get_allowed_directory,
|
66
|
+
handle_update_allowed_directory,
|
67
|
+
update_allowed_directory_tool,
|
68
|
+
)
|
69
|
+
from .screenshot_tool import (
|
70
|
+
capture_screenshot_tool,
|
71
|
+
handle_capture_screenshot,
|
72
|
+
)
|
73
|
+
from .system_tools import get_system_info_tool, handle_get_system_info
|
74
|
+
|
75
|
+
# Export all tools definitions
|
76
|
+
TOOL_DEFINITIONS = [
|
77
|
+
get_allowed_directory_tool(),
|
78
|
+
write_file_tool(),
|
79
|
+
update_allowed_directory_tool(),
|
80
|
+
create_directory_tool(),
|
81
|
+
edit_file_tool(),
|
82
|
+
list_directory_tool(),
|
83
|
+
read_file_tool(),
|
84
|
+
read_multiple_files_tool(),
|
85
|
+
move_file_tool(),
|
86
|
+
search_files_tool(),
|
87
|
+
delete_file_tool(),
|
88
|
+
get_file_info_tool(),
|
89
|
+
directory_tree_tool(),
|
90
|
+
execute_code_tool(),
|
91
|
+
execute_shell_script_tool(),
|
92
|
+
codebase_mapper_tool(),
|
93
|
+
# Git tools
|
94
|
+
git_init_tool(),
|
95
|
+
git_status_tool(),
|
96
|
+
git_diff_unstaged_tool(),
|
97
|
+
git_diff_staged_tool(),
|
98
|
+
git_diff_tool(),
|
99
|
+
git_commit_tool(),
|
100
|
+
git_add_tool(),
|
101
|
+
git_reset_tool(),
|
102
|
+
git_log_tool(),
|
103
|
+
git_create_branch_tool(),
|
104
|
+
git_checkout_tool(),
|
105
|
+
git_show_tool(),
|
106
|
+
get_system_info_tool(),
|
107
|
+
# Screenshot tools
|
108
|
+
capture_screenshot_tool(),
|
109
|
+
# System context tools
|
110
|
+
get_active_apps_tool(),
|
111
|
+
get_available_windows_tool(),
|
112
|
+
# Image tools
|
113
|
+
read_image_file_tool(),
|
114
|
+
]
|
115
|
+
|
116
|
+
# Export all handlers
|
117
|
+
TOOL_HANDLERS = {
|
118
|
+
"get_allowed_directory": handle_get_allowed_directory,
|
119
|
+
"update_allowed_directory": handle_update_allowed_directory,
|
120
|
+
"list_directory": handle_list_directory,
|
121
|
+
"create_directory": handle_create_directory,
|
122
|
+
"read_file": handle_read_file,
|
123
|
+
"write_file": handle_write_file,
|
124
|
+
"edit_file": handle_edit_file,
|
125
|
+
"read_multiple_files": handle_read_multiple_files,
|
126
|
+
"move_file": handle_move_file,
|
127
|
+
"search_files": handle_search_files,
|
128
|
+
"delete_file": handle_delete_file,
|
129
|
+
"get_file_info": handle_get_file_info,
|
130
|
+
"directory_tree": handle_directory_tree,
|
131
|
+
"execute_code": handle_execute_code,
|
132
|
+
"execute_shell_script": handle_execute_shell_script,
|
133
|
+
"codebase_mapper": handle_codebase_mapper,
|
134
|
+
# Git handlers
|
135
|
+
"git_init": handle_git_init,
|
136
|
+
"git_status": handle_git_status,
|
137
|
+
"git_diff_unstaged": handle_git_diff_unstaged,
|
138
|
+
"git_diff_staged": handle_git_diff_staged,
|
139
|
+
"git_diff": handle_git_diff,
|
140
|
+
"git_commit": handle_git_commit,
|
141
|
+
"git_add": handle_git_add,
|
142
|
+
"git_reset": handle_git_reset,
|
143
|
+
"git_log": handle_git_log,
|
144
|
+
"git_create_branch": handle_git_create_branch,
|
145
|
+
"git_checkout": handle_git_checkout,
|
146
|
+
"git_show": handle_git_show,
|
147
|
+
"get_system_info": handle_get_system_info,
|
148
|
+
# Screenshot handlers
|
149
|
+
"capture_screenshot": handle_capture_screenshot,
|
150
|
+
# System context handlers
|
151
|
+
"get_active_apps": handle_get_active_apps,
|
152
|
+
"get_available_windows": handle_get_available_windows,
|
153
|
+
# Image handlers
|
154
|
+
"read_image_file": handle_read_image_file,
|
155
|
+
}
|
aidd/tools/base.py
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
3
|
+
import mcp.types as types
|
4
|
+
|
5
|
+
|
6
|
+
class Tool:
|
7
|
+
"""Base class for all tools"""
|
8
|
+
name: str
|
9
|
+
description: str
|
10
|
+
input_schema: Dict[str, Any]
|
11
|
+
|
12
|
+
@classmethod
|
13
|
+
def get_definition(cls) -> types.Tool:
|
14
|
+
return types.Tool(
|
15
|
+
name=cls.name,
|
16
|
+
description=cls.description,
|
17
|
+
inputSchema=cls.input_schema
|
18
|
+
)
|