@josephyan/qingflow-app-builder-mcp 0.1.0-beta.9
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.
- package/README.md +21 -0
- package/docs/local-agent-install.md +228 -0
- package/entry_point.py +13 -0
- package/npm/bin/qingflow-app-builder-mcp.mjs +7 -0
- package/npm/lib/runtime.mjs +146 -0
- package/npm/scripts/postinstall.mjs +12 -0
- package/package.json +33 -0
- package/pyproject.toml +64 -0
- package/qingflow-app-builder-mcp +15 -0
- package/src/qingflow_mcp/__init__.py +5 -0
- package/src/qingflow_mcp/__main__.py +5 -0
- package/src/qingflow_mcp/backend_client.py +336 -0
- package/src/qingflow_mcp/config.py +182 -0
- package/src/qingflow_mcp/errors.py +66 -0
- package/src/qingflow_mcp/json_types.py +18 -0
- package/src/qingflow_mcp/list_type_labels.py +52 -0
- package/src/qingflow_mcp/server.py +70 -0
- package/src/qingflow_mcp/server_app_builder.py +352 -0
- package/src/qingflow_mcp/server_app_user.py +334 -0
- package/src/qingflow_mcp/session_store.py +249 -0
- package/src/qingflow_mcp/solution/__init__.py +6 -0
- package/src/qingflow_mcp/solution/build_assembly_store.py +137 -0
- package/src/qingflow_mcp/solution/compiler/__init__.py +265 -0
- package/src/qingflow_mcp/solution/compiler/chart_compiler.py +96 -0
- package/src/qingflow_mcp/solution/compiler/form_compiler.py +456 -0
- package/src/qingflow_mcp/solution/compiler/icon_utils.py +113 -0
- package/src/qingflow_mcp/solution/compiler/navigation_compiler.py +57 -0
- package/src/qingflow_mcp/solution/compiler/package_compiler.py +19 -0
- package/src/qingflow_mcp/solution/compiler/portal_compiler.py +60 -0
- package/src/qingflow_mcp/solution/compiler/view_compiler.py +51 -0
- package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +134 -0
- package/src/qingflow_mcp/solution/design_session.py +222 -0
- package/src/qingflow_mcp/solution/design_store.py +100 -0
- package/src/qingflow_mcp/solution/executor.py +2065 -0
- package/src/qingflow_mcp/solution/normalizer.py +23 -0
- package/src/qingflow_mcp/solution/run_store.py +221 -0
- package/src/qingflow_mcp/solution/spec_models.py +853 -0
- package/src/qingflow_mcp/tools/__init__.py +1 -0
- package/src/qingflow_mcp/tools/app_tools.py +406 -0
- package/src/qingflow_mcp/tools/approval_tools.py +498 -0
- package/src/qingflow_mcp/tools/auth_tools.py +514 -0
- package/src/qingflow_mcp/tools/base.py +81 -0
- package/src/qingflow_mcp/tools/directory_tools.py +476 -0
- package/src/qingflow_mcp/tools/file_tools.py +375 -0
- package/src/qingflow_mcp/tools/navigation_tools.py +177 -0
- package/src/qingflow_mcp/tools/package_tools.py +142 -0
- package/src/qingflow_mcp/tools/portal_tools.py +100 -0
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +235 -0
- package/src/qingflow_mcp/tools/record_tools.py +4307 -0
- package/src/qingflow_mcp/tools/role_tools.py +94 -0
- package/src/qingflow_mcp/tools/solution_tools.py +2680 -0
- package/src/qingflow_mcp/tools/task_tools.py +692 -0
- package/src/qingflow_mcp/tools/view_tools.py +280 -0
- package/src/qingflow_mcp/tools/workflow_tools.py +238 -0
- package/src/qingflow_mcp/tools/workspace_tools.py +170 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from mcp.server.fastmcp import FastMCP
|
|
4
|
+
|
|
5
|
+
from .backend_client import BackendClient
|
|
6
|
+
from .session_store import SessionStore
|
|
7
|
+
from .tools.app_tools import AppTools
|
|
8
|
+
from .tools.auth_tools import AuthTools
|
|
9
|
+
from .tools.file_tools import FileTools
|
|
10
|
+
from .tools.package_tools import PackageTools
|
|
11
|
+
from .tools.navigation_tools import NavigationTools
|
|
12
|
+
from .tools.approval_tools import ApprovalTools
|
|
13
|
+
from .tools.directory_tools import DirectoryTools
|
|
14
|
+
from .tools.portal_tools import PortalTools
|
|
15
|
+
from .tools.qingbi_report_tools import QingbiReportTools
|
|
16
|
+
from .tools.record_tools import RecordTools
|
|
17
|
+
from .tools.role_tools import RoleTools
|
|
18
|
+
from .tools.solution_tools import SolutionTools
|
|
19
|
+
from .tools.task_tools import TaskTools
|
|
20
|
+
from .tools.view_tools import ViewTools
|
|
21
|
+
from .tools.workflow_tools import WorkflowTools
|
|
22
|
+
from .tools.workspace_tools import WorkspaceTools
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def build_server() -> FastMCP:
|
|
26
|
+
server = FastMCP(
|
|
27
|
+
"Qingflow MCP",
|
|
28
|
+
instructions=(
|
|
29
|
+
"Use auth_login first, then workspace_list and workspace_select. "
|
|
30
|
+
"All resource tools operate with the logged-in user's Qingflow permissions.\n\n"
|
|
31
|
+
"Task Center (待办/已办) handling:\n"
|
|
32
|
+
"- Use task_statistics to get counts of pending tasks (todo_count), timeouts, urged, etc.\n"
|
|
33
|
+
"- Use task_list to query tasks. Type values: 1=todo (待办), 2=initiated (我发起的), 3=cc (抄送), 5=done (已办).\n"
|
|
34
|
+
"- Use task_list_grouped to get tasks grouped by form/worksheet.\n"
|
|
35
|
+
"- Use task_mark_read to mark a specific task as read.\n"
|
|
36
|
+
"- Use task_urge to send an urgent reminder for a pending task.\n"
|
|
37
|
+
"- Process status values: 1=all, 2=processing, 3=passed, 4=refused, 5=need_supply, 6=urged, 7=timeout, 8=pre_timeout, 9=unread.\n"
|
|
38
|
+
"- After identifying the exact task node and record, use record_approve, record_reject, record_rollback, record_transfer, record_reassign, or record_countersign as needed."
|
|
39
|
+
),
|
|
40
|
+
)
|
|
41
|
+
sessions = SessionStore()
|
|
42
|
+
backend = BackendClient()
|
|
43
|
+
AuthTools(sessions, backend).register(server)
|
|
44
|
+
WorkspaceTools(sessions, backend).register(server)
|
|
45
|
+
FileTools(sessions, backend).register(server)
|
|
46
|
+
RecordTools(sessions, backend).register(server)
|
|
47
|
+
RoleTools(sessions, backend).register(server)
|
|
48
|
+
AppTools(sessions, backend).register(server)
|
|
49
|
+
QingbiReportTools(sessions, backend).register(server)
|
|
50
|
+
PackageTools(sessions, backend).register(server)
|
|
51
|
+
NavigationTools(sessions, backend).register(server)
|
|
52
|
+
ApprovalTools(sessions, backend).register(server)
|
|
53
|
+
PortalTools(sessions, backend).register(server)
|
|
54
|
+
DirectoryTools(sessions, backend).register(server)
|
|
55
|
+
WorkflowTools(sessions, backend).register(server)
|
|
56
|
+
ViewTools(sessions, backend).register(server)
|
|
57
|
+
SolutionTools(sessions, backend).register(server)
|
|
58
|
+
TaskTools(sessions, backend).register(server)
|
|
59
|
+
return server
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
mcp = build_server()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def main() -> None:
|
|
66
|
+
mcp.run()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
main()
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from mcp.server.fastmcp import FastMCP
|
|
4
|
+
|
|
5
|
+
from .backend_client import BackendClient
|
|
6
|
+
from .config import DEFAULT_PROFILE
|
|
7
|
+
from .session_store import SessionStore
|
|
8
|
+
from .tools.app_tools import AppTools
|
|
9
|
+
from .tools.auth_tools import AuthTools
|
|
10
|
+
from .tools.file_tools import FileTools
|
|
11
|
+
from .tools.navigation_tools import NavigationTools
|
|
12
|
+
from .tools.package_tools import PackageTools
|
|
13
|
+
from .tools.portal_tools import PortalTools
|
|
14
|
+
from .tools.solution_tools import SolutionTools
|
|
15
|
+
from .tools.workspace_tools import WorkspaceTools
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def build_builder_server() -> FastMCP:
|
|
19
|
+
server = FastMCP(
|
|
20
|
+
"Qingflow App Builder MCP",
|
|
21
|
+
instructions=(
|
|
22
|
+
"Use this server for high-level Qingflow builder workflows. "
|
|
23
|
+
"Call solution_schema_example before generating non-trivial builder payloads. "
|
|
24
|
+
"Prefer solution_build_app for package/entity/field/layout design, then solution_build_flow for workflow, "
|
|
25
|
+
"then solution_build_views, solution_build_analytics_portal, and solution_build_navigation. "
|
|
26
|
+
"Avoid handcrafting low-level workflow/view/report payloads."
|
|
27
|
+
),
|
|
28
|
+
)
|
|
29
|
+
sessions = SessionStore()
|
|
30
|
+
backend = BackendClient()
|
|
31
|
+
auth = AuthTools(sessions, backend)
|
|
32
|
+
workspace = WorkspaceTools(sessions, backend)
|
|
33
|
+
files = FileTools(sessions, backend)
|
|
34
|
+
apps = AppTools(sessions, backend)
|
|
35
|
+
packages = PackageTools(sessions, backend)
|
|
36
|
+
portals = PortalTools(sessions, backend)
|
|
37
|
+
navigation = NavigationTools(sessions, backend)
|
|
38
|
+
solution = SolutionTools(sessions, backend)
|
|
39
|
+
|
|
40
|
+
@server.tool()
|
|
41
|
+
def auth_login(
|
|
42
|
+
profile: str = DEFAULT_PROFILE,
|
|
43
|
+
base_url: str | None = None,
|
|
44
|
+
qf_version: str | None = None,
|
|
45
|
+
email: str = "",
|
|
46
|
+
password: str = "",
|
|
47
|
+
persist: bool = True,
|
|
48
|
+
) -> dict:
|
|
49
|
+
return auth.auth_login(
|
|
50
|
+
profile=profile,
|
|
51
|
+
base_url=base_url,
|
|
52
|
+
qf_version=qf_version,
|
|
53
|
+
email=email,
|
|
54
|
+
password=password,
|
|
55
|
+
persist=persist,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
@server.tool()
|
|
59
|
+
def auth_use_token(
|
|
60
|
+
profile: str = DEFAULT_PROFILE,
|
|
61
|
+
base_url: str | None = None,
|
|
62
|
+
qf_version: str | None = None,
|
|
63
|
+
token: str = "",
|
|
64
|
+
ws_id: int | None = None,
|
|
65
|
+
persist: bool = False,
|
|
66
|
+
) -> dict:
|
|
67
|
+
return auth.auth_use_token(
|
|
68
|
+
profile=profile,
|
|
69
|
+
base_url=base_url,
|
|
70
|
+
qf_version=qf_version,
|
|
71
|
+
token=token,
|
|
72
|
+
ws_id=ws_id,
|
|
73
|
+
persist=persist,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
@server.tool()
|
|
77
|
+
def auth_whoami(profile: str = DEFAULT_PROFILE) -> dict:
|
|
78
|
+
return auth.auth_whoami(profile=profile)
|
|
79
|
+
|
|
80
|
+
@server.tool()
|
|
81
|
+
def auth_logout(profile: str = DEFAULT_PROFILE, forget_persisted: bool = False) -> dict:
|
|
82
|
+
return auth.auth_logout(profile=profile, forget_persisted=forget_persisted)
|
|
83
|
+
|
|
84
|
+
@server.tool()
|
|
85
|
+
def workspace_list(
|
|
86
|
+
profile: str = DEFAULT_PROFILE,
|
|
87
|
+
page_num: int = 1,
|
|
88
|
+
page_size: int = 20,
|
|
89
|
+
include_external: bool = False,
|
|
90
|
+
) -> dict:
|
|
91
|
+
return workspace.workspace_list(
|
|
92
|
+
profile=profile,
|
|
93
|
+
page_num=page_num,
|
|
94
|
+
page_size=page_size,
|
|
95
|
+
include_external=include_external,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
@server.tool()
|
|
99
|
+
def workspace_select(profile: str = DEFAULT_PROFILE, ws_id: int = 0) -> dict:
|
|
100
|
+
return workspace.workspace_select(profile=profile, ws_id=ws_id)
|
|
101
|
+
|
|
102
|
+
@server.tool()
|
|
103
|
+
def file_upload_local(
|
|
104
|
+
profile: str = DEFAULT_PROFILE,
|
|
105
|
+
upload_kind: str = "attachment",
|
|
106
|
+
file_path: str = "",
|
|
107
|
+
upload_mark: str | None = None,
|
|
108
|
+
content_type: str | None = None,
|
|
109
|
+
bucket_type: str | None = None,
|
|
110
|
+
path_id: int | None = None,
|
|
111
|
+
file_related_url: str | None = None,
|
|
112
|
+
) -> dict:
|
|
113
|
+
return files.file_upload_local(
|
|
114
|
+
profile=profile,
|
|
115
|
+
upload_kind=upload_kind,
|
|
116
|
+
file_path=file_path,
|
|
117
|
+
upload_mark=upload_mark,
|
|
118
|
+
content_type=content_type,
|
|
119
|
+
bucket_type=bucket_type,
|
|
120
|
+
path_id=path_id,
|
|
121
|
+
file_related_url=file_related_url,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
@server.tool()
|
|
125
|
+
def app_list(profile: str = DEFAULT_PROFILE, ship_auth: bool = False) -> dict:
|
|
126
|
+
return apps.app_list(profile=profile, ship_auth=ship_auth)
|
|
127
|
+
|
|
128
|
+
@server.tool()
|
|
129
|
+
def app_search(profile: str = DEFAULT_PROFILE, keyword: str = "", page_num: int = 1, page_size: int = 50) -> dict:
|
|
130
|
+
return apps.app_search(profile=profile, keyword=keyword, page_num=page_num, page_size=page_size)
|
|
131
|
+
|
|
132
|
+
@server.tool()
|
|
133
|
+
def app_get_base(profile: str = DEFAULT_PROFILE, app_key: str = "", include_raw: bool = False) -> dict:
|
|
134
|
+
return apps.app_get_base(profile=profile, app_key=app_key, include_raw=include_raw)
|
|
135
|
+
|
|
136
|
+
@server.tool()
|
|
137
|
+
def app_get_form_schema(
|
|
138
|
+
profile: str = DEFAULT_PROFILE,
|
|
139
|
+
app_key: str = "",
|
|
140
|
+
form_type: int = 1,
|
|
141
|
+
being_draft: bool | None = None,
|
|
142
|
+
being_apply: bool | None = None,
|
|
143
|
+
audit_node_id: int | None = None,
|
|
144
|
+
include_raw: bool = False,
|
|
145
|
+
) -> dict:
|
|
146
|
+
return apps.app_get_form_schema(
|
|
147
|
+
profile=profile,
|
|
148
|
+
app_key=app_key,
|
|
149
|
+
form_type=form_type,
|
|
150
|
+
being_draft=being_draft,
|
|
151
|
+
being_apply=being_apply,
|
|
152
|
+
audit_node_id=audit_node_id,
|
|
153
|
+
include_raw=include_raw,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
@server.tool()
|
|
157
|
+
def app_create(profile: str = DEFAULT_PROFILE, payload: dict | None = None) -> dict:
|
|
158
|
+
return apps.app_create(profile=profile, payload=payload or {})
|
|
159
|
+
|
|
160
|
+
@server.tool()
|
|
161
|
+
def app_publish(profile: str = DEFAULT_PROFILE, app_key: str = "", payload: dict | None = None) -> dict:
|
|
162
|
+
return apps.app_publish(profile=profile, app_key=app_key, payload=payload or {})
|
|
163
|
+
|
|
164
|
+
@server.tool()
|
|
165
|
+
def package_list(profile: str = DEFAULT_PROFILE, trial_status: str = "all") -> dict:
|
|
166
|
+
return packages.package_list(profile=profile, trial_status=trial_status)
|
|
167
|
+
|
|
168
|
+
@server.tool()
|
|
169
|
+
def package_get(profile: str = DEFAULT_PROFILE, tag_id: int = 0) -> dict:
|
|
170
|
+
return packages.package_get(profile=profile, tag_id=tag_id)
|
|
171
|
+
|
|
172
|
+
@server.tool()
|
|
173
|
+
def portal_list(profile: str = DEFAULT_PROFILE) -> dict:
|
|
174
|
+
return portals.portal_list(profile=profile)
|
|
175
|
+
|
|
176
|
+
@server.tool()
|
|
177
|
+
def portal_get(profile: str = DEFAULT_PROFILE, dash_key: str = "", being_draft: bool = False) -> dict:
|
|
178
|
+
return portals.portal_get(profile=profile, dash_key=dash_key, being_draft=being_draft)
|
|
179
|
+
|
|
180
|
+
@server.tool()
|
|
181
|
+
def navigation_list_published(profile: str = DEFAULT_PROFILE, page_num: int = 1, page_size: int = 50) -> dict:
|
|
182
|
+
return navigation.navigation_list_published(profile=profile, page_num=page_num, page_size=page_size)
|
|
183
|
+
|
|
184
|
+
@server.tool()
|
|
185
|
+
def navigation_list_draft_all(profile: str = DEFAULT_PROFILE, query_key: str | None = None) -> dict:
|
|
186
|
+
return navigation.navigation_list_draft_all(profile=profile, query_key=query_key)
|
|
187
|
+
|
|
188
|
+
@server.tool()
|
|
189
|
+
def navigation_get_status(profile: str = DEFAULT_PROFILE) -> dict:
|
|
190
|
+
return navigation.navigation_get_status(profile=profile)
|
|
191
|
+
|
|
192
|
+
@server.tool()
|
|
193
|
+
def solution_design_session(
|
|
194
|
+
action: str = "get",
|
|
195
|
+
session_id: str = "",
|
|
196
|
+
stage: str | None = None,
|
|
197
|
+
design_patch: dict | None = None,
|
|
198
|
+
metadata: dict | None = None,
|
|
199
|
+
) -> dict:
|
|
200
|
+
return solution.solution_design_session(
|
|
201
|
+
action=action,
|
|
202
|
+
session_id=session_id,
|
|
203
|
+
stage=stage,
|
|
204
|
+
design_patch=design_patch or {},
|
|
205
|
+
metadata=metadata or {},
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
@server.tool()
|
|
209
|
+
def solution_schema_example(stage: str = "app", intent: str = "minimal") -> dict:
|
|
210
|
+
return solution.solution_schema_example(stage=stage, intent=intent)
|
|
211
|
+
|
|
212
|
+
@server.tool()
|
|
213
|
+
def solution_build_all(
|
|
214
|
+
profile: str = DEFAULT_PROFILE,
|
|
215
|
+
mode: str = "plan",
|
|
216
|
+
build_id: str = "",
|
|
217
|
+
solution_spec: dict | None = None,
|
|
218
|
+
publish: bool = True,
|
|
219
|
+
run_label: str | None = None,
|
|
220
|
+
target: dict | None = None,
|
|
221
|
+
repair_patch: dict | None = None,
|
|
222
|
+
verify: bool = False,
|
|
223
|
+
) -> dict:
|
|
224
|
+
return solution.solution_build_all(
|
|
225
|
+
profile=profile,
|
|
226
|
+
mode=mode,
|
|
227
|
+
build_id=build_id,
|
|
228
|
+
solution_spec=solution_spec or {},
|
|
229
|
+
publish=publish,
|
|
230
|
+
run_label=run_label,
|
|
231
|
+
target=target or {},
|
|
232
|
+
repair_patch=repair_patch or {},
|
|
233
|
+
verify=verify,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
@server.tool()
|
|
237
|
+
def solution_build_app(
|
|
238
|
+
profile: str = DEFAULT_PROFILE,
|
|
239
|
+
mode: str = "plan",
|
|
240
|
+
build_id: str = "",
|
|
241
|
+
app_spec: dict | None = None,
|
|
242
|
+
publish: bool = True,
|
|
243
|
+
run_label: str | None = None,
|
|
244
|
+
target: dict | None = None,
|
|
245
|
+
repair_patch: dict | None = None,
|
|
246
|
+
) -> dict:
|
|
247
|
+
return solution.solution_build_app(
|
|
248
|
+
profile=profile,
|
|
249
|
+
mode=mode,
|
|
250
|
+
build_id=build_id,
|
|
251
|
+
app_spec=app_spec or {},
|
|
252
|
+
publish=publish,
|
|
253
|
+
run_label=run_label,
|
|
254
|
+
target=target or {},
|
|
255
|
+
repair_patch=repair_patch or {},
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
@server.tool()
|
|
259
|
+
def solution_build_flow(
|
|
260
|
+
profile: str = DEFAULT_PROFILE,
|
|
261
|
+
mode: str = "plan",
|
|
262
|
+
build_id: str = "",
|
|
263
|
+
flow_spec: dict | None = None,
|
|
264
|
+
publish: bool = True,
|
|
265
|
+
run_label: str | None = None,
|
|
266
|
+
repair_patch: dict | None = None,
|
|
267
|
+
) -> dict:
|
|
268
|
+
return solution.solution_build_flow(
|
|
269
|
+
profile=profile,
|
|
270
|
+
mode=mode,
|
|
271
|
+
build_id=build_id,
|
|
272
|
+
flow_spec=flow_spec or {},
|
|
273
|
+
publish=publish,
|
|
274
|
+
run_label=run_label,
|
|
275
|
+
repair_patch=repair_patch or {},
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
@server.tool()
|
|
279
|
+
def solution_build_views(
|
|
280
|
+
profile: str = DEFAULT_PROFILE,
|
|
281
|
+
mode: str = "plan",
|
|
282
|
+
build_id: str = "",
|
|
283
|
+
views_spec: dict | None = None,
|
|
284
|
+
publish: bool = True,
|
|
285
|
+
run_label: str | None = None,
|
|
286
|
+
repair_patch: dict | None = None,
|
|
287
|
+
) -> dict:
|
|
288
|
+
return solution.solution_build_views(
|
|
289
|
+
profile=profile,
|
|
290
|
+
mode=mode,
|
|
291
|
+
build_id=build_id,
|
|
292
|
+
views_spec=views_spec or {},
|
|
293
|
+
publish=publish,
|
|
294
|
+
run_label=run_label,
|
|
295
|
+
repair_patch=repair_patch or {},
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
@server.tool()
|
|
299
|
+
def solution_build_analytics_portal(
|
|
300
|
+
profile: str = DEFAULT_PROFILE,
|
|
301
|
+
mode: str = "plan",
|
|
302
|
+
build_id: str = "",
|
|
303
|
+
analytics_portal_spec: dict | None = None,
|
|
304
|
+
publish: bool = True,
|
|
305
|
+
run_label: str | None = None,
|
|
306
|
+
repair_patch: dict | None = None,
|
|
307
|
+
) -> dict:
|
|
308
|
+
return solution.solution_build_analytics_portal(
|
|
309
|
+
profile=profile,
|
|
310
|
+
mode=mode,
|
|
311
|
+
build_id=build_id,
|
|
312
|
+
analytics_portal_spec=analytics_portal_spec or {},
|
|
313
|
+
publish=publish,
|
|
314
|
+
run_label=run_label,
|
|
315
|
+
repair_patch=repair_patch or {},
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
@server.tool()
|
|
319
|
+
def solution_build_navigation(
|
|
320
|
+
profile: str = DEFAULT_PROFILE,
|
|
321
|
+
mode: str = "plan",
|
|
322
|
+
build_id: str = "",
|
|
323
|
+
navigation_spec: dict | None = None,
|
|
324
|
+
publish: bool = True,
|
|
325
|
+
run_label: str | None = None,
|
|
326
|
+
repair_patch: dict | None = None,
|
|
327
|
+
) -> dict:
|
|
328
|
+
return solution.solution_build_navigation(
|
|
329
|
+
profile=profile,
|
|
330
|
+
mode=mode,
|
|
331
|
+
build_id=build_id,
|
|
332
|
+
navigation_spec=navigation_spec or {},
|
|
333
|
+
publish=publish,
|
|
334
|
+
run_label=run_label,
|
|
335
|
+
repair_patch=repair_patch or {},
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
@server.tool()
|
|
339
|
+
def solution_build_status(build_id: str = "") -> dict:
|
|
340
|
+
return solution.solution_build_status(build_id=build_id)
|
|
341
|
+
return server
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
mcp = build_builder_server()
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def main() -> None:
|
|
348
|
+
mcp.run()
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
if __name__ == "__main__":
|
|
352
|
+
main()
|