rowan-mcp 1.0.2__tar.gz → 2.0.1__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 (76) hide show
  1. rowan_mcp-2.0.1/.gitignore +21 -0
  2. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/PKG-INFO +38 -45
  3. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/README.md +33 -41
  4. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/pyproject.toml +15 -4
  5. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/__init__.py +1 -1
  6. rowan_mcp-2.0.1/rowan_mcp/__main__.py +12 -0
  7. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/admet.py +0 -5
  8. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/bde.py +1 -8
  9. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/conformers.py +1 -4
  10. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/descriptors.py +1 -4
  11. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/docking.py +6 -56
  12. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/electronic_properties.py +1 -4
  13. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/folder_management.py +1 -8
  14. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/fukui.py +1 -4
  15. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/hydrogen_bond_basicity.py +1 -8
  16. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/multistage_opt.py +1 -4
  17. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/pka.py +1 -8
  18. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/redox_potential.py +2 -5
  19. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/system_management.py +1 -8
  20. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/tautomers.py +1 -4
  21. rowan_mcp-2.0.1/rowan_mcp/functions_v2/BENCHMARK.md +86 -0
  22. rowan_mcp-2.0.1/rowan_mcp/functions_v2/molecule_lookup.py +232 -0
  23. rowan_mcp-2.0.1/rowan_mcp/functions_v2/protein_management.py +141 -0
  24. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_basic_calculation_workflow.py +195 -0
  25. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_conformer_search_workflow.py +158 -0
  26. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_descriptors_workflow.py +52 -0
  27. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_docking_workflow.py +244 -0
  28. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_fukui_workflow.py +114 -0
  29. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_irc_workflow.py +58 -0
  30. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_macropka_workflow.py +99 -0
  31. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_pka_workflow.py +72 -0
  32. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_protein_cofolding_workflow.py +88 -0
  33. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_redox_potential_workflow.py +55 -0
  34. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_scan_workflow.py +82 -0
  35. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_solubility_workflow.py +157 -0
  36. rowan_mcp-2.0.1/rowan_mcp/functions_v2/submit_tautomer_search_workflow.py +51 -0
  37. rowan_mcp-2.0.1/rowan_mcp/functions_v2/workflow_management_v2.py +382 -0
  38. rowan_mcp-2.0.1/rowan_mcp/server.py +134 -0
  39. rowan_mcp-2.0.1/rowan_mcp/tests/basic_calculation_from_json.py +0 -0
  40. rowan_mcp-2.0.1/rowan_mcp/tests/basic_calculation_with_constraint.py +33 -0
  41. rowan_mcp-2.0.1/rowan_mcp/tests/basic_calculation_with_solvent.py +0 -0
  42. rowan_mcp-2.0.1/rowan_mcp/tests/bde.py +37 -0
  43. rowan_mcp-2.0.1/rowan_mcp/tests/benchmark_queries.md +120 -0
  44. rowan_mcp-2.0.1/rowan_mcp/tests/cofolding_screen.py +131 -0
  45. rowan_mcp-2.0.1/rowan_mcp/tests/conformer_dependent_redox.py +37 -0
  46. rowan_mcp-2.0.1/rowan_mcp/tests/conformers.py +31 -0
  47. rowan_mcp-2.0.1/rowan_mcp/tests/data.json +189 -0
  48. rowan_mcp-2.0.1/rowan_mcp/tests/docking_screen.py +157 -0
  49. rowan_mcp-2.0.1/rowan_mcp/tests/irc.py +24 -0
  50. rowan_mcp-2.0.1/rowan_mcp/tests/macropka.py +13 -0
  51. rowan_mcp-2.0.1/rowan_mcp/tests/multistage_opt.py +13 -0
  52. rowan_mcp-2.0.1/rowan_mcp/tests/optimization.py +21 -0
  53. rowan_mcp-2.0.1/rowan_mcp/tests/phenol_pka.py +36 -0
  54. rowan_mcp-2.0.1/rowan_mcp/tests/pka.py +36 -0
  55. rowan_mcp-2.0.1/rowan_mcp/tests/protein_cofolding.py +17 -0
  56. rowan_mcp-2.0.1/rowan_mcp/tests/scan.py +28 -0
  57. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/uv.lock +1 -1
  58. rowan_mcp-1.0.2/.gitignore +0 -12
  59. rowan_mcp-1.0.2/ROWAN_MCP_TEST_QUERIES.md +0 -123
  60. rowan_mcp-1.0.2/ROWAN_MCP_TOOLS.md +0 -440
  61. rowan_mcp-1.0.2/rowan-dxt.dxt +0 -0
  62. rowan_mcp-1.0.2/rowan_mcp/__main__.py +0 -14
  63. rowan_mcp-1.0.2/rowan_mcp/server.py +0 -169
  64. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/calculation_retrieve.py +0 -0
  65. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/docking_enhanced.py +0 -0
  66. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/irc.py +0 -0
  67. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/macropka.py +0 -0
  68. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/molecular_converter.py +0 -0
  69. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/molecular_dynamics.py +0 -0
  70. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/molecule_lookup.py +0 -0
  71. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/pdb_handler.py +0 -0
  72. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/scan.py +0 -0
  73. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/scan_analyzer.py +0 -0
  74. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/solubility.py +0 -0
  75. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/spin_states.py +0 -0
  76. {rowan_mcp-1.0.2 → rowan_mcp-2.0.1}/rowan_mcp/functions/workflow_management.py +0 -0
