Spaces:
Sleeping
Sleeping
kabudadada commited on
Commit ·
b2105f3
1
Parent(s): 97961e2
feat(mcp): add get_prediction_pdb tool (latest/by name) and simplify to read-only
Browse files
esm/mcp_output/mcp_plugin/mcp_service.py
CHANGED
|
@@ -196,6 +196,51 @@ def predict_structure(sequence: str):
|
|
| 196 |
"error": f"Error predicting structure: {str(e)}"
|
| 197 |
}
|
| 198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
@mcp.tool(name="analyze_protein_sequence", description="Analyze protein sequence features")
|
| 200 |
def analyze_protein_sequence(sequence: str):
|
| 201 |
"""Analyze basic features of a protein sequence"""
|
|
|
|
| 196 |
"error": f"Error predicting structure: {str(e)}"
|
| 197 |
}
|
| 198 |
|
| 199 |
+
@mcp.tool(name="get_prediction_pdb", description="Fetch saved PDB by filename or latest from predictions directory")
|
| 200 |
+
def get_prediction_pdb(filename: str):
|
| 201 |
+
"""Return PDB content saved under predictions directory.
|
| 202 |
+
|
| 203 |
+
Parameters:
|
| 204 |
+
filename (str): Filename in predictions directory. Use "latest" to fetch the most recent file.
|
| 205 |
+
|
| 206 |
+
Returns:
|
| 207 |
+
dict: success/result/error. result contains { filename, pdb_content, path }
|
| 208 |
+
"""
|
| 209 |
+
try:
|
| 210 |
+
import glob
|
| 211 |
+
predictions_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "predictions")
|
| 212 |
+
if not os.path.isdir(predictions_dir):
|
| 213 |
+
return {"success": False, "result": None, "error": f"Predictions dir not found: {predictions_dir}"}
|
| 214 |
+
|
| 215 |
+
target_path: str
|
| 216 |
+
if filename.strip().lower() == "latest":
|
| 217 |
+
files = sorted(
|
| 218 |
+
glob.glob(os.path.join(predictions_dir, "*.pdb")),
|
| 219 |
+
key=lambda p: os.path.getmtime(p),
|
| 220 |
+
reverse=True,
|
| 221 |
+
)
|
| 222 |
+
if not files:
|
| 223 |
+
return {"success": False, "result": None, "error": "No PDB files found"}
|
| 224 |
+
target_path = files[0]
|
| 225 |
+
filename = os.path.basename(target_path)
|
| 226 |
+
else:
|
| 227 |
+
# prevent path traversal
|
| 228 |
+
safe_name = os.path.basename(filename)
|
| 229 |
+
target_path = os.path.join(predictions_dir, safe_name)
|
| 230 |
+
if not os.path.isfile(target_path):
|
| 231 |
+
return {"success": False, "result": None, "error": f"File not found: {safe_name}"}
|
| 232 |
+
|
| 233 |
+
with open(target_path, "r") as f:
|
| 234 |
+
content = f.read()
|
| 235 |
+
|
| 236 |
+
return {
|
| 237 |
+
"success": True,
|
| 238 |
+
"result": {"filename": filename, "pdb_content": content, "path": target_path},
|
| 239 |
+
"error": None,
|
| 240 |
+
}
|
| 241 |
+
except Exception as e:
|
| 242 |
+
return {"success": False, "result": None, "error": str(e)}
|
| 243 |
+
|
| 244 |
@mcp.tool(name="analyze_protein_sequence", description="Analyze protein sequence features")
|
| 245 |
def analyze_protein_sequence(sequence: str):
|
| 246 |
"""Analyze basic features of a protein sequence"""
|