rowan-mcp 1.0.1__tar.gz → 1.0.2__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 rowan-mcp might be problematic. Click here for more details.

Files changed (41) hide show
  1. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/.gitignore +1 -0
  2. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/PKG-INFO +9 -1
  3. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/README.md +8 -0
  4. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/pyproject.toml +1 -1
  5. rowan_mcp-1.0.2/rowan-dxt.dxt +0 -0
  6. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/__init__.py +1 -1
  7. rowan_mcp-1.0.2/rowan_mcp/functions/pka.py +88 -0
  8. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/uv.lock +1 -1
  9. rowan_mcp-1.0.1/MANIFEST.in +0 -8
  10. rowan_mcp-1.0.1/rowan-dxt.dxt +0 -0
  11. rowan_mcp-1.0.1/rowan_mcp/functions/pka.py +0 -137
  12. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/ROWAN_MCP_TEST_QUERIES.md +0 -0
  13. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/ROWAN_MCP_TOOLS.md +0 -0
  14. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/__main__.py +0 -0
  15. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/admet.py +0 -0
  16. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/bde.py +0 -0
  17. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/calculation_retrieve.py +0 -0
  18. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/conformers.py +0 -0
  19. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/descriptors.py +0 -0
  20. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/docking.py +0 -0
  21. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/docking_enhanced.py +0 -0
  22. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/electronic_properties.py +0 -0
  23. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/folder_management.py +0 -0
  24. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/fukui.py +0 -0
  25. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/hydrogen_bond_basicity.py +0 -0
  26. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/irc.py +0 -0
  27. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/macropka.py +0 -0
  28. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/molecular_converter.py +0 -0
  29. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/molecular_dynamics.py +0 -0
  30. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/molecule_lookup.py +0 -0
  31. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/multistage_opt.py +0 -0
  32. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/pdb_handler.py +0 -0
  33. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/redox_potential.py +0 -0
  34. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/scan.py +0 -0
  35. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/scan_analyzer.py +0 -0
  36. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/solubility.py +0 -0
  37. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/spin_states.py +0 -0
  38. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/system_management.py +0 -0
  39. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/tautomers.py +0 -0
  40. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/functions/workflow_management.py +0 -0
  41. {rowan_mcp-1.0.1 → rowan_mcp-1.0.2}/rowan_mcp/server.py +0 -0
@@ -9,3 +9,4 @@ __pycache__/
9
9
 
10
10
  .claude
11
11
  CLAUDE.md
12
+ /dist
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rowan-mcp
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Summary: Model Context Protocol server for Rowan computational chemistry platform
5
5
  Project-URL: Homepage, https://github.com/k-yenko/rowan-mcp
6
6
  Author-email: Katherine Yenko <katherineayenko@gmail.com>
@@ -225,3 +225,11 @@ uv publish
225
225
  # Or publish to TestPyPI first
226
226
  uv publish --index-url https://test.pypi.org/simple/
227
227
  ```
228
+
229
+ To update the dxt file:
230
+ ```bash
231
+ # After updating the PyPI package, update all changed tools/functions
232
+
233
+ # Then update the desktop extension
234
+ dxt pack rowan-dxt
235
+ ```
@@ -193,3 +193,11 @@ uv publish
193
193
  # Or publish to TestPyPI first
194
194
  uv publish --index-url https://test.pypi.org/simple/
195
195
  ```
196
+
197
+ To update the dxt file:
198
+ ```bash
199
+ # After updating the PyPI package, update all changed tools/functions
200
+
201
+ # Then update the desktop extension
202
+ dxt pack rowan-dxt
203
+ ```
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rowan-mcp"
7
- version = "1.0.1"
7
+ version = "1.0.2"
8
8
  description = "Model Context Protocol server for Rowan computational chemistry platform"