@@ -0,0 +1,21 @@
1
+ /.venv
2
+ /rowan-dxt
3
+ .env
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+ *.so
8
+ .DS_Store
9
+
10
+ .claude
11
+ CLAUDE.md
12
+ /dist
13
+
14
+ # MCP configuration (may contain tokens)
15
+ .mcp.json
16
+
17
+ # Personal compatibility notes
18
+ GEMINI_MCP_COMPATIBILITY.md
19
+ MCP_CHATGPT_GEMINI_COMPATIBILITY_ANALYSIS.md
20
+ ROWAN_MCP_TEST_QUERIES.md
21
+ ROWAN_MCP_TOOLS.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rowan-mcp
3
- Version: 1.0.2
3
+ Version: 2.0.1
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>
@@ -13,14 +13,15 @@ Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Topic :: Scientific/Engineering :: Chemistry
16
- Requires-Python: >=3.10
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: aiohttp>=3.12.15
17
18
  Requires-Dist: fastapi>=0.104.0
18
- Requires-Dist: fastmcp>=0.2.0
19
+ Requires-Dist: fastmcp>=2.11.3
19
20
  Requires-Dist: pubchempy>=1.0.4
20
21
  Requires-Dist: pydantic>=2.0.0
21
22
  Requires-Dist: python-dotenv>=1.0.0
22
23
  Requires-Dist: rdkit>=2025.3.2
23
- Requires-Dist: rowan-python>=0.1.0
24
+ Requires-Dist: rowan-python>=2.1.1
24
25
  Requires-Dist: typing-extensions>=4.0.0
25
26
  Requires-Dist: uvicorn>=0.24.0
26
27
  Provides-Extra: dev
@@ -32,7 +33,7 @@ Description-Content-Type: text/markdown
32
33
 
33
34
  # Rowan MCP Server
34
35
 
35
- This project wraps an MCP (Model Context Protocol) around Rowan's tools, making it easy for users to design molecuels and run simulations in natural everyday language.
36
+ MCP server for making it easy to run Rowan's molecular design and simulation tools.
36
37
 
37
38
  ---
38
39
 
@@ -56,34 +57,25 @@ That's it - no command line setup needed!
56
57
 
57
58
  Just add this to your MCP configuration and it will automatically install and run:
58
59
 
59
- **Using uvx (simplest):**
60
+ **HTTP/SSE configuration:**
60
61
  ```json
61
62
  {
62
63
  "mcpServers": {
63
64
  "rowan": {
64
- "command": "uvx",
65
- "args": ["--from", "rowan-mcp", "rowan-mcp"],
66
- "env": {
67
- "ROWAN_API_KEY": "your_api_key_here"
68
- }
65
+ "type": "http",
66
+ "url": "http://127.0.0.1:6276/sse"
69
67
  }
70
68
  }
71
69
  }
72
70
  ```
73
71
 
