scitex 2.11.0__py3-none-any.whl → 2.13.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.
- scitex/__main__.py +24 -5
- scitex/__version__.py +1 -1
- scitex/_optional_deps.py +33 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
- scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
- scitex/ai/plt/_plot_feature_importance.py +1 -1
- scitex/ai/plt/_plot_learning_curve.py +1 -1
- scitex/ai/plt/_plot_optuna_study.py +1 -1
- scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
- scitex/ai/plt/_plot_roc_curve.py +1 -1
- scitex/ai/plt/_stx_conf_mat.py +1 -1
- scitex/ai/training/_LearningCurveLogger.py +1 -1
- scitex/audio/mcp_server.py +38 -8
- scitex/browser/automation/CookieHandler.py +1 -1
- scitex/browser/core/BrowserMixin.py +1 -1
- scitex/browser/core/ChromeProfileManager.py +1 -1
- scitex/browser/debugging/_browser_logger.py +1 -1
- scitex/browser/debugging/_highlight_element.py +1 -1
- scitex/browser/debugging/_show_grid.py +1 -1
- scitex/browser/interaction/click_center.py +1 -1
- scitex/browser/interaction/click_with_fallbacks.py +1 -1
- scitex/browser/interaction/close_popups.py +1 -1
- scitex/browser/interaction/fill_with_fallbacks.py +1 -1
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
- scitex/browser/stealth/HumanBehavior.py +1 -1
- scitex/browser/stealth/StealthManager.py +1 -1
- scitex/canvas/_mcp_handlers.py +372 -0
- scitex/canvas/_mcp_tool_schemas.py +219 -0
- scitex/canvas/mcp_server.py +151 -0
- scitex/capture/mcp_server.py +41 -12
- scitex/cli/audio.py +233 -0
- scitex/cli/capture.py +307 -0
- scitex/cli/main.py +27 -4
- scitex/cli/repro.py +233 -0
- scitex/cli/resource.py +240 -0
- scitex/cli/stats.py +325 -0
- scitex/cli/template.py +236 -0
- scitex/cli/tex.py +286 -0
- scitex/cli/web.py +11 -12
- scitex/dev/__init__.py +3 -0
- scitex/dev/_pyproject.py +405 -0
- scitex/dev/plt/__init__.py +2 -2
- scitex/dev/plt/mpl/get_dir_ax.py +1 -1
- scitex/dev/plt/mpl/get_signatures.py +1 -1
- scitex/dev/plt/mpl/get_signatures_details.py +1 -1
- scitex/diagram/_mcp_handlers.py +400 -0
- scitex/diagram/_mcp_tool_schemas.py +157 -0
- scitex/diagram/mcp_server.py +151 -0
- scitex/dsp/_demo_sig.py +51 -5
- scitex/dsp/_mne.py +13 -2
- scitex/dsp/_modulation_index.py +15 -3
- scitex/dsp/_pac.py +23 -5
- scitex/dsp/_psd.py +16 -4
- scitex/dsp/_resample.py +24 -4
- scitex/dsp/_transform.py +16 -3
- scitex/dsp/add_noise.py +15 -1
- scitex/dsp/norm.py +17 -2
- scitex/dsp/reference.py +17 -1
- scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
- scitex/dsp/utils/_zero_pad.py +18 -4
- scitex/dt/_normalize_timestamp.py +1 -1
- scitex/git/_session.py +1 -1
- scitex/io/_load_modules/_con.py +12 -1
- scitex/io/_load_modules/_eeg.py +12 -1
- scitex/io/_load_modules/_optuna.py +21 -63
- scitex/io/_load_modules/_torch.py +11 -3
- scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
- scitex/io/_save_modules/_torch.py +11 -3
- scitex/mcp_server.py +159 -0
- scitex/plt/_mcp_handlers.py +361 -0
- scitex/plt/_mcp_tool_schemas.py +169 -0
- scitex/plt/mcp_server.py +205 -0
- scitex/repro/README_RandomStateManager.md +3 -3
- scitex/repro/_RandomStateManager.py +14 -14
- scitex/repro/_gen_ID.py +1 -1
- scitex/repro/_gen_timestamp.py +1 -1
- scitex/repro/_hash_array.py +4 -4
- scitex/scholar/__main__.py +24 -2
- scitex/scholar/_mcp_handlers.py +685 -0
- scitex/scholar/_mcp_tool_schemas.py +339 -0
- scitex/scholar/docs/template.py +1 -1
- scitex/scholar/examples/07_storage_integration.py +1 -1
- scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
- scitex/scholar/impact_factor/jcr/build_database.py +1 -1
- scitex/scholar/mcp_server.py +315 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
- scitex/scholar/storage/PaperIO.py +1 -1
- scitex/session/README.md +4 -4
- scitex/session/__init__.py +1 -1
- scitex/session/_decorator.py +9 -9
- scitex/session/_lifecycle.py +5 -5
- scitex/session/template.py +1 -1
- scitex/stats/__main__.py +281 -0
- scitex/stats/_mcp_handlers.py +1191 -0
- scitex/stats/_mcp_tool_schemas.py +384 -0
- scitex/stats/correct/_correct_bonferroni.py +1 -1
- scitex/stats/correct/_correct_fdr.py +1 -1
- scitex/stats/correct/_correct_fdr_.py +1 -1
- scitex/stats/correct/_correct_holm.py +1 -1
- scitex/stats/correct/_correct_sidak.py +1 -1
- scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
- scitex/stats/effect_sizes/_cohens_d.py +1 -1
- scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
- scitex/stats/effect_sizes/_eta_squared.py +1 -1
- scitex/stats/effect_sizes/_prob_superiority.py +1 -1
- scitex/stats/mcp_server.py +405 -0
- scitex/stats/posthoc/_dunnett.py +1 -1
- scitex/stats/posthoc/_games_howell.py +1 -1
- scitex/stats/posthoc/_tukey_hsd.py +1 -1
- scitex/stats/power/_power.py +1 -1
- scitex/stats/utils/_effect_size.py +1 -1
- scitex/stats/utils/_formatters.py +1 -1
- scitex/stats/utils/_power.py +1 -1
- scitex/template/_mcp_handlers.py +259 -0
- scitex/template/_mcp_tool_schemas.py +112 -0
- scitex/template/mcp_server.py +186 -0
- scitex/utils/_verify_scitex_format.py +2 -2
- scitex/utils/template.py +1 -1
- scitex/web/__init__.py +12 -11
- scitex/web/_scraping.py +26 -265
- scitex/web/download_images.py +316 -0
- scitex/writer/Writer.py +1 -1
- scitex/writer/_clone_writer_project.py +1 -1
- scitex/writer/_validate_tree_structures.py +1 -1
- scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
- scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
- scitex/writer/dataclasses/core/_Document.py +1 -1
- scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
- scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
- scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
- scitex/writer/utils/.legacy_git_retry.py +7 -5
- scitex/writer/utils/_parse_latex_logs.py +1 -1
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/METADATA +431 -269
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/RECORD +147 -118
- scitex-2.13.0.dist-info/entry_points.txt +11 -0
- scitex-2.11.0.dist-info/entry_points.txt +0 -2
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
- {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-08
|
|
3
|
+
# File: src/scitex/template/_mcp_handlers.py
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MCP Handler implementations for SciTeX Template module.
|
|
8
|
+
|
|
9
|
+
Provides async handlers for project scaffolding operations:
|
|
10
|
+
- list_templates_handler: List available templates
|
|
11
|
+
- get_template_info_handler: Get template details
|
|
12
|
+
- clone_template_handler: Create project from template
|
|
13
|
+
- list_git_strategies_handler: List git strategies
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Optional
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def list_templates_handler() -> dict:
|
|
24
|
+
"""
|
|
25
|
+
List all available SciTeX project templates.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
dict
|
|
30
|
+
Success status and list of templates with basic info
|
|
31
|
+
"""
|
|
32
|
+
try:
|
|
33
|
+
from scitex.template import get_available_templates_info
|
|
34
|
+
|
|
35
|
+
templates = get_available_templates_info()
|
|
36
|
+
|
|
37
|
+
# Simplify for listing
|
|
38
|
+
template_list = [
|
|
39
|
+
{
|
|
40
|
+
"id": t["id"],
|
|
41
|
+
"name": t["name"],
|
|
42
|
+
"description": t["description"],
|
|
43
|
+
"use_case": t["use_case"],
|
|
44
|
+
}
|
|
45
|
+
for t in templates
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
"success": True,
|
|
50
|
+
"count": len(template_list),
|
|
51
|
+
"templates": template_list,
|
|
52
|
+
}
|
|
53
|
+
except Exception as e:
|
|
54
|
+
return {
|
|
55
|
+
"success": False,
|
|
56
|
+
"error": str(e),
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def get_template_info_handler(template_id: str) -> dict:
|
|
61
|
+
"""
|
|
62
|
+
Get detailed information about a specific template.
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
template_id : str
|
|
67
|
+
Template identifier (research, pip_project, singularity, paper_directory)
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
dict
|
|
72
|
+
Success status and template details
|
|
73
|
+
"""
|
|
74
|
+
try:
|
|
75
|
+
from scitex.template import get_available_templates_info
|
|
76
|
+
|
|
77
|
+
templates = get_available_templates_info()
|
|
78
|
+
|
|
79
|
+
# Find the requested template
|
|
80
|
+
template = None
|
|
81
|
+
for t in templates:
|
|
82
|
+
if t["id"] == template_id:
|
|
83
|
+
template = t
|
|
84
|
+
break
|
|
85
|
+
|
|
86
|
+
if template is None:
|
|
87
|
+
return {
|
|
88
|
+
"success": False,
|
|
89
|
+
"error": f"Template not found: {template_id}",
|
|
90
|
+
"available_templates": [t["id"] for t in templates],
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
"success": True,
|
|
95
|
+
"template": template,
|
|
96
|
+
}
|
|
97
|
+
except Exception as e:
|
|
98
|
+
return {
|
|
99
|
+
"success": False,
|
|
100
|
+
"error": str(e),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
async def clone_template_handler(
|
|
105
|
+
template_id: str,
|
|
106
|
+
project_name: str,
|
|
107
|
+
target_dir: Optional[str] = None,
|
|
108
|
+
git_strategy: str = "child",
|
|
109
|
+
branch: Optional[str] = None,
|
|
110
|
+
tag: Optional[str] = None,
|
|
111
|
+
) -> dict:
|
|
112
|
+
"""
|
|
113
|
+
Create a new project by cloning a template.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
template_id : str
|
|
118
|
+
Template to clone (research, pip_project, singularity, paper_directory)
|
|
119
|
+
project_name : str
|
|
120
|
+
Name for the new project
|
|
121
|
+
target_dir : str, optional
|
|
122
|
+
Parent directory for the project (default: current directory)
|
|
123
|
+
git_strategy : str, optional
|
|
124
|
+
Git initialization strategy (child, parent, origin, none)
|
|
125
|
+
branch : str, optional
|
|
126
|
+
Specific branch to clone
|
|
127
|
+
tag : str, optional
|
|
128
|
+
Specific tag to clone
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
dict
|
|
133
|
+
Success status and project path
|
|
134
|
+
"""
|
|
135
|
+
try:
|
|
136
|
+
# Map template_id to clone function
|
|
137
|
+
clone_functions = {
|
|
138
|
+
"research": "clone_research",
|
|
139
|
+
"pip_project": "clone_pip_project",
|
|
140
|
+
"singularity": "clone_singularity",
|
|
141
|
+
"paper_directory": "clone_writer_directory",
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if template_id not in clone_functions:
|
|
145
|
+
return {
|
|
146
|
+
"success": False,
|
|
147
|
+
"error": f"Unknown template: {template_id}",
|
|
148
|
+
"available_templates": list(clone_functions.keys()),
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# Import the specific clone function
|
|
152
|
+
import scitex.template as template_module
|
|
153
|
+
|
|
154
|
+
clone_func = getattr(template_module, clone_functions[template_id])
|
|
155
|
+
|
|
156
|
+
# Build project path
|
|
157
|
+
if target_dir:
|
|
158
|
+
project_path = str(Path(target_dir) / project_name)
|
|
159
|
+
else:
|
|
160
|
+
project_path = project_name
|
|
161
|
+
|
|
162
|
+
# Handle git_strategy='none'
|
|
163
|
+
git_strat = None if git_strategy == "none" else git_strategy
|
|
164
|
+
|
|
165
|
+
# Run clone in executor (blocking operation)
|
|
166
|
+
loop = asyncio.get_event_loop()
|
|
167
|
+
success = await loop.run_in_executor(
|
|
168
|
+
None,
|
|
169
|
+
lambda: clone_func(
|
|
170
|
+
project_dir=project_path,
|
|
171
|
+
git_strategy=git_strat,
|
|
172
|
+
branch=branch,
|
|
173
|
+
tag=tag,
|
|
174
|
+
),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if success:
|
|
178
|
+
# Resolve the actual path
|
|
179
|
+
resolved_path = Path(project_path)
|
|
180
|
+
if not resolved_path.is_absolute():
|
|
181
|
+
resolved_path = Path.cwd() / resolved_path
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
"success": True,
|
|
185
|
+
"project_path": str(resolved_path),
|
|
186
|
+
"template": template_id,
|
|
187
|
+
"git_strategy": git_strategy,
|
|
188
|
+
"message": f"Successfully created {template_id} project at {resolved_path}",
|
|
189
|
+
}
|
|
190
|
+
else:
|
|
191
|
+
return {
|
|
192
|
+
"success": False,
|
|
193
|
+
"error": f"Failed to clone template: {template_id}",
|
|
194
|
+
"project_name": project_name,
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
except Exception as e:
|
|
198
|
+
return {
|
|
199
|
+
"success": False,
|
|
200
|
+
"error": str(e),
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
async def list_git_strategies_handler() -> dict:
|
|
205
|
+
"""
|
|
206
|
+
List available git initialization strategies.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
dict
|
|
211
|
+
Success status and list of strategies with descriptions
|
|
212
|
+
"""
|
|
213
|
+
strategies = [
|
|
214
|
+
{
|
|
215
|
+
"id": "child",
|
|
216
|
+
"name": "Child Repository",
|
|
217
|
+
"description": "Create an isolated git repository in the project directory",
|
|
218
|
+
"recommended": True,
|
|
219
|
+
"preserves_template_history": False,
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"id": "parent",
|
|
223
|
+
"name": "Parent Repository",
|
|
224
|
+
"description": "Use the parent directory's git repository (project becomes part of parent repo)",
|
|
225
|
+
"recommended": False,
|
|
226
|
+
"preserves_template_history": False,
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"id": "origin",
|
|
230
|
+
"name": "Preserve Origin",
|
|
231
|
+
"description": "Keep the template's original git history (maintains connection to template repo)",
|
|
232
|
+
"recommended": False,
|
|
233
|
+
"preserves_template_history": True,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"id": "none",
|
|
237
|
+
"name": "No Git",
|
|
238
|
+
"description": "Skip git initialization entirely",
|
|
239
|
+
"recommended": False,
|
|
240
|
+
"preserves_template_history": False,
|
|
241
|
+
},
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
"success": True,
|
|
246
|
+
"count": len(strategies),
|
|
247
|
+
"strategies": strategies,
|
|
248
|
+
"default": "child",
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
__all__ = [
|
|
253
|
+
"list_templates_handler",
|
|
254
|
+
"get_template_info_handler",
|
|
255
|
+
"clone_template_handler",
|
|
256
|
+
"list_git_strategies_handler",
|
|
257
|
+
]
|
|
258
|
+
|
|
259
|
+
# EOF
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-08
|
|
3
|
+
# File: src/scitex/template/_mcp_tool_schemas.py
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MCP Tool schemas for SciTeX Template module.
|
|
8
|
+
|
|
9
|
+
Defines available tools for project scaffolding:
|
|
10
|
+
- list_templates: List available project templates
|
|
11
|
+
- get_template_info: Get detailed information about a template
|
|
12
|
+
- clone_template: Create a new project from a template
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import mcp.types as types
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_tool_schemas() -> list[types.Tool]:
|
|
21
|
+
"""Return list of available MCP tools for template operations."""
|
|
22
|
+
return [
|
|
23
|
+
# List available templates
|
|
24
|
+
types.Tool(
|
|
25
|
+
name="list_templates",
|
|
26
|
+
description="List all available SciTeX project templates with their descriptions",
|
|
27
|
+
inputSchema={
|
|
28
|
+
"type": "object",
|
|
29
|
+
"properties": {},
|
|
30
|
+
"required": [],
|
|
31
|
+
},
|
|
32
|
+
),
|
|
33
|
+
# Get template information
|
|
34
|
+
types.Tool(
|
|
35
|
+
name="get_template_info",
|
|
36
|
+
description="Get detailed information about a specific project template",
|
|
37
|
+
inputSchema={
|
|
38
|
+
"type": "object",
|
|
39
|
+
"properties": {
|
|
40
|
+
"template_id": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Template identifier (research, pip_project, singularity, paper_directory)",
|
|
43
|
+
"enum": [
|
|
44
|
+
"research",
|
|
45
|
+
"pip_project",
|
|
46
|
+
"singularity",
|
|
47
|
+
"paper_directory",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
"required": ["template_id"],
|
|
52
|
+
},
|
|
53
|
+
),
|
|
54
|
+
# Clone template
|
|
55
|
+
types.Tool(
|
|
56
|
+
name="clone_template",
|
|
57
|
+
description="Create a new project by cloning a template. Supports research projects, Python packages, Singularity containers, and paper directories.",
|
|
58
|
+
inputSchema={
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"template_id": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "Template to clone (research, pip_project, singularity, paper_directory)",
|
|
64
|
+
"enum": [
|
|
65
|
+
"research",
|
|
66
|
+
"pip_project",
|
|
67
|
+
"singularity",
|
|
68
|
+
"paper_directory",
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
"project_name": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "Name for the new project (will be used as directory name)",
|
|
74
|
+
},
|
|
75
|
+
"target_dir": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Parent directory where project will be created (default: current directory)",
|
|
78
|
+
},
|
|
79
|
+
"git_strategy": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "Git initialization strategy",
|
|
82
|
+
"enum": ["child", "parent", "origin", "none"],
|
|
83
|
+
"default": "child",
|
|
84
|
+
},
|
|
85
|
+
"branch": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"description": "Specific branch to clone (optional)",
|
|
88
|
+
},
|
|
89
|
+
"tag": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "Specific tag/release to clone (optional)",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
"required": ["template_id", "project_name"],
|
|
95
|
+
},
|
|
96
|
+
),
|
|
97
|
+
# Get git strategies
|
|
98
|
+
types.Tool(
|
|
99
|
+
name="list_git_strategies",
|
|
100
|
+
description="List available git initialization strategies for template cloning",
|
|
101
|
+
inputSchema={
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {},
|
|
104
|
+
"required": [],
|
|
105
|
+
},
|
|
106
|
+
),
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
__all__ = ["get_tool_schemas"]
|
|
111
|
+
|
|
112
|
+
# EOF
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-08
|
|
3
|
+
# File: src/scitex/template/mcp_server.py
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MCP Server for SciTeX Template - Project Scaffolding Framework
|
|
8
|
+
|
|
9
|
+
Provides tools for:
|
|
10
|
+
- Listing available project templates
|
|
11
|
+
- Getting detailed template information
|
|
12
|
+
- Creating new projects from templates
|
|
13
|
+
- Managing git initialization strategies
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import asyncio
|
|
19
|
+
|
|
20
|
+
# Graceful MCP dependency handling
|
|
21
|
+
try:
|
|
22
|
+
import mcp.types as types
|
|
23
|
+
from mcp.server import NotificationOptions, Server
|
|
24
|
+
from mcp.server.models import InitializationOptions
|
|
25
|
+
from mcp.server.stdio import stdio_server
|
|
26
|
+
|
|
27
|
+
MCP_AVAILABLE = True
|
|
28
|
+
except ImportError:
|
|
29
|
+
MCP_AVAILABLE = False
|
|
30
|
+
types = None # type: ignore
|
|
31
|
+
Server = None # type: ignore
|
|
32
|
+
NotificationOptions = None # type: ignore
|
|
33
|
+
InitializationOptions = None # type: ignore
|
|
34
|
+
stdio_server = None # type: ignore
|
|
35
|
+
|
|
36
|
+
__all__ = ["TemplateServer", "main", "MCP_AVAILABLE"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TemplateServer:
|
|
40
|
+
"""MCP Server for Project Template Management."""
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
self.server = Server("scitex-template")
|
|
44
|
+
self.setup_handlers()
|
|
45
|
+
|
|
46
|
+
def setup_handlers(self):
|
|
47
|
+
"""Set up MCP server handlers."""
|
|
48
|
+
from ._mcp_handlers import (
|
|
49
|
+
clone_template_handler,
|
|
50
|
+
get_template_info_handler,
|
|
51
|
+
list_git_strategies_handler,
|
|
52
|
+
list_templates_handler,
|
|
53
|
+
)
|
|
54
|
+
from ._mcp_tool_schemas import get_tool_schemas
|
|
55
|
+
|
|
56
|
+
@self.server.list_tools()
|
|
57
|
+
async def handle_list_tools():
|
|
58
|
+
return get_tool_schemas()
|
|
59
|
+
|
|
60
|
+
@self.server.call_tool()
|
|
61
|
+
async def handle_call_tool(name: str, arguments: dict):
|
|
62
|
+
# List templates
|
|
63
|
+
if name == "list_templates":
|
|
64
|
+
return await self._wrap_result(list_templates_handler())
|
|
65
|
+
|
|
66
|
+
# Get template info
|
|
67
|
+
elif name == "get_template_info":
|
|
68
|
+
return await self._wrap_result(get_template_info_handler(**arguments))
|
|
69
|
+
|
|
70
|
+
# Clone template
|
|
71
|
+
elif name == "clone_template":
|
|
72
|
+
return await self._wrap_result(clone_template_handler(**arguments))
|
|
73
|
+
|
|
74
|
+
# List git strategies
|
|
75
|
+
elif name == "list_git_strategies":
|
|
76
|
+
return await self._wrap_result(list_git_strategies_handler())
|
|
77
|
+
|
|
78
|
+
else:
|
|
79
|
+
raise ValueError(f"Unknown tool: {name}")
|
|
80
|
+
|
|
81
|
+
@self.server.list_resources()
|
|
82
|
+
async def handle_list_resources():
|
|
83
|
+
"""List available template resources."""
|
|
84
|
+
resources = [
|
|
85
|
+
types.Resource(
|
|
86
|
+
uri="template://templates",
|
|
87
|
+
name="Available Templates",
|
|
88
|
+
description="List of all available project templates",
|
|
89
|
+
mimeType="application/json",
|
|
90
|
+
),
|
|
91
|
+
types.Resource(
|
|
92
|
+
uri="template://git-strategies",
|
|
93
|
+
name="Git Strategies",
|
|
94
|
+
description="Available git initialization strategies",
|
|
95
|
+
mimeType="application/json",
|
|
96
|
+
),
|
|
97
|
+
]
|
|
98
|
+
return resources
|
|
99
|
+
|
|
100
|
+
@self.server.read_resource()
|
|
101
|
+
async def handle_read_resource(uri: str):
|
|
102
|
+
"""Read a template resource."""
|
|
103
|
+
import json
|
|
104
|
+
|
|
105
|
+
if uri == "template://templates":
|
|
106
|
+
result = await list_templates_handler()
|
|
107
|
+
return types.TextResourceContents(
|
|
108
|
+
uri=uri,
|
|
109
|
+
mimeType="application/json",
|
|
110
|
+
text=json.dumps(result, indent=2),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
elif uri == "template://git-strategies":
|
|
114
|
+
result = await list_git_strategies_handler()
|
|
115
|
+
return types.TextResourceContents(
|
|
116
|
+
uri=uri,
|
|
117
|
+
mimeType="application/json",
|
|
118
|
+
text=json.dumps(result, indent=2),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
else:
|
|
122
|
+
raise ValueError(f"Unknown resource URI: {uri}")
|
|
123
|
+
|
|
124
|
+
async def _wrap_result(self, coro):
|
|
125
|
+
"""Wrap handler result as MCP TextContent."""
|
|
126
|
+
import json
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
result = await coro
|
|
130
|
+
return [
|
|
131
|
+
types.TextContent(
|
|
132
|
+
type="text",
|
|
133
|
+
text=json.dumps(result, indent=2, default=str),
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
except Exception as e:
|
|
137
|
+
return [
|
|
138
|
+
types.TextContent(
|
|
139
|
+
type="text",
|
|
140
|
+
text=json.dumps({"success": False, "error": str(e)}, indent=2),
|
|
141
|
+
)
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
async def _run_server():
|
|
146
|
+
"""Run the MCP server (internal)."""
|
|
147
|
+
server = TemplateServer()
|
|
148
|
+
async with stdio_server() as (read_stream, write_stream):
|
|
149
|
+
await server.server.run(
|
|
150
|
+
read_stream,
|
|
151
|
+
write_stream,
|
|
152
|
+
InitializationOptions(
|
|
153
|
+
server_name="scitex-template",
|
|
154
|
+
server_version="0.1.0",
|
|
155
|
+
capabilities=server.server.get_capabilities(
|
|
156
|
+
notification_options=NotificationOptions(),
|
|
157
|
+
experimental_capabilities={},
|
|
158
|
+
),
|
|
159
|
+
),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def main():
|
|
164
|
+
"""Main entry point for the MCP server."""
|
|
165
|
+
if not MCP_AVAILABLE:
|
|
166
|
+
import sys
|
|
167
|
+
|
|
168
|
+
print("=" * 60)
|
|
169
|
+
print("MCP Server 'scitex-template' requires the 'mcp' package.")
|
|
170
|
+
print()
|
|
171
|
+
print("Install with:")
|
|
172
|
+
print(" pip install mcp")
|
|
173
|
+
print()
|
|
174
|
+
print("Or install scitex with MCP support:")
|
|
175
|
+
print(" pip install scitex[mcp]")
|
|
176
|
+
print("=" * 60)
|
|
177
|
+
sys.exit(1)
|
|
178
|
+
|
|
179
|
+
asyncio.run(_run_server())
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
if __name__ == "__main__":
|
|
183
|
+
main()
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# EOF
|
|
@@ -206,7 +206,7 @@ def _check_run_main_unchanged(content: str) -> bool:
|
|
|
206
206
|
r"import matplotlib\.pyplot as plt",
|
|
207
207
|
r"import scitex as stx",
|
|
208
208
|
r"args = parse_args\(\)",
|
|
209
|
-
r"CONFIG, sys\.stdout, sys\.stderr, plt, CC,
|
|
209
|
+
r"CONFIG, sys\.stdout, sys\.stderr, plt, CC, rng = stx\.session\.start\(",
|
|
210
210
|
r"exit_status = main\(args\)",
|
|
211
211
|
r"stx\.session\.close\(",
|
|
212
212
|
]
|
|
@@ -535,7 +535,7 @@ def run_main() -> None:
|
|
|
535
535
|
|
|
536
536
|
args = parse_args()
|
|
537
537
|
|
|
538
|
-
CONFIG, sys.stdout, sys.stderr, plt, CC,
|
|
538
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC, rng = stx.session.start(
|
|
539
539
|
sys,
|
|
540
540
|
plt,
|
|
541
541
|
args=args,
|
scitex/utils/template.py
CHANGED
scitex/web/__init__.py
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Web-related utilities module for scitex."""
|
|
3
3
|
|
|
4
|
+
from ._scraping import get_image_urls, get_urls
|
|
4
5
|
from ._search_pubmed import (
|
|
5
|
-
search_pubmed,
|
|
6
|
-
_search_pubmed,
|
|
7
6
|
_fetch_details,
|
|
8
|
-
_parse_abstract_xml,
|
|
9
7
|
_get_citation,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
format_bibtex,
|
|
13
|
-
fetch_async,
|
|
8
|
+
_parse_abstract_xml,
|
|
9
|
+
_search_pubmed,
|
|
14
10
|
batch__fetch_details,
|
|
11
|
+
fetch_async,
|
|
12
|
+
format_bibtex,
|
|
13
|
+
get_crossref_metrics,
|
|
15
14
|
parse_args,
|
|
16
15
|
run_main,
|
|
16
|
+
save_bibtex,
|
|
17
|
+
search_pubmed,
|
|
17
18
|
)
|
|
18
19
|
from ._summarize_url import (
|
|
19
|
-
summarize_url,
|
|
20
|
-
extract_main_content,
|
|
21
|
-
crawl_url,
|
|
22
20
|
crawl_to_json,
|
|
21
|
+
crawl_url,
|
|
22
|
+
extract_main_content,
|
|
23
23
|
summarize_all,
|
|
24
|
+
summarize_url,
|
|
24
25
|
)
|
|
25
|
-
from .
|
|
26
|
+
from .download_images import download_images
|
|
26
27
|
|
|
27
28
|
__all__ = [
|
|
28
29
|
"search_pubmed",
|