9
9
  authors = [
10
10
  {name = "Katherine Yenko", email = "katherineayenko@gmail.com"}
Binary file
@@ -6,7 +6,7 @@ for integrating with Rowan's computational chemistry platform.
6
6
  """
7
7
 
8
8
  __version__ = "1.0.0"
9
- __author__ = "Rowan MCP Team"
9
+ __author__ = "Kat Yenko"
10
10
  __description__ = "MCP server for Rowan computational chemistry platform"
11
11
 
12
12
  from .server import main
@@ -0,0 +1,88 @@
1
+ """
2
+ Calculate pKa values for molecules using Rowan API.
3
+ """
4
+
5
+ import os
6
+ import rowan
7
+ from typing import Optional
8
+
9
+ # Set up logging
10
+ import logging
11
+ logger = logging.getLogger(__name__)
12
+
13
+ # Configure rowan API key
14
+ if not hasattr(rowan, 'api_key') or not rowan.api_key:
15
+ api_key = os.getenv("ROWAN_API_KEY")
16
+ if api_key:
17
+ rowan.api_key = api_key
18
+ logger.info("Rowan API key configured")
19
+ else:
20
+ logger.error("No ROWAN_API_KEY found in environment")
21
+
22
+ def log_rowan_api_call(workflow_type: str, **kwargs):
23
+ """Log Rowan API calls and let Rowan handle its own errors."""
24
+
25
+ # Simple logging for calculations
26
+ logger.info(f" Starting {workflow_type.replace('_', ' ')}...")
27
+
28
+ # Let Rowan handle everything - no custom error handling
29
+ return rowan.compute(workflow_type=workflow_type, **kwargs)
30
+
31
+ def rowan_pka(
32
+ name: str,
33
+ molecule: str,
34
+ folder_uuid: Optional[str] = None,
35
+ blocking: bool = True,
36
+ ping_interval: int = 5
37
+ ) -> str:
38
+ """Calculate pKa values for molecules.
39
+
40
+ Args:
41
+ name: Name for the calculation
42
+ molecule: Molecule SMILES string
43
+ folder_uuid: UUID of folder to organize calculation in
44
+ blocking: Whether to wait for completion (default: True)
45
+ ping_interval: How often to check status in seconds (default: 5)
46
+
47
+ Returns:
48
+ pKa calculation results
49
+ """
50
+ try:
51
+ result = log_rowan_api_call(
52
+ workflow_type="pka",
53
+ name=name,
54
+ molecule=molecule,
55
+ folder_uuid=folder_uuid,
56
+ blocking=blocking,
57
+ ping_interval=ping_interval
58
+ )
59
+
60
+ return str(result)
61
+
62
+ except Exception as e:
63
+ error_response = {
64
+ "error": f"pKa calculation failed: {str(e)}",
65
+ "name": name,
66
+ "molecule": molecule
67
+ }
68
+ return str(error_response)
69
+
70
+
71
+ def test_rowan_pka():
72
+ """Test the rowan_pka function."""
73
+ try:
74
+ # Test with minimal parameters
75
+ result = rowan_pka(
76
+ name="test_pka_water",
77
+ molecule="O"
78
+ )
79
+ print("pKa test successful")
80
+ print(f"Result: {result}")
81
+ return True
82
+ except Exception as e:
83
+ print(f"pKa test failed: {e}")
84
+ return False
85
+
86
+
87
+ if __name__ == "__main__":
88
+ test_rowan_pka()
@@ -1229,7 +1229,7 @@ wheels = [
1229
1229
 
1230
1230
  [[package]]
1231
1231
  name = "rowan-mcp"
1232
- version = "1.0.0"
1232
+ version = "1.0.1"
1233
1233
  source = { editable = "." }
1234
1234
  dependencies = [
1235
1235
  { name = "fastapi" },
@@ -1,8 +0,0 @@
1
- include README.md
2
- include ROWAN_MCP_TOOLS.md
3
- include ROWAN_MCP_TEST_QUERIES.md
4
- include rowan-dxt.dxt
5
- recursive-include rowan_mcp *.db
6
- recursive-exclude * __pycache__
7
- recursive-exclude * *.py[co]
8
- recursive-exclude * .DS_Store
Binary file
@@ -1,137 +0,0 @@
1
- """
2
- Calculate pKa values for molecules using Rowan API.
3
- """
4
-
5
- import os
6
- import rowan
7
- from typing import Optional
8
-
9
- # Set up logging
10
- import logging
11
- logger = logging.getLogger(__name__)
12
-
13
- # Configure rowan API key
14
- if not hasattr(rowan, 'api_key') or not rowan.api_key:
15
- api_key = os.getenv("ROWAN_API_KEY")
16
- if api_key:
17
- rowan.api_key = api_key
18
- logger.info("🔑 Rowan API key configured")
19
- else:
20
- logger.error("No ROWAN_API_KEY found in environment")
21
-
22
- def log_rowan_api_call(workflow_type: str, **kwargs):
23
- """Log Rowan API calls and let Rowan handle its own errors."""
24
-
25
- # Simple logging for calculations
26
- logger.info(f" Starting {workflow_type.replace('_', ' ')}...")
27
-
28
- # Let Rowan handle everything - no custom error handling
29
- return rowan.compute(workflow_type=workflow_type, **kwargs)
30
-
31
- def rowan_pka(
32
- name: str,
33
- molecule: str,
34
- folder_uuid: Optional[str] = None,
35
- blocking: bool = True,
36
- ping_interval: int = 5
37
- ) -> str:
38
- """Calculate pKa values for molecules.
39
-
40
- Args:
41
- name: Name for the calculation
42
- molecule: Molecule SMILES string or common name
43
- folder_uuid: UUID of folder to organize calculation in
44
- blocking: Whether to wait for completion (default: True)
45
- ping_interval: How often to check status in seconds (default: 5)
46
-
47
- Returns:
48
- pKa calculation results
49
- """
50
- try:
51
- result = log_rowan_api_call(
52
- workflow_type="pka",
53
- name=name,
54
- molecule=molecule,
55
- folder_uuid=folder_uuid,
56
- blocking=blocking,
57
- ping_interval=ping_interval
58
- )
59
-
60
- # Format results based on whether we waited or not
61
- if blocking:
62
- # We waited for completion - format actual results
63
- status = result.get('status', result.get('object_status', 'Unknown'))
64
-
65
- if status == 2: # Completed successfully
66
- formatted = f" pKa calculation for '{name}' completed successfully!\n\n"
67
- elif status == 3: # Failed
68
- formatted = f" pKa calculation for '{name}' failed!\n\n"
69
- else:
70
- formatted = f" pKa calculation for '{name}' finished with status {status}\n\n"
71
-
72
- formatted += f" Molecule: {molecule}\n"
73
- formatted += f" Job UUID: {result.get('uuid', 'N/A')}\n"
74
- formatted += f" Status: {status}\n"
75
-
76
- # Try to extract pKa results
77
- if isinstance(result, dict) and 'object_data' in result and result['object_data']:
78
- data = result['object_data']
79
-
80
- # Extract pKa values
81
- if 'strongest_acid' in data:
82
- if data['strongest_acid'] is not None:
83
- formatted += f" Strongest Acid pKa: {data['strongest_acid']:.2f}\n"
84
- else:
85
- formatted += f" Strongest Acid pKa: N/A (no acidic sites found)\n"
86
-
87
- if 'strongest_base' in data:
88
- if data['strongest_base'] is not None:
89
- formatted += f" Strongest Base pKa: {data['strongest_base']:.2f}\n"
90
- else:
91
- formatted += f" Strongest Base pKa: N/A (no basic sites found)\n"
92
- if 'pka_values' in data and isinstance(data['pka_values'], list):
93
- formatted += f" All pKa values: {', '.join([f'{val:.2f}' for val in data['pka_values']])}\n"
94
-
95
- # Additional properties if available
96
- if 'ionizable_sites' in data:
97
- formatted += f" Ionizable sites found: {data['ionizable_sites']}\n"
98
-
99
- # Basic guidance
100
- if status == 2:
101
- formatted += f"\n Use rowan_workflow_management(action='retrieve', workflow_uuid='{result.get('uuid')}') for detailed data\n"
102
- else:
103
- # Non-blocking mode - just submission confirmation
104
- formatted = f" pKa calculation for '{name}' submitted!\n\n"
105
- formatted += f" Molecule: {molecule}\n"
106
- formatted += f" Job UUID: {result.get('uuid', 'N/A')}\n"
107
- formatted += f" Status: {result.get('status', 'Submitted')}\n"
108
-
109
- return formatted
110
-
111
- except Exception as e:
112
- error_response = {
113
- "error": f"pKa calculation failed: {str(e)}",
114
- "name": name,
115
- "molecule": molecule
116
- }
117
- return str(error_response)
118
-
119
-
120
- def test_rowan_pka():
121
- """Test the rowan_pka function."""
122
- try:
123
- # Test with minimal parameters
124
- result = rowan_pka(
125
- name="test_pka_water",
126
- molecule="O"
127
- )
128
- print("✅ pKa test successful!")
129
- print(f"Result: {result}")
130
- return True
131
- except Exception as e:
132
- print(f"pKa test failed: {e}")
133
- return False
134
-
135
-
136
- if __name__ == "__main__":
137
- test_rowan_pka()
File without changes
File without changes