74
- **Using uv run (alternative):**
75
- ```json
76
- {
77
- "mcpServers": {
78
- "rowan": {
79
- "command": "uv",
80
- "args": ["run", "--with", "rowan-mcp", "-m", "rowan_mcp"],
81
- "env": {
82
- "ROWAN_API_KEY": "your_api_key_here"
83
- }
84
- }
85
- }
86
- }
72
+ Then start the server:
73
+ ```bash
74
+ # Set your API key
75
+ export ROWAN_API_KEY="your_api_key_here"
76
+
77
+ # Start the HTTP server
78
+ uvx --from rowan-mcp rowan-mcp
87
79
  ```
88
80
 
89
81
  ### **Option 2: Manual Installation**
@@ -100,20 +92,24 @@ uv add rowan-mcp
100
92
  pip install rowan-mcp
101
93
  ```
102
94
 
103
- Then use this configuration:
95
+ Then configure and start:
104
96
  ```json
105
97
  {
106
98
  "mcpServers": {
107
99
  "rowan": {
108
- "command": "rowan-mcp",
109
- "env": {
110
- "ROWAN_API_KEY": "your_api_key_here"
111
- }
100
+ "type": "http",
101
+ "url": "http://127.0.0.1:6276/sse"
112
102
  }
113
103
  }
114
104
  }
115
105
  ```
116
106
 
107
+ ```bash
108
+ # Set API key and start server
109
+ export ROWAN_API_KEY="your_api_key_here"
110
+ rowan-mcp
111
+ ```
112
+
117
113
  ### **Get API Key**
118
114
 
