gnnepcsaft-mcp-server 0.1.0__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 gnnepcsaft-mcp-server might be problematic. Click here for more details.

@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.3
2
+ Name: gnnepcsaft-mcp-server
3
+ Version: 0.1.0
4
+ Summary: Model Context Protocol server for GNNePCSAFT tools
5
+ License: GNU General Public License v3.0
6
+ Author: wildsonbbl
7
+ Author-email: wil_bbl@hotmail.com
8
+ Requires-Python: >=3.10
9
+ Classifier: License :: Other/Proprietary License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: feos (>=0.8.0,<0.9.0)
16
+ Requires-Dist: gnnepcsaft (>=0.2.2,<0.3.0)
17
+ Requires-Dist: mcp (>=1.6.0,<2.0.0)
18
+ Requires-Dist: numpy (>=2.2.4,<3.0.0)
19
+ Requires-Dist: onnxruntime (>=1.21.0,<2.0.0)
20
+ Requires-Dist: rdkit (>=2024.9.6,<2025.0.0)
21
+ Requires-Dist: si-units (>=0.11.0,<0.12.0)
22
+ Description-Content-Type: text/markdown
23
+
24
+ # GNNEPCSAFT MCP Server
25
+
26
+ ## Overview
27
+
28
+ This is the Model Context Protocol ([MCP](https://modelcontextprotocol.io/introduction)) server implementation for [GNNePCSAFT](https://github.com/wildsonbbl/gnnepcsaft) tools. The server handles communication and context management between models and clients using the MCP protocol.
29
+
30
+ ## Features
31
+
32
+ - Model context management
33
+ - Protocol handling for model communication
34
+ - Client request processing
35
+ - Context state synchronization
36
+
37
+ ## Installation
38
+
39
+ You're gonna need [pipx](https://pipx.pypa.io/latest/installation/) for this.
40
+
41
+ ```bash
42
+ pipx install gnnepcsaft-mcp-server
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ stdio command to start the MCP server:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "gnnepcsaft": {
53
+ "command": "gnnepcsaftmcp",
54
+ "args": []
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ## License
61
+
62
+ GNU General Public License v3.0
63
+
@@ -0,0 +1,39 @@
1
+ # GNNEPCSAFT MCP Server
2
+
3
+ ## Overview
4
+
5
+ This is the Model Context Protocol ([MCP](https://modelcontextprotocol.io/introduction)) server implementation for [GNNePCSAFT](https://github.com/wildsonbbl/gnnepcsaft) tools. The server handles communication and context management between models and clients using the MCP protocol.
6
+
7
+ ## Features
8
+
9
+ - Model context management
10
+ - Protocol handling for model communication
11
+ - Client request processing
12
+ - Context state synchronization
13
+
14
+ ## Installation
15
+
16
+ You're gonna need [pipx](https://pipx.pypa.io/latest/installation/) for this.
17
+
18
+ ```bash
19
+ pipx install gnnepcsaft-mcp-server
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ stdio command to start the MCP server:
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "gnnepcsaft": {
30
+ "command": "gnnepcsaftmcp",
31
+ "args": []
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ## License
38
+
39
+ GNU General Public License v3.0
@@ -0,0 +1 @@
1
+ "GNNePCSAFT MCP Server"
@@ -0,0 +1,38 @@
1
+ "GNNePCSAFT MCP Server"
2
+
3
+ from typing import Any, Callable, List
4
+
5
+ from gnnepcsaft.data.rdkit_util import inchitosmiles, mw, smilestoinchi
6
+ from gnnepcsaft.epcsaft.epcsaft_feos import (
7
+ mix_den_feos,
8
+ mix_vp_feos,
9
+ pure_den_feos,
10
+ pure_h_lv_feos,
11
+ pure_vp_feos,
12
+ )
13
+ from mcp.server.fastmcp import FastMCP
14
+
15
+ from .utils import mixture_phase, prediction, pubchem_description, pure_phase
16
+
17
+ mcp = FastMCP("gnnepcsaft")
18
+ fn_list: List[Callable[..., Any]] = [
19
+ pure_vp_feos,
20
+ pure_den_feos,
21
+ mix_den_feos,
22
+ mix_vp_feos,
23
+ pure_phase,
24
+ mixture_phase,
25
+ pubchem_description,
26
+ mw,
27
+ smilestoinchi,
28
+ prediction,
29
+ inchitosmiles,
30
+ pure_h_lv_feos,
31
+ ]
32
+ for fn in fn_list:
33
+ mcp.add_tool(fn)
34
+
35
+
36
+ def run():
37
+ "run stdio"
38
+ mcp.run("stdio")
@@ -0,0 +1,136 @@
1
+ "Utils for MCP Server"
2
+
3
+ from json import loads
4
+ from pathlib import Path
5
+ from typing import List, Literal
6
+ from urllib.parse import quote
7
+ from urllib.request import HTTPError, urlopen
8
+
9
+ import numpy as np
10
+ import onnxruntime as ort
11
+ from gnnepcsaft.data.ogb_utils import smiles2graph
12
+ from gnnepcsaft.data.rdkit_util import assoc_number, smilestoinchi
13
+
14
+ file_dir = Path(__file__).parent
15
+ model_dir = file_dir / "models"
16
+ ort.set_default_logger_severity(3)
17
+
18
+ msigmae_onnx = ort.InferenceSession(model_dir / "msigmae_7.onnx")
19
+ assoc_onnx = ort.InferenceSession(model_dir / "assoc_8.onnx")
20
+
21
+
22
+ def prediction(
23
+ smiles: str,
24
+ ) -> List[float]:
25
+ """Predict ePC-SAFT parameters
26
+ `[m, sigma, epsilon/kB, kappa_ab, epsilon_ab/kB, dipole moment, na, nb]`
27
+
28
+ Args:
29
+ smiles (str): SMILES of the molecule.
30
+ """
31
+ lower_bounds = np.asarray([1.0, 1.9, 50.0, 0.0, 0.0, 0, 0, 0])
32
+ upper_bounds = np.asarray([25.0, 4.5, 550.0, 0.9, 5000.0, np.inf, np.inf, np.inf])
33
+
34
+ inchi = smilestoinchi(smiles)
35
+
36
+ graph = smiles2graph(smiles)
37
+ na, nb = assoc_number(inchi)
38
+ x, edge_index, edge_attr = (
39
+ graph["node_feat"],
40
+ graph["edge_index"],
41
+ graph["edge_feat"],
42
+ )
43
+
44
+ assoc = 10 ** (
45
+ assoc_onnx.run(
46
+ None,
47
+ {
48
+ "x": x,
49
+ "edge_index": edge_index,
50
+ "edge_attr": edge_attr,
51
+ },
52
+ )[0][0]
53
+ * np.asarray([-1.0, 1.0])
54
+ )
55
+ if na == 0 and nb == 0:
56
+ assoc *= 0
57
+ msigmae = msigmae_onnx.run(
58
+ None,
59
+ {
60
+ "x": x,
61
+ "edge_index": edge_index,
62
+ "edge_attr": edge_attr,
63
+ },
64
+ )[0][0]
65
+ munanb = np.asarray([0.0, na, nb])
66
+ pred = np.hstack([msigmae, assoc, munanb], dtype=np.float64)
67
+ np.clip(pred, lower_bounds, upper_bounds, out=pred)
68
+
69
+ return pred.tolist() # type: ignore
70
+
71
+
72
+ def pure_phase(
73
+ vapor_pressure: float, system_pressure: float
74
+ ) -> Literal["liquid", "vapor"]:
75
+ """
76
+ Given the vapor pressure and system pressure, return the phase of the molecule.
77
+ Both pressures must be in the same unit.
78
+
79
+ Args:
80
+ vapor_pressure (float): The calculated vapor pressure of the pure component.
81
+ system_pressure (float): The actual system pressure.
82
+
83
+ """
84
+ assert isinstance(vapor_pressure, (int, float)), "vapor_pressure must be a number"
85
+ assert isinstance(system_pressure, (int, float)), "system_pressure must be a number"
86
+ assert vapor_pressure > 0, "vapor_pressure must be positive"
87
+ assert system_pressure > 0, "system_pressure must be positive"
88
+
89
+ return "liquid" if vapor_pressure < system_pressure else "vapor"
90
+
91
+
92
+ def mixture_phase(
93
+ bubble_point: float,
94
+ dew_point: float,
95
+ system_pressure: float,
96
+ ) -> Literal["liquid", "vapor", "two-phase"]:
97
+ """
98
+ Given the bubble/dew point of the mixture and the system pressure,
99
+ return the phase of the mixture.
100
+ All pressures must be in the same unit.
101
+
102
+ Args:
103
+ bubble_point (float): The calculated bubble point of the mixture.
104
+ dew_point (float): The calculated dew point of the mixture.
105
+ system_pressure (float): The actual system pressure.
106
+ """
107
+ assert isinstance(bubble_point, (int, float)), "bubble_point must be a number"
108
+ assert isinstance(dew_point, (int, float)), "dew_point must be a number"
109
+ assert isinstance(system_pressure, (int, float)), "system_pressure must be a number"
110
+ assert bubble_point > 0, "bubble_point must be positive"
111
+ assert dew_point > 0, "dew_point must be positive"
112
+ assert system_pressure > 0, "system_pressure must be positive"
113
+ return (
114
+ "liquid"
115
+ if bubble_point < system_pressure
116
+ else ("two-phase" if dew_point <= system_pressure else "vapor")
117
+ )
118
+
119
+
120
+ def pubchem_description(inchi: str) -> str:
121
+ """
122
+ Look for information on PubChem for the InChI.
123
+
124
+ Args:
125
+ inchi (str): The InChI of the molecule.
126
+ """
127
+ url = (
128
+ "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/inchi/description/json?inchi="
129
+ + quote(inchi, safe="")
130
+ )
131
+ try:
132
+ with urlopen(url) as ans:
133
+ ans = loads(ans.read().decode("utf8").strip())
134
+ except (TypeError, HTTPError, ValueError):
135
+ ans = "no data available on this molecule in PubChem."
136
+ return ans
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "gnnepcsaft-mcp-server"
3
+ version = "0.1.0"
4
+ description = "Model Context Protocol server for GNNePCSAFT tools"
5
+ authors = [
6
+ {name = "wildsonbbl",email = "wil_bbl@hotmail.com"}
7
+ ]
8
+ license = {text = "GNU General Public License v3.0"}
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "numpy (>=2.2.4,<3.0.0)",
13
+ "onnxruntime (>=1.21.0,<2.0.0)",
14
+ "gnnepcsaft (>=0.2.2,<0.3.0)",
15
+ "mcp (>=1.6.0,<2.0.0)",
16
+ "rdkit (>=2024.9.6,<2025.0.0)",
17
+ "feos (>=0.8.0,<0.9.0)",
18
+ "si-units (>=0.11.0,<0.12.0)"
19
+ ]
20
+
21
+ [project.scripts]
22
+ gnnepcsaftmcp = 'gnnepcsaft_mcp_server.mcp_server:run'
23
+
24
+ [tool.poetry]
25
+ include = ["gnnepcsaft_mcp_server/models/assoc_8.onnx", "gnnepcsaft_mcp_server/models/assoc_8.onnx.data", "gnnepcsaft_mcp_server/models/msigmae_7.onnx", "gnnepcsaft_mcp_server/models/msigmae_7.onnx.data"]
26
+
27
+
28
+
29
+ [build-system]
30
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
31
+ build-backend = "poetry.core.masonry.api"