machinecommander 0.1.0__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.

Potentially problematic release.


This version of machinecommander might be problematic. Click here for more details.

@@ -0,0 +1,8 @@
1
+ from . import mcp_server
2
+
3
+ def main():
4
+ """Main entry point for the package."""
5
+ mcp_server.main()
6
+
7
+ # Optionally expose other important items at package level
8
+ __all__ = ['main']
@@ -0,0 +1,30 @@
1
+ from mcp.server.fastmcp import FastMCP
2
+ import requests
3
+
4
+ mcp = FastMCP("MachineCommander")
5
+
6
+ @mcp.tool()
7
+ def get_construction_machines_data(question: str) -> dict:
8
+ """MachineCommander is a global system to manage all the construction machines working on construction projects. Use this tool to extract the data of construction machines and projects, and to answer construction related questions. The return value is a list of rows, with each row as a dict."""
9
+ url = f"https://gpt-agent.zhgcloud.com/paipai_mcp/{question}"
10
+ auth = ("zeaho-data", "Zeaho_93246!")
11
+ try:
12
+ response = requests.get(url, auth=auth)
13
+ response.raise_for_status()
14
+ try:
15
+ result_data = response.json()
16
+ result = {"result": result_data}
17
+ except:
18
+ result = {"result": response.text}
19
+ except Exception as e:
20
+ result = {"result": f"请求失败: {str(e)}"}
21
+ return result
22
+
23
+ @mcp.tool()
24
+ def manage_construction_machines(order: str) -> dict:
25
+ """MachineCommander is a global system to manage all the construction machines working on construction projects. Use this tool to send orders to the construction machines."""
26
+ return {"result": "nop"}
27
+
28
+ # Start the server
29
+ def main():
30
+ mcp.run(transport="stdio")
@@ -0,0 +1,188 @@
1
+ import asyncio
2
+ import requests
3
+
4
+ from mcp.server.models import InitializationOptions
5
+ import mcp.types as types
6
+ from mcp.server import NotificationOptions, Server
7
+ from pydantic import AnyUrl
8
+ import mcp.server.stdio
9
+
10
+ # Store notes as a simple key-value dict to demonstrate state management
11
+ notes: dict[str, str] = {}
12
+
13
+ server = Server("MachineCommander")
14
+
15
+ @server.list_resources()
16
+ async def handle_list_resources() -> list[types.Resource]:
17
+ """
18
+ List available note resources.
19
+ Each note is exposed as a resource with a custom note:// URI scheme.
20
+ """
21
+ return [
22
+ types.Resource(
23
+ uri=AnyUrl(f"note://internal/{name}"),
24
+ name=f"Note: {name}",
25
+ description=f"A simple note named {name}",
26
+ mimeType="text/plain",
27
+ )
28
+ for name in notes
29
+ ]
30
+
31
+ @server.read_resource()
32
+ async def handle_read_resource(uri: AnyUrl) -> str:
33
+ """
34
+ Read a specific note's content by its URI.
35
+ The note name is extracted from the URI host component.
36
+ """
37
+ if uri.scheme != "note":
38
+ raise ValueError(f"Unsupported URI scheme: {uri.scheme}")
39
+
40
+ name = uri.path
41
+ if name is not None:
42
+ name = name.lstrip("/")
43
+ return notes[name]
44
+ raise ValueError(f"Note not found: {name}")
45
+
46
+ @server.list_prompts()
47
+ async def handle_list_prompts() -> list[types.Prompt]:
48
+ """
49
+ List available prompts.
50
+ Each prompt can have optional arguments to customize its behavior.
51
+ """
52
+ return [
53
+ types.Prompt(
54
+ name="summarize-notes",
55
+ description="Creates a summary of all notes",
56
+ arguments=[
57
+ types.PromptArgument(
58
+ name="style",
59
+ description="Style of the summary (brief/detailed)",
60
+ required=False,
61
+ )
62
+ ],
63
+ )
64
+ ]
65
+
66
+ @server.get_prompt()
67
+ async def handle_get_prompt(
68
+ name: str, arguments: dict[str, str] | None
69
+ ) -> types.GetPromptResult:
70
+ """
71
+ Generate a prompt by combining arguments with server state.
72
+ The prompt includes all current notes and can be customized via arguments.
73
+ """
74
+ if name != "summarize-notes":
75
+ raise ValueError(f"Unknown prompt: {name}")
76
+
77
+ style = (arguments or {}).get("style", "brief")
78
+ detail_prompt = " Give extensive details." if style == "detailed" else ""
79
+
80
+ return types.GetPromptResult(
81
+ description="Summarize the current notes",
82
+ messages=[
83
+ types.PromptMessage(
84
+ role="user",
85
+ content=types.TextContent(
86
+ type="text",
87
+ text=f"Here are the current notes to summarize:{detail_prompt}\n\n"
88
+ + "\n".join(
89
+ f"- {name}: {content}"
90
+ for name, content in notes.items()
91
+ ),
92
+ ),
93
+ )
94
+ ],
95
+ )
96
+
97
+ @server.list_tools()
98
+ async def handle_list_tools() -> list[types.Tool]:
99
+ """
100
+ List available tools.
101
+ Each tool specifies its arguments using JSON Schema validation.
102
+ """
103
+ return [
104
+ types.Tool(
105
+ name="add-note",
106
+ description="Add a new note",
107
+ inputSchema={
108
+ "type": "object",
109
+ "properties": {
110
+ "name": {"type": "string"},
111
+ "content": {"type": "string"},
112
+ },
113
+ "required": ["name", "content"],
114
+ },
115
+ )
116
+ ]
117
+
118
+ @server.call_tool()
119
+ async def handle_call_tool(
120
+ name: str, arguments: dict | None
121
+ ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
122
+ """
123
+ Handle tool execution requests.
124
+ """
125
+ if name != "add-note":
126
+ raise ValueError(f"Unknown tool: {name}")
127
+
128
+ if not arguments:
129
+ raise ValueError("Missing arguments")
130
+
131
+ note_name = arguments.get("name")
132
+ content = arguments.get("content")
133
+
134
+ if not note_name or not content:
135
+ raise ValueError("Missing name or content")
136
+
137
+ # Update server state
138
+ notes[note_name] = content
139
+
140
+ # Notify clients that resources have changed
141
+ await server.request_context.session.send_resource_list_changed()
142
+
143
+ return [
144
+ types.TextContent(
145
+ type="text",
146
+ text=f"Added note '{note_name}' with content: {content}",
147
+ )
148
+ ]
149
+
150
+ @server.tool()
151
+ async def get_construction_machines_data(question: str) -> dict:
152
+ """MachineCommander is a global system to manage all the construction machines working on construction projects. Use this tool to extract the data of construction machines and projects, and to answer construction related questions. The return value is a list of rows, with each row as a dict."""
153
+ url = f"https://gpt-agent.zhgcloud.com/paipai_mcp/{question}"
154
+ auth = ("zeaho-data", "Zeaho_93246!")
155
+ try:
156
+ loop = asyncio.get_event_loop()
157
+ # 使用线程池避免阻塞事件循环
158
+ def fetch():
159
+ try:
160
+ response = requests.get(url, auth=auth, timeout=10)
161
+ response.raise_for_status()
162
+ try:
163
+ result_data = response.json()
164
+ return {"result": result_data}
165
+ except Exception:
166
+ return {"result": response.text}
167
+ except Exception as e:
168
+ return {"result": f"请求失败: {str(e)}"}
169
+ result = await loop.run_in_executor(None, fetch)
170
+ except Exception as e:
171
+ result = {"result": f"请求失败: {str(e)}"}
172
+ return result
173
+
174
+ async def main():
175
+ # Run the server using stdin/stdout streams
176
+ async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
177
+ await server.run(
178
+ read_stream,
179
+ write_stream,
180
+ InitializationOptions(
181
+ server_name="MachineCommander",
182
+ server_version="0.1.0",
183
+ capabilities=server.get_capabilities(
184
+ notification_options=NotificationOptions(),
185
+ experimental_capabilities={},
186
+ ),
187
+ ),
188
+ )
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: machinecommander
3
+ Version: 0.1.0
4
+ Summary: MachineCommander is an IoT system to manage all the construction machines working on construction projects.
5
+ Author-email: Ye Wang <wangye@zeaho.com>
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: mcp>=1.10.1
8
+ Requires-Dist: requests>=2.31.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # MachineCommander MCP server
12
+
13
+ MachineCommander is an IoT system to manage all the construction machines working on construction projects.
14
+
15
+ ## Components
16
+
17
+ ### Resources
18
+
19
+ The server implements a simple note storage system with:
20
+ - Custom note:// URI scheme for accessing individual notes
21
+ - Each note resource has a name, description and text/plain mimetype
22
+
23
+ ### Prompts
24
+
25
+ The server provides a single prompt:
26
+ - summarize-notes: Creates summaries of all stored notes
27
+ - Optional "style" argument to control detail level (brief/detailed)
28
+ - Generates prompt combining all current notes with style preference
29
+
30
+ ### Tools
31
+
32
+ The server implements one tool:
33
+ - add-note: Adds a new note to the server
34
+ - Takes "name" and "content" as required string arguments
35
+ - Updates server state and notifies clients of resource changes
36
+
37
+ ## Configuration
38
+
39
+ [TODO: Add configuration details specific to your implementation]
40
+
41
+ ## Quickstart
42
+
43
+ ### Install
44
+
45
+ #### Claude Desktop
46
+
47
+ On MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
48
+ On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
49
+
50
+ <details>
51
+ <summary>Development/Unpublished Servers Configuration</summary>
52
+ ```
53
+ "mcpServers": {
54
+ "MachineCommander": {
55
+ "command": "uv",
56
+ "args": [
57
+ "--directory",
58
+ "/Users/yewang/work/ai/machine-commander/MachineCommander",
59
+ "run",
60
+ "MachineCommander"
61
+ ]
62
+ }
63
+ }
64
+ ```
65
+ </details>
66
+
67
+ <details>
68
+ <summary>Published Servers Configuration</summary>
69
+ ```
70
+ "mcpServers": {
71
+ "MachineCommander": {
72
+ "command": "uvx",
73
+ "args": [
74
+ "MachineCommander"
75
+ ]
76
+ }
77
+ }
78
+ ```
79
+ </details>
80
+
81
+ ## Development
82
+
83
+ ### Building and Publishing
84
+
85
+ To prepare the package for distribution:
86
+
87
+ 1. Sync dependencies and update lockfile:
88
+ ```bash
89
+ uv sync
90
+ ```
91
+
92
+ 2. Build package distributions:
93
+ ```bash
94
+ uv build
95
+ ```
96
+
97
+ This will create source and wheel distributions in the `dist/` directory.
98
+
99
+ 3. Publish to PyPI:
100
+ ```bash
101
+ uv publish
102
+ ```
103
+
104
+ Note: You'll need to set PyPI credentials via environment variables or command flags:
105
+ - Token: `--token` or `UV_PUBLISH_TOKEN`
106
+ - Or username/password: `--username`/`UV_PUBLISH_USERNAME` and `--password`/`UV_PUBLISH_PASSWORD`
107
+
108
+ ### Debugging
109
+
110
+ Since MCP servers run over stdio, debugging can be challenging. For the best debugging
111
+ experience, we strongly recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector).
112
+
113
+
114
+ You can launch the MCP Inspector via [`npm`](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) with this command:
115
+
116
+ ```bash
117
+ npx @modelcontextprotocol/inspector uv --directory /Users/yewang/work/ai/machine-commander/MachineCommander run machinecommander
118
+ ```
119
+
120
+
121
+ Upon launching, the Inspector will display a URL that you can access in your browser to begin debugging.
@@ -0,0 +1,7 @@
1
+ machinecommander/__init__.py,sha256=uoRnkrZJolcVImtRw7bS8csjWqsCD1kCl-Ut8qHxb1w,182
2
+ machinecommander/mcp_server.py,sha256=DA49649xLhAbjCiI5BFw7FbTVXA_lxjvIzWAFZRRr8U,1264
3
+ machinecommander/server.py,sha256=QtWUj06y29eO_qeWdXuFT2IxRUU8vqaoJE4R2CFSy6w,6078
4
+ machinecommander-0.1.0.dist-info/METADATA,sha256=opha51p8vV26sonW0NZZoZJtKsookgEYh_RVPDqoNoo,3125
5
+ machinecommander-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ machinecommander-0.1.0.dist-info/entry_points.txt,sha256=WwSKZcxuzujhwJ4Lk7EhGfzSQD1Vf76lW_tDDTDEZrw,59
7
+ machinecommander-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ machinecommander = machinecommander:main