htmlgen-mcp 0.3.6__tar.gz → 0.3.7__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.
Potentially problematic release.
This version of htmlgen-mcp might be problematic. Click here for more details.
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/PKG-INFO +1 -1
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/pyproject.toml +1 -1
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/web_agent_server.py +106 -29
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp.egg-info/PKG-INFO +1 -1
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/README.md +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/setup.cfg +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/__init__.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/__init__.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/ai_content_generator.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/quick_generator.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/smart_web_agent.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/__init__.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/bootstrap.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/browser.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/colors.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/css.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/edgeone_deploy.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/html_templates.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/html_templates_improved.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/images.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/images_fixed.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/js.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/navigation.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/project.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/simple_builder.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/simple_css.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/simple_js.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/simple_templates.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/validation.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/config.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/context_aware_executor.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/improved_progress.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/nas_log_manager.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/nas_storage.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/progress_tools.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/progress_tracker.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/prompt_enhancer.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/sse_optimizations.py +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp.egg-info/SOURCES.txt +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp.egg-info/dependency_links.txt +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp.egg-info/entry_points.txt +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp.egg-info/requires.txt +0 -0
- {htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "htmlgen-mcp"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.7"
|
|
8
8
|
description = "AI-powered HTML website generator with auto-upload functionality via Model Context Protocol"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -38,9 +38,14 @@ from datetime import datetime
|
|
|
38
38
|
|
|
39
39
|
# 使用 NAS 作为默认存储路径
|
|
40
40
|
NAS_PATH = os.environ.get("NAS_STORAGE_PATH", "/app/mcp-servers/mcp-servers/html_agent")
|
|
41
|
+
# 项目根目录:优先使用 WEB_AGENT_PROJECT_ROOT 环境变量,否则使用 NAS_PATH/projects
|
|
41
42
|
DEFAULT_PROJECT_ROOT = os.path.abspath(
|
|
42
43
|
os.environ.get("WEB_AGENT_PROJECT_ROOT", f"{NAS_PATH}/projects")
|
|
43
44
|
)
|
|
45
|
+
# 是否自动生成项目子目录(可通过环境变量控制)
|
|
46
|
+
AUTO_CREATE_PROJECT_DIR = os.environ.get("AUTO_CREATE_PROJECT_DIR", "true").lower() == "true"
|
|
47
|
+
# 默认的文件上传URL(固定值)
|
|
48
|
+
DEFAULT_UPLOAD_URL = "https://www.mcpcn.cc/api/fileUploadAndDownload/uploadMcpFile"
|
|
44
49
|
DEFAULT_MODEL = os.environ.get("WEB_AGENT_MODEL", "qwen3-coder-plus-2025-09-23")
|
|
45
50
|
DEFAULT_BASE_URL = os.environ.get(
|
|
46
51
|
"OPENAI_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
@@ -173,9 +178,47 @@ def _resolve_cached_context(context_id: Optional[str]) -> Optional[Dict[str, Any
|
|
|
173
178
|
return None
|
|
174
179
|
|
|
175
180
|
|
|
176
|
-
def _resolve_project_directory(project_root: Optional[str]) -> str:
|
|
177
|
-
|
|
178
|
-
|
|
181
|
+
def _resolve_project_directory(project_root: Optional[str], project_name: Optional[str] = None) -> str:
|
|
182
|
+
"""
|
|
183
|
+
解析项目目录路径
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
project_root: 项目根目录或完整路径
|
|
187
|
+
project_name: 项目名称(可选)
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
完整的项目目录路径
|
|
191
|
+
"""
|
|
192
|
+
if project_root:
|
|
193
|
+
# 如果提供了 project_root
|
|
194
|
+
if os.path.isabs(project_root):
|
|
195
|
+
# 绝对路径:直接使用
|
|
196
|
+
abs_path = project_root
|
|
197
|
+
else:
|
|
198
|
+
# 相对路径:相对于默认根目录
|
|
199
|
+
# 如果 project_root 看起来像项目名(不含/),则作为子目录
|
|
200
|
+
if '/' not in project_root and '\\' not in project_root:
|
|
201
|
+
abs_path = os.path.join(DEFAULT_PROJECT_ROOT, project_root)
|
|
202
|
+
else:
|
|
203
|
+
# 包含路径分隔符,作为相对路径处理
|
|
204
|
+
abs_path = os.path.abspath(os.path.join(DEFAULT_PROJECT_ROOT, project_root))
|
|
205
|
+
else:
|
|
206
|
+
# 没有提供 project_root,使用默认根目录
|
|
207
|
+
base = DEFAULT_PROJECT_ROOT
|
|
208
|
+
|
|
209
|
+
# 如果提供了 project_name 且启用了自动创建子目录
|
|
210
|
+
if project_name and AUTO_CREATE_PROJECT_DIR:
|
|
211
|
+
# 清理项目名称,去除特殊字符
|
|
212
|
+
safe_name = "".join(c for c in project_name if c.isalnum() or c in (' ', '-', '_', '.'))
|
|
213
|
+
safe_name = safe_name.strip().replace(' ', '_')
|
|
214
|
+
if safe_name:
|
|
215
|
+
abs_path = os.path.join(base, safe_name)
|
|
216
|
+
else:
|
|
217
|
+
abs_path = base
|
|
218
|
+
else:
|
|
219
|
+
abs_path = base
|
|
220
|
+
|
|
221
|
+
# 创建目录
|
|
179
222
|
os.makedirs(abs_path, exist_ok=True)
|
|
180
223
|
return abs_path
|
|
181
224
|
|
|
@@ -403,8 +446,7 @@ def _execute_plan(
|
|
|
403
446
|
@mcp.tool()
|
|
404
447
|
async def execute_plan(
|
|
405
448
|
plan_id: str,
|
|
406
|
-
|
|
407
|
-
project_root: str,
|
|
449
|
+
project_root: Optional[str] = None,
|
|
408
450
|
# auto_plan: bool = False, # 已禁用,没有实际作用
|
|
409
451
|
# confirm_each_step: bool = False, # 后台执行模式下用户无法交互确认
|
|
410
452
|
# show_code: bool = False, # 后台执行时用户看不到输出
|
|
@@ -412,7 +454,7 @@ async def execute_plan(
|
|
|
412
454
|
save_output: bool = False,
|
|
413
455
|
progress_log: Optional[str] = None,
|
|
414
456
|
auto_upload: bool = False,
|
|
415
|
-
upload_url: str =
|
|
457
|
+
upload_url: Optional[str] = None,
|
|
416
458
|
) -> Dict[str, Any]:
|
|
417
459
|
"""执行网页构建计划,始终以后台模式运行。
|
|
418
460
|
|
|
@@ -442,9 +484,9 @@ async def execute_plan(
|
|
|
442
484
|
False: 仅构建,不上传
|
|
443
485
|
默认为 False
|
|
444
486
|
|
|
445
|
-
- upload_url: 文件上传API
|
|
487
|
+
- upload_url: 文件上传API地址(可选)
|
|
446
488
|
默认为 "https://www.mcpcn.cc/api/fileUploadAndDownload/uploadMcpFile"
|
|
447
|
-
只在 auto_upload=True
|
|
489
|
+
只在 auto_upload=True 时生效,一般不需要修改
|
|
448
490
|
|
|
449
491
|
执行流程:
|
|
450
492
|
- 任务始终在后台异步执行,立即返回 job_id 和 progress_log 路径
|
|
@@ -454,7 +496,40 @@ async def execute_plan(
|
|
|
454
496
|
- 🎯 新增:auto_upload=True时,构建完成(100%)后自动上传并返回访问URL
|
|
455
497
|
"""
|
|
456
498
|
try:
|
|
457
|
-
|
|
499
|
+
# 如果没有提供project_root,尝试从缓存中获取
|
|
500
|
+
if not project_root:
|
|
501
|
+
cached_by_id = _PLAN_CACHE_BY_ID.get(plan_id)
|
|
502
|
+
if cached_by_id and cached_by_id.get("project_directory"):
|
|
503
|
+
project_root = cached_by_id["project_directory"]
|
|
504
|
+
else:
|
|
505
|
+
# 尝试从文件中读取
|
|
506
|
+
possible_paths = [
|
|
507
|
+
PLAN_CACHE_DIR / f"{plan_id}.json",
|
|
508
|
+
PLAN_CACHE_DIR / f"simple_site_plan_{plan_id}.json",
|
|
509
|
+
]
|
|
510
|
+
for path in possible_paths:
|
|
511
|
+
if path.exists():
|
|
512
|
+
try:
|
|
513
|
+
plan_data = json.loads(path.read_text(encoding="utf-8"))
|
|
514
|
+
project_root = plan_data.get("project_directory")
|
|
515
|
+
if project_root:
|
|
516
|
+
break
|
|
517
|
+
except Exception:
|
|
518
|
+
pass
|
|
519
|
+
|
|
520
|
+
if not project_root:
|
|
521
|
+
# 使用默认根目录,但不添加子目录
|
|
522
|
+
project_root = None
|
|
523
|
+
|
|
524
|
+
# 从计划中获取项目名称(如果有)
|
|
525
|
+
project_name = None
|
|
526
|
+
if plan_id:
|
|
527
|
+
cached_plan = _PLAN_CACHE_BY_ID.get(plan_id)
|
|
528
|
+
if cached_plan:
|
|
529
|
+
# 尝试从缓存中获取项目名称
|
|
530
|
+
project_name = cached_plan.get("site_title") or cached_plan.get("project_name")
|
|
531
|
+
|
|
532
|
+
project_dir = _resolve_project_directory(project_root, project_name)
|
|
458
533
|
|
|
459
534
|
# 移除 auto_plan 检查,因为参数已被移除
|
|
460
535
|
|
|
@@ -563,6 +638,9 @@ async def execute_plan(
|
|
|
563
638
|
|
|
564
639
|
_persist_job_state(job_id)
|
|
565
640
|
|
|
641
|
+
# 使用默认URL如果没有提供
|
|
642
|
+
effective_upload_url = upload_url or DEFAULT_UPLOAD_URL
|
|
643
|
+
|
|
566
644
|
asyncio.create_task(
|
|
567
645
|
_run_execution_job(
|
|
568
646
|
job_id,
|
|
@@ -570,7 +648,7 @@ async def execute_plan(
|
|
|
570
648
|
plan_dict,
|
|
571
649
|
progress_log_path=progress_log_path,
|
|
572
650
|
auto_upload=auto_upload,
|
|
573
|
-
upload_url=
|
|
651
|
+
upload_url=effective_upload_url,
|
|
574
652
|
)
|
|
575
653
|
)
|
|
576
654
|
|
|
@@ -609,7 +687,7 @@ async def _run_execution_job(
|
|
|
609
687
|
*,
|
|
610
688
|
progress_log_path: Optional[str],
|
|
611
689
|
auto_upload: bool = False,
|
|
612
|
-
upload_url: str =
|
|
690
|
+
upload_url: str = None,
|
|
613
691
|
) -> None:
|
|
614
692
|
job_info = _JOB_REGISTRY.get(job_id)
|
|
615
693
|
if not job_info:
|
|
@@ -634,9 +712,12 @@ async def _run_execution_job(
|
|
|
634
712
|
job_info["upload_status"] = "uploading"
|
|
635
713
|
_persist_job_state(job_id)
|
|
636
714
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
715
|
+
# 只在不是默认值时传递upload_url
|
|
716
|
+
upload_params = {"folder_path": job_info["project_directory"]}
|
|
717
|
+
if upload_url and upload_url != DEFAULT_UPLOAD_URL:
|
|
718
|
+
upload_params["upload_url"] = upload_url
|
|
719
|
+
|
|
720
|
+
upload_result = await upload_project_to_mcp_server(**upload_params)
|
|
640
721
|
|
|
641
722
|
# 记录上传结果
|
|
642
723
|
job_info["upload_result"] = upload_result
|
|
@@ -735,18 +816,9 @@ async def create_simple_site(
|
|
|
735
816
|
# 使用指定模型或默认模型
|
|
736
817
|
used_model = model or DEFAULT_MODEL
|
|
737
818
|
|
|
738
|
-
#
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
project_directory = os.path.join(DEFAULT_PROJECT_ROOT, project_root)
|
|
742
|
-
else:
|
|
743
|
-
project_directory = project_root
|
|
744
|
-
else:
|
|
745
|
-
# 使用站点标题作为目录名
|
|
746
|
-
safe_title = "".join(
|
|
747
|
-
c if c.isalnum() or c in "._-" else "_" for c in site_title
|
|
748
|
-
)
|
|
749
|
-
project_directory = os.path.join(DEFAULT_PROJECT_ROOT, safe_title)
|
|
819
|
+
# 使用新的路径解析逻辑
|
|
820
|
+
# 如果没有提供 project_root,使用 site_title 作为项目名
|
|
821
|
+
project_directory = _resolve_project_directory(project_root, site_title)
|
|
750
822
|
|
|
751
823
|
# 处理上下文
|
|
752
824
|
context_data = ""
|
|
@@ -1075,13 +1147,15 @@ async def get_progress(
|
|
|
1075
1147
|
@mcp.tool()
|
|
1076
1148
|
async def upload_project_to_mcp_server(
|
|
1077
1149
|
folder_path: str,
|
|
1078
|
-
upload_url: str =
|
|
1150
|
+
upload_url: Optional[str] = None,
|
|
1079
1151
|
) -> Dict[str, Any]:
|
|
1080
1152
|
"""将项目文件夹打包成ZIP并上传到MCP服务器。
|
|
1081
1153
|
|
|
1082
1154
|
参数说明:
|
|
1083
1155
|
- folder_path: 项目文件夹的绝对路径
|
|
1084
|
-
- upload_url: 上传API
|
|
1156
|
+
- upload_url: 上传API地址(可选)
|
|
1157
|
+
默认为 "https://www.mcpcn.cc/api/fileUploadAndDownload/uploadMcpFile"
|
|
1158
|
+
一般不需要修改
|
|
1085
1159
|
|
|
1086
1160
|
返回值:
|
|
1087
1161
|
- status: 上传状态 ("success" 或 "error")
|
|
@@ -1090,6 +1164,9 @@ async def upload_project_to_mcp_server(
|
|
|
1090
1164
|
- message: 状态信息
|
|
1091
1165
|
"""
|
|
1092
1166
|
try:
|
|
1167
|
+
# 使用默认URL如果没有提供
|
|
1168
|
+
effective_upload_url = upload_url or DEFAULT_UPLOAD_URL
|
|
1169
|
+
|
|
1093
1170
|
# 验证文件夹路径
|
|
1094
1171
|
if not os.path.exists(folder_path):
|
|
1095
1172
|
return {"status": "error", "message": f"项目文件夹不存在: {folder_path}"}
|
|
@@ -1129,7 +1206,7 @@ async def upload_project_to_mcp_server(
|
|
|
1129
1206
|
"file", f, filename=zip_filename, content_type="application/zip"
|
|
1130
1207
|
)
|
|
1131
1208
|
|
|
1132
|
-
async with session.post(
|
|
1209
|
+
async with session.post(effective_upload_url, data=data) as response:
|
|
1133
1210
|
response_text = await response.text()
|
|
1134
1211
|
|
|
1135
1212
|
if response.status != 200:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/html_templates_improved.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{htmlgen_mcp-0.3.6 → htmlgen_mcp-0.3.7}/src/htmlgen_mcp/agents/web_tools/simple_templates.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|