119
115
  Visit [labs.rowansci.com](https://labs.rowansci.com) → Create account → Generate API key
@@ -134,7 +130,7 @@ Ask the LLM to:
134
130
 
135
131
  ## **System Requirements**
136
132
 
137
- - **Python 3.10+** (Python 3.11+ recommended)
133
+ - **Python 3.11+**
138
134
  - **Package manager**: [uv](https://docs.astral.sh/uv/) (recommended) or pip
139
135
  - **Rowan API key** (free at [labs.rowansci.com](https://labs.rowansci.com))
140
136
  - **MCP-compatible client** (Claude Desktop, etc.)
@@ -142,7 +138,8 @@ Ask the LLM to:
142
138
  **Development commands** (if you cloned the repo):
143
139
  ```bash
144
140
  # Run from source
145
- uv run python -m rowan_mcp --http
141
+ export ROWAN_API_KEY="your_api_key_here"
142
+ uv run python -m rowan_mcp
146
143
  ```
147
144
 
148
145
  ---
@@ -176,7 +173,7 @@ uv run python -m rowan_mcp --http
176
173
 
177
174
  ## **Requirements**
178
175
 
179
- - Python 3.10+
176
+ - Python 3.11+
180
177
  - Rowan API key
181
178
  - MCP-compatible AI assistant (Claude Desktop, etc.)
182
179
 
@@ -187,19 +184,6 @@ uv run python -m rowan_mcp --http
187
184
 
188
185
  ---
189
186
 
190
- ## **Todo**
191
-
192
- - [ ] Remove unnecessary AI spaghetti formatting 🙃
193
- - [ ] Some complex conformer searches hang on "running"
194
- - [ ] Edit MCP one-liner context
195
- - [ ] Transition state finding and IRC
196
- - [X] `rowan_scan` - Potential energy surfaces
197
- - [ ] `rowan_docking` - Protein-ligand docking
198
- - [X] add in h-bond, BDE and macroscopic pka, logD, BBB
199
- - [ ] Folder listing API bug (returns 500 error) - Rowan side?
200
- - [ ] Multistage optimization sometimes shows unexpected imaginary frequencies
201
- - [ ] Some calculations show as finished in logs but not in Rowan UI
202
-
203
187
  ## **Citation**
204
188
 
205
189
  If you use this MCP tool in your research, please cite the underlying Rowan platform:
@@ -233,3 +217,12 @@ To update the dxt file:
233
217
  # Then update the desktop extension
234
218
  dxt pack rowan-dxt
235
219
  ```
220
+ ### MCP inspector
221
+ ```bash
222
+ # Start the server first
223
+ export ROWAN_API_KEY="your_api_key_here"
224
+ uv run python -m rowan_mcp &
225
+
226
+ # Then inspect
227
+ npx @modelcontextprotocol/inspector http://127.0.0.1:6276/sse
228
+ ```
@@ -1,6 +1,6 @@
1
1
  # Rowan MCP Server
2
2
 
3
- This project wraps an MCP (Model Context Protocol) around Rowan's tools, making it easy for users to design molecuels and run simulations in natural everyday language.
3
+ MCP server for making it easy to run Rowan's molecular design and simulation tools.
4
4
 
5
5
  ---
6
6
 
@@ -24,34 +24,25 @@ That's it - no command line setup needed!
24
24
 
25
25
  Just add this to your MCP configuration and it will automatically install and run:
26
26
 
27
- **Using uvx (simplest):**
27
+ **HTTP/SSE configuration:**
28
28
  ```json
29
29
  {
30
30
  "mcpServers": {
31
31
  "rowan": {
32
- "command": "uvx",
33
- "args": ["--from", "rowan-mcp", "rowan-mcp"],
34
- "env": {
35
- "ROWAN_API_KEY": "your_api_key_here"
36
- }
32
+ "type": "http",
33
+ "url": "http://127.0.0.1:6276/sse"
37
34
  }
38
35
  }
39
36
  }
40
37
  ```
41
38
 
42
- **Using uv run (alternative):**
43
- ```json
44
- {
45
- "mcpServers": {
46
- "rowan": {
47
- "command": "uv",
48
- "args": ["run", "--with", "rowan-mcp", "-m", "rowan_mcp"],
49
- "env": {
50
- "ROWAN_API_KEY": "your_api_key_here"
51
- }
52
- }
53
- }
54
- }
39
+ Then start the server:
40
+ ```bash
41
+ # Set your API key
42
+ export ROWAN_API_KEY="your_api_key_here"
43
+
44
+ # Start the HTTP server
45
+ uvx --from rowan-mcp rowan-mcp
55
46
  ```
56
47
 
57
48
  ### **Option 2: Manual Installation**
@@ -68,20 +59,24 @@ uv add rowan-mcp
68
59
  pip install rowan-mcp
69
60
  ```
70
61
 
71
- Then use this configuration:
62
+ Then configure and start:
72
63
  ```json
73
64
  {
74
65
  "mcpServers": {
75
66
  "rowan": {
76
- "command": "rowan-mcp",
77
- "env": {
78
- "ROWAN_API_KEY": "your_api_key_here"
79
- }
67
+ "type": "http",
68
+ "url": "http://127.0.0.1:6276/sse"
80
69
  }
81
70
  }
82
71
  }
83
72
  ```
84
73
 
74
+ ```bash
75
+ # Set API key and start server
76
+ export ROWAN_API_KEY="your_api_key_here"
77
+ rowan-mcp
78
+ ```
79
+
85
80
  ### **Get API Key**
86
81
 
87
82
  Visit [labs.rowansci.com](https://labs.rowansci.com) → Create account → Generate API key
@@ -102,7 +97,7 @@ Ask the LLM to:
102
97
 
103
98
  ## **System Requirements**
104
99
 
105
- - **Python 3.10+** (Python 3.11+ recommended)
100
+ - **Python 3.11+**
106
101
  - **Package manager**: [uv](https://docs.astral.sh/uv/) (recommended) or pip
107
102
  - **Rowan API key** (free at [labs.rowansci.com](https://labs.rowansci.com))
108
103
  - **MCP-compatible client** (Claude Desktop, etc.)
@@ -110,7 +105,8 @@ Ask the LLM to:
110
105
  **Development commands** (if you cloned the repo):
111
106
  ```bash
112
107
  # Run from source
113
- uv run python -m rowan_mcp --http
108
+ export ROWAN_API_KEY="your_api_key_here"
109
+ uv run python -m rowan_mcp
114
110
  ```
115
111
 
116
112
  ---
@@ -144,7 +140,7 @@ uv run python -m rowan_mcp --http
144
140
 
145
141
  ## **Requirements**
146
142
 
147
- - Python 3.10+
143
+ - Python 3.11+
148
144
  - Rowan API key
149
145
  - MCP-compatible AI assistant (Claude Desktop, etc.)
150
146
 
@@ -155,19 +151,6 @@ uv run python -m rowan_mcp --http
155
151
 
156
152
  ---
157
153
 
158
- ## **Todo**
159
-
160
- - [ ] Remove unnecessary AI spaghetti formatting 🙃
161
- - [ ] Some complex conformer searches hang on "running"
162
- - [ ] Edit MCP one-liner context
163
- - [ ] Transition state finding and IRC
164
- - [X] `rowan_scan` - Potential energy surfaces
165
- - [ ] `rowan_docking` - Protein-ligand docking
166
- - [X] add in h-bond, BDE and macroscopic pka, logD, BBB
167
- - [ ] Folder listing API bug (returns 500 error) - Rowan side?
168
- - [ ] Multistage optimization sometimes shows unexpected imaginary frequencies
169
- - [ ] Some calculations show as finished in logs but not in Rowan UI
170
-
171
154
  ## **Citation**
172
155
 
173
156
  If you use this MCP tool in your research, please cite the underlying Rowan platform:
@@ -201,3 +184,12 @@ To update the dxt file:
201
184
  # Then update the desktop extension
202
185
  dxt pack rowan-dxt
203
186
  ```
187
+ ### MCP inspector
188
+ ```bash
189
+ # Start the server first
190
+ export ROWAN_API_KEY="your_api_key_here"
191
+ uv run python -m rowan_mcp &
192
+
193
+ # Then inspect
194
+ npx @modelcontextprotocol/inspector http://127.0.0.1:6276/sse
195
+ ```
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rowan-mcp"
7
- version = "1.0.2"
7
+ version = "2.0.1"
8
8
  description = "Model Context Protocol server for Rowan computational chemistry platform"
9
9
  authors = [
10
10
  {name = "Katherine Yenko", email = "katherineayenko@gmail.com"}
11
11
  ]
12
12
  license = {text = "MIT"}
13
13
  readme = "README.md"
14
- requires-python = ">=3.10"
14
+ requires-python = ">=3.11"
15
15
  urls = {Homepage = "https://github.com/k-yenko/rowan-mcp"}
16
16
  classifiers = [
17
17
  "Development Status :: 3 - Alpha",
@@ -24,8 +24,8 @@ classifiers = [
24
24
  "Topic :: Scientific/Engineering :: Chemistry",
25
25
  ]
26
26
  dependencies = [
27
- "fastmcp>=0.2.0",
28
- "rowan-python>=0.1.0",
27
+ "fastmcp>=2.11.3",
28
+ "rowan-python>=2.1.1",
29
29
  "pydantic>=2.0.0",
30
30
  "typing-extensions>=4.0.0",
31
31
  "uvicorn>=0.24.0",
@@ -33,6 +33,7 @@ dependencies = [
33
33
  "python-dotenv>=1.0.0",
34
34
  "pubchempy>=1.0.4",
35
35
  "rdkit>=2025.3.2",
36
+ "aiohttp>=3.12.15",
36
37
  ]
37
38
 
38
39
  [project.optional-dependencies]
@@ -49,6 +50,16 @@ rowan-mcp = "rowan_mcp.server:main"
49
50
  [tool.hatch.build.targets.wheel]
50
51
  packages = ["rowan_mcp"]
51
52
 
53
+ [tool.hatch.build.targets.sdist]
54
+ exclude = [
55
+ "rowan-dxt/",
56
+ "dxt/",
57
+ "*.log",
58
+ "test_*.py",
59
+ ".venv/",
60
+ "*.dxt"
61
+ ]
62
+
52
63
  [tool.black]
53
64
  line-length = 88
54
65
  target-version = ['py38']
@@ -5,7 +5,7 @@ This package provides MCP (Model Context Protocol) server functionality
5
5
  for integrating with Rowan's computational chemistry platform.
6
6
  """
7
7
 
8
- __version__ = "1.0.0"
8
+ __version__ = "1.0.2"
9
9
  __author__ = "Kat Yenko"
10
10
  __description__ = "MCP server for Rowan computational chemistry platform"
11
11
 
@@ -0,0 +1,12 @@
1
+ """
2
+ Main entry point for Rowan MCP Server when run as a module.
3
+
4
+ Usage:
5
+ python -m rowan_mcp # HTTP/SSE mode
6
+ python -m rowan_mcp --help # Show help
7
+ """
8
+
9
+ if __name__ == "__main__":
10
+ # HTTP transport only
11
+ from .server import main
12
+ main()
@@ -16,11 +16,6 @@ except ImportError:
16
16
  # Setup logging
17
17
  logger = logging.getLogger(__name__)
18
18
 
19
- # Setup API key
20
- api_key = os.getenv("ROWAN_API_KEY")
21
- if rowan and api_key:
22
- rowan.api_key = api_key
23
-
24
19
 
25
20
  def log_rowan_api_call(workflow_type: str, **kwargs):
26
21
  """Log Rowan API calls with detailed parameters."""
@@ -10,14 +10,7 @@ from typing import Optional, List, Union
10
10
  import logging
11
11
  logger = logging.getLogger(__name__)
12
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")
13
+
21
14
 
22
15
  def log_rowan_api_call(workflow_type: str, **kwargs):
23
16
  """Log Rowan API calls and let Rowan handle its own errors."""
@@ -15,10 +15,7 @@ except ImportError:
15
15
  # Setup logging
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
- # Setup API key
19
- api_key = os.getenv("ROWAN_API_KEY")
20
- if rowan and api_key:
21
- rowan.api_key = api_key
18
+
22
19
 
23
20
  def log_rowan_api_call(workflow_type: str, **kwargs):
24
21
  """Log Rowan API calls and let Rowan handle its own errors."""
@@ -15,10 +15,7 @@ except ImportError:
15
15
  # Setup logging
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
- # Setup API key
19
- api_key = os.getenv("ROWAN_API_KEY")
20
- if rowan and api_key:
21
- rowan.api_key = api_key
18
+
22
19
 
23
20
  def log_rowan_api_call(workflow_type: str, **kwargs):
24
21
  """Log Rowan API calls with detailed parameters."""
@@ -192,63 +192,13 @@ def rowan_docking(
192
192
  if conformers is not None:
193
193
  compute_params["conformers"] = conformers
194
194
 
195
- # Submit docking calculation
195
+ # Submit docking calculation and return raw result
196
196
  result = rowan.compute(**compute_params)
197
-
198
- # Format results
199
- uuid = result.get('uuid', 'N/A')
200
- status = result.get('status', 'unknown')
201
-
202
- if blocking:
203
- # Blocking mode - check if successful
204
- if status == "success":
205
- formatted = f"✅ Docking calculation '{name}' completed successfully!\n"
206
- formatted += f"🔖 Workflow UUID: {uuid}\n"
207
- formatted += f"📊 Status: {status}\n\n"
208
-
209
- # Extract docking results if available
210
- object_data = result.get("object_data", {})
211
- scores = object_data.get("scores", [])
212
-
213
- if scores:
214
- formatted += f"🎯 Docking Results: {len(scores)} poses generated\n"
215
- formatted += f"📈 Best docking score: {scores[0] if scores else 'N/A'}\n"
216
-
217
- # Show top poses
218
- formatted += "\nTop poses:\n"
219
- for i, score in enumerate(scores[:5]):
220
- formatted += f" {i+1}. Score: {score}\n"
221
-
222
- if len(scores) > 5:
223
- formatted += f" ... and {len(scores) - 5} more poses\n"
224
- else:
225
- formatted += "📈 Results: Check workflow details for docking data\n"
226
-
227
- return formatted
228
- else:
229
- # Failed calculation
230
- return f"❌ Docking calculation failed\n🔖 UUID: {uuid}\n📋 Status: {status}\n💬 Check workflow details for more information"
231
- else:
232
- # Non-blocking mode
233
- formatted = f"📋 Docking calculation '{name}' submitted!\n"
234
- formatted += f"🔖 Workflow UUID: {uuid}\n"
235
- formatted += f"⏳ Status: Running...\n"
236
- formatted += f"💡 Use rowan_workflow_management to check status\n\n"
237
-
238
- formatted += f"Docking Details:\n"
239
- formatted += f"🧬 Ligand: {initial_molecule}\n"
240
- formatted += f"🎯 Target: {target_uuid or target[:50] + '...' if target and len(target) > 50 else target}\n"
241
- formatted += f"📍 Pocket: center={pocket[0]}, size={pocket[1]}\n"
242
- formatted += f"⚙️ Settings: csearch={do_csearch}, optimize={do_optimization}, refine={do_pose_refinement}\n"
243
-
244
- if conformers:
245
- formatted += f"🔬 Pre-optimized conformers: {len(conformers)}\n"
246
-
247
- return formatted
197
+ return result
248
198
 
249
199
  except Exception as e:
250
200
  logger.error(f"Error in rowan_docking: {str(e)}")
251
- return f"Docking calculation failed: {str(e)}"
201
+ return f"Docking calculation failed: {str(e)}"
252
202
 
253
203
  def rowan_docking_pdb_id(
254
204
  name: str,
@@ -297,7 +247,7 @@ def rowan_docking_pdb_id(
297
247
  else:
298
248
  ligand_param = f" smiles={smiles},\n"
299
249
 
300
- return (f"PDB {pdb_id} found in RCSB database!\n\n"
250
+ return (f"PDB {pdb_id} found in RCSB database!\n\n"
301
251
  f"To perform docking with this protein:\n\n"
302
252
  f"1. Go to https://labs.rowansci.com\n"
303
253
  f"2. Upload the PDB file for {pdb_id}\n"
@@ -329,11 +279,11 @@ def test_rowan_docking():
329
279
  pocket=((0.0, 0.0, 0.0), (20.0, 20.0, 20.0)),
330
280
  blocking=False
331
281
  )
332
- print("Docking test result:")
282
+ print("Docking test result:")
333
283
  print(result)
334
284
  return True
335
285
  except Exception as e:
336
- print(f"Docking test failed: {e}")
286
+ print(f"Docking test failed: {e}")
337
287
  return False
338
288
 
339
289
  if __name__ == "__main__":
@@ -22,10 +22,7 @@ except ImportError:
22
22
  logging.basicConfig(level=logging.INFO)
23
23
  logger = logging.getLogger(__name__)
24
24
 
25
- # Setup API key
26
- api_key = os.getenv("ROWAN_API_KEY")
27
- if api_key and rowan:
28
- rowan.api_key = api_key
25
+
29
26
 
30
27
  def log_rowan_api_call(workflow_type: str, **kwargs):
31
28
  """Log Rowan API calls with detailed parameters."""
@@ -10,14 +10,7 @@ from typing import Optional
10
10
  import logging
11
11
  logger = logging.getLogger(__name__)
12
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")
13
+
21
14
 
22
15
  def rowan_folder_management(
23
16
  action: str,
@@ -22,10 +22,7 @@ except ImportError:
22
22
  logging.basicConfig(level=logging.INFO)
23
23
  logger = logging.getLogger(__name__)
24
24
 
25
- # Setup API key
26
- api_key = os.getenv("ROWAN_API_KEY")
27
- if api_key and rowan:
28
- rowan.api_key = api_key
25
+
29
26
 
30
27
  def log_rowan_api_call(workflow_type: str, **kwargs):
31
28
  """Log Rowan API calls with detailed parameters."""
@@ -10,14 +10,7 @@ from typing import Optional
10
10
  import logging
11
11
  logger = logging.getLogger(__name__)
12
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")
13
+
21
14
 
22
15
  def log_rowan_api_call(workflow_type: str, **kwargs):
23
16
  """Log Rowan API calls and let Rowan handle its own errors."""
@@ -15,10 +15,7 @@ except ImportError:
15
15
  # Setup logging
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
- # Setup API key
19
- api_key = os.getenv("ROWAN_API_KEY")
20
- if rowan and api_key:
21
- rowan.api_key = api_key
18
+
22
19
 
23
20
  def log_rowan_api_call(workflow_type: str, **kwargs):
24
21
  """Log Rowan API calls with detailed parameters."""
@@ -10,14 +10,7 @@ from typing import Optional
10
10
  import logging
11
11
  logger = logging.getLogger(__name__)
12
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")
13
+
21
14
 
22
15
  def log_rowan_api_call(workflow_type: str, **kwargs):
23
16
  """Log Rowan API calls and let Rowan handle its own errors."""
@@ -15,10 +15,7 @@ except ImportError:
15
15
  # Setup logging
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
- # Setup API key
19
- api_key = os.getenv("ROWAN_API_KEY")
20
- if rowan and api_key:
21
- rowan.api_key = api_key
18
+
22
19
 
23
20
  def lookup_molecule_smiles(molecule_name: str) -> str:
24
21
  """Look up canonical SMILES for common molecule names."""
@@ -287,7 +284,7 @@ def rowan_redox_potential(
287
284
  formatted += f" Job UUID: {result.get('uuid', 'N/A')}\n"
288
285
  formatted += f" Status: {status}\n"
289
286
  formatted += f"⚙ Mode: {mode_lower.title()}\n"
290
- formatted += f"💧 Solvent: Acetonitrile\n"
287
+ formatted += f"Solvent: Acetonitrile\n"
291
288
 
292
289
  # Show which potentials were calculated
293
290
  calc_types = []