@josephyan/qingflow-cli 0.2.0-beta.71 → 0.2.0-beta.73
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 +2 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/qingflow_mcp/backend_client.py +1 -0
- package/src/qingflow_mcp/builder_facade/models.py +22 -11
- package/src/qingflow_mcp/builder_facade/service.py +183 -121
- package/src/qingflow_mcp/cli/commands/__init__.py +4 -1
- package/src/qingflow_mcp/cli/commands/builder.py +81 -64
- package/src/qingflow_mcp/cli/commands/chart.py +18 -0
- package/src/qingflow_mcp/cli/commands/portal.py +25 -0
- package/src/qingflow_mcp/cli/commands/view.py +18 -0
- package/src/qingflow_mcp/cli/context.py +9 -0
- package/src/qingflow_mcp/response_trim.py +219 -178
- package/src/qingflow_mcp/server_app_builder.py +18 -42
- package/src/qingflow_mcp/server_app_user.py +21 -1
- package/src/qingflow_mcp/tools/ai_builder_tools.py +244 -124
- package/src/qingflow_mcp/tools/app_tools.py +0 -4
- package/src/qingflow_mcp/tools/resource_read_tools.py +399 -0
|
@@ -35,7 +35,7 @@ def build_builder_server() -> FastMCP:
|
|
|
35
35
|
"Follow the resource path resolve -> summary read -> apply -> attach -> publish_verify. "
|
|
36
36
|
"Use builder_tool_contract when you need a machine-readable contract, aliases, allowed enums, or a minimal valid example for a public builder tool. "
|
|
37
37
|
"If creating a new package may be appropriate, ask the user to confirm package creation before calling package_create; otherwise use package_resolve/package_list and app_resolve to locate resources, "
|
|
38
|
-
"
|
|
38
|
+
"app_get/app_get_fields/app_get_layout/app_get_views/app_get_flow/app_get_charts/portal_list/portal_get/view_get/chart_get for configuration reads, "
|
|
39
39
|
"member_search/role_search/role_create when workflow assignees must come from the directory or role catalog, preferring roles over explicit members unless the user explicitly names members, "
|
|
40
40
|
"then app_schema_apply/app_layout_apply/app_flow_apply/app_views_apply/app_charts_apply/portal_apply to execute normalized patches; these apply tools perform planning, normalization, and dependency checks internally where applicable. Schema/layout/views noop requests skip publish, charts are immediate-live without publish and resolve targets by chart_id first then exact unique chart name, portal updates are replace-only and publish=false only guarantees draft/base-info updates, and flow should use publish=false whenever you only want draft/precheck behavior. "
|
|
41
41
|
"Use package_attach_app to attach apps to packages, and app_publish_verify for explicit final publish verification. "
|
|
@@ -153,7 +153,7 @@ def build_builder_server() -> FastMCP:
|
|
|
153
153
|
) -> dict:
|
|
154
154
|
try:
|
|
155
155
|
return trim_public_response(
|
|
156
|
-
"feedback_submit",
|
|
156
|
+
"builder:feedback_submit",
|
|
157
157
|
feedback.feedback_submit(
|
|
158
158
|
category=category,
|
|
159
159
|
title=title,
|
|
@@ -311,28 +311,28 @@ def build_builder_server() -> FastMCP:
|
|
|
311
311
|
return ai_builder.app_custom_button_delete(profile=profile, app_key=app_key, button_id=button_id)
|
|
312
312
|
|
|
313
313
|
@server.tool()
|
|
314
|
-
def
|
|
315
|
-
return ai_builder.
|
|
314
|
+
def app_get(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
315
|
+
return ai_builder.app_get(profile=profile, app_key=app_key)
|
|
316
316
|
|
|
317
317
|
@server.tool()
|
|
318
|
-
def
|
|
319
|
-
return ai_builder.
|
|
318
|
+
def app_get_fields(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
319
|
+
return ai_builder.app_get_fields(profile=profile, app_key=app_key)
|
|
320
320
|
|
|
321
321
|
@server.tool()
|
|
322
|
-
def
|
|
323
|
-
return ai_builder.
|
|
322
|
+
def app_get_layout(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
323
|
+
return ai_builder.app_get_layout(profile=profile, app_key=app_key)
|
|
324
324
|
|
|
325
325
|
@server.tool()
|
|
326
|
-
def
|
|
327
|
-
return ai_builder.
|
|
326
|
+
def app_get_views(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
327
|
+
return ai_builder.app_get_views(profile=profile, app_key=app_key)
|
|
328
328
|
|
|
329
329
|
@server.tool()
|
|
330
|
-
def
|
|
331
|
-
return ai_builder.
|
|
330
|
+
def app_get_flow(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
331
|
+
return ai_builder.app_get_flow(profile=profile, app_key=app_key)
|
|
332
332
|
|
|
333
333
|
@server.tool()
|
|
334
|
-
def
|
|
335
|
-
return ai_builder.
|
|
334
|
+
def app_get_charts(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
335
|
+
return ai_builder.app_get_charts(profile=profile, app_key=app_key)
|
|
336
336
|
|
|
337
337
|
@server.tool()
|
|
338
338
|
def portal_list(profile: str = DEFAULT_PROFILE) -> dict:
|
|
@@ -347,36 +347,12 @@ def build_builder_server() -> FastMCP:
|
|
|
347
347
|
return ai_builder.portal_get(profile=profile, dash_key=dash_key, being_draft=being_draft)
|
|
348
348
|
|
|
349
349
|
@server.tool()
|
|
350
|
-
def
|
|
351
|
-
profile
|
|
352
|
-
dash_key: str = "",
|
|
353
|
-
being_draft: bool = True,
|
|
354
|
-
) -> dict:
|
|
355
|
-
return ai_builder.portal_read_summary(profile=profile, dash_key=dash_key, being_draft=being_draft)
|
|
356
|
-
|
|
357
|
-
@server.tool()
|
|
358
|
-
def view_get(profile: str = DEFAULT_PROFILE, viewgraph_key: str = "") -> dict:
|
|
359
|
-
return ai_builder.view_get(profile=profile, viewgraph_key=viewgraph_key)
|
|
350
|
+
def view_get(profile: str = DEFAULT_PROFILE, view_key: str = "") -> dict:
|
|
351
|
+
return ai_builder.view_get(profile=profile, view_key=view_key)
|
|
360
352
|
|
|
361
353
|
@server.tool()
|
|
362
|
-
def chart_get(
|
|
363
|
-
profile
|
|
364
|
-
chart_id: str = "",
|
|
365
|
-
data_payload: dict | None = None,
|
|
366
|
-
page_num: int | None = None,
|
|
367
|
-
page_size: int | None = None,
|
|
368
|
-
page_num_y: int | None = None,
|
|
369
|
-
page_size_y: int | None = None,
|
|
370
|
-
) -> dict:
|
|
371
|
-
return ai_builder.chart_get(
|
|
372
|
-
profile=profile,
|
|
373
|
-
chart_id=chart_id,
|
|
374
|
-
data_payload=data_payload or {},
|
|
375
|
-
page_num=page_num,
|
|
376
|
-
page_size=page_size,
|
|
377
|
-
page_num_y=page_num_y,
|
|
378
|
-
page_size_y=page_size_y,
|
|
379
|
-
)
|
|
354
|
+
def chart_get(profile: str = DEFAULT_PROFILE, chart_id: str = "") -> dict:
|
|
355
|
+
return ai_builder.chart_get(profile=profile, chart_id=chart_id)
|
|
380
356
|
|
|
381
357
|
@server.tool()
|
|
382
358
|
def app_schema_apply(
|
|
@@ -16,6 +16,7 @@ from .tools.directory_tools import DirectoryTools
|
|
|
16
16
|
from .tools.feedback_tools import FeedbackTools
|
|
17
17
|
from .tools.file_tools import FileTools
|
|
18
18
|
from .tools.import_tools import ImportTools
|
|
19
|
+
from .tools.resource_read_tools import ResourceReadTools
|
|
19
20
|
from .tools.task_context_tools import TaskContextTools
|
|
20
21
|
from .tools.workspace_tools import WorkspaceTools
|
|
21
22
|
|
|
@@ -95,6 +96,8 @@ Analysis answers must include concrete numbers. When applicable, include percent
|
|
|
95
96
|
`record_update_schema_get -> record_update`
|
|
96
97
|
`record_list / record_get -> record_delete`
|
|
97
98
|
`record_code_block_schema_get -> record_code_block_run`
|
|
99
|
+
`portal_list -> portal_get -> chart_get / view_get`
|
|
100
|
+
`portal_get -> view_get -> record_list`
|
|
98
101
|
|
|
99
102
|
- Use `columns` as `[{{field_id}}]`
|
|
100
103
|
- Use `where` items as `{{field_id, op, value}}`
|
|
@@ -177,6 +180,7 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
|
|
|
177
180
|
workspace = wrap_trimmed_methods(WorkspaceTools(sessions, backend), USER_SERVER_METHOD_MAP)
|
|
178
181
|
file_tools = wrap_trimmed_methods(FileTools(sessions, backend), USER_SERVER_METHOD_MAP)
|
|
179
182
|
imports = wrap_trimmed_methods(ImportTools(sessions, backend), USER_SERVER_METHOD_MAP)
|
|
183
|
+
resources = wrap_trimmed_methods(ResourceReadTools(sessions, backend), USER_SERVER_METHOD_MAP)
|
|
180
184
|
feedback = FeedbackTools(backend, mcp_side="App User MCP")
|
|
181
185
|
code_block_tools = wrap_trimmed_methods(CodeBlockTools(sessions, backend), USER_SERVER_METHOD_MAP)
|
|
182
186
|
task_context_tools = wrap_trimmed_methods(TaskContextTools(sessions, backend), USER_SERVER_METHOD_MAP)
|
|
@@ -256,6 +260,22 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
|
|
|
256
260
|
def app_get(profile: str = DEFAULT_PROFILE, app_key: str = "") -> dict:
|
|
257
261
|
return apps.app_get(profile=profile, app_key=app_key)
|
|
258
262
|
|
|
263
|
+
@server.tool()
|
|
264
|
+
def portal_list(profile: str = DEFAULT_PROFILE) -> dict:
|
|
265
|
+
return resources.portal_list(profile=profile)
|
|
266
|
+
|
|
267
|
+
@server.tool()
|
|
268
|
+
def portal_get(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> dict:
|
|
269
|
+
return resources.portal_get(profile=profile, dash_key=dash_key)
|
|
270
|
+
|
|
271
|
+
@server.tool()
|
|
272
|
+
def view_get(profile: str = DEFAULT_PROFILE, view_id: str = "") -> dict:
|
|
273
|
+
return resources.view_get(profile=profile, view_id=view_id)
|
|
274
|
+
|
|
275
|
+
@server.tool()
|
|
276
|
+
def chart_get(profile: str = DEFAULT_PROFILE, chart_id: str = "") -> dict:
|
|
277
|
+
return resources.chart_get(profile=profile, chart_id=chart_id)
|
|
278
|
+
|
|
259
279
|
@server.tool()
|
|
260
280
|
def file_get_upload_info(
|
|
261
281
|
profile: str = DEFAULT_PROFILE,
|
|
@@ -320,7 +340,7 @@ If the current MCP capability is unsupported, the workflow is awkward, or the us
|
|
|
320
340
|
) -> dict:
|
|
321
341
|
try:
|
|
322
342
|
return trim_public_response(
|
|
323
|
-
"feedback_submit",
|
|
343
|
+
"user:feedback_submit",
|
|
324
344
|
feedback.feedback_submit(
|
|
325
345
|
category=category,
|
|
326
346
|
title=title,
|