gfp-mcp 0.2.4__tar.gz → 0.3.3__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.
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/PKG-INFO +59 -64
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/README.md +55 -63
- {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/__init__.py +10 -8
- {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/client.py +0 -14
- gfp_mcp-0.3.3/gfp_mcp/config.py +161 -0
- gfp_mcp-0.3.3/gfp_mcp/render.py +139 -0
- gfp_mcp-0.3.3/gfp_mcp/samples.py +206 -0
- gfp_mcp-0.3.3/gfp_mcp/server.py +235 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/__init__.py +134 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/base.py +235 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/bbox.py +115 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/build.py +159 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/cells.py +103 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/connectivity.py +70 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/drc.py +379 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/freeze.py +82 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/lvs.py +86 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/pdk.py +47 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/port.py +82 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/project.py +160 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/samples.py +215 -0
- gfp_mcp-0.3.3/gfp_mcp/tools/simulation.py +153 -0
- gfp_mcp-0.3.3/gfp_mcp/utils.py +55 -0
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/gfp_mcp.egg-info/PKG-INFO +59 -64
- gfp_mcp-0.3.3/gfp_mcp.egg-info/SOURCES.txt +45 -0
- gfp_mcp-0.3.3/gfp_mcp.egg-info/entry_points.txt +2 -0
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/gfp_mcp.egg-info/requires.txt +4 -0
- gfp_mcp-0.3.3/gfp_mcp.egg-info/top_level.txt +1 -0
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/pyproject.toml +7 -3
- gfp_mcp-0.3.3/tests/test_gfp_phase4.py +308 -0
- gfp_mcp-0.3.3/tests/test_gfp_server.py +331 -0
- gfp_mcp-0.3.3/tests/test_gfp_tool_handlers.py +594 -0
- gfp_mcp-0.3.3/tests/test_gfp_tools_base.py +313 -0
- gfp_mcp-0.3.3/tests/test_gfp_tools_init.py +166 -0
- gfp_mcp-0.3.3/tests/test_gfp_utils.py +83 -0
- gfp_mcp-0.3.3/tests/test_mcp_config.py +208 -0
- gfp_mcp-0.2.4/tests/test_mcp_mappings.py → gfp_mcp-0.3.3/tests/test_mcp_handlers.py +319 -127
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/tests/test_mcp_integration.py +103 -91
- gfp_mcp-0.3.3/tests/test_mcp_render.py +299 -0
- gfp_mcp-0.3.3/tests/test_mcp_samples.py +491 -0
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/tests/test_mcp_tools.py +65 -61
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/tests/test_registry.py +1 -1
- gfp_mcp-0.2.4/gfp_mcp.egg-info/SOURCES.txt +0 -21
- gfp_mcp-0.2.4/gfp_mcp.egg-info/entry_points.txt +0 -2
- gfp_mcp-0.2.4/gfp_mcp.egg-info/top_level.txt +0 -1
- gfp_mcp-0.2.4/mcp_standalone/config.py +0 -50
- gfp_mcp-0.2.4/mcp_standalone/mappings.py +0 -565
- gfp_mcp-0.2.4/mcp_standalone/server.py +0 -282
- gfp_mcp-0.2.4/mcp_standalone/tools.py +0 -466
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/LICENSE +0 -0
- {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/registry.py +0 -0
- {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/resources.py +0 -0
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/gfp_mcp.egg-info/dependency_links.txt +0 -0
- {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gfp-mcp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Model Context Protocol (MCP) server for GDSFactory+ photonic IC design
|
|
5
5
|
Author: GDSFactory+ Team
|
|
6
6
|
License: MIT
|
|
@@ -27,7 +27,10 @@ License-File: LICENSE
|
|
|
27
27
|
Requires-Dist: mcp>=1.7.1
|
|
28
28
|
Requires-Dist: httpx>=0.25.0
|
|
29
29
|
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.11"
|
|
30
|
+
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
30
31
|
Requires-Dist: psutil>=5.9.0
|
|
32
|
+
Provides-Extra: render
|
|
33
|
+
Requires-Dist: klayout>=0.28.0; extra == "render"
|
|
31
34
|
Provides-Extra: dev
|
|
32
35
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
33
36
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
@@ -41,7 +44,6 @@ Dynamic: license-file
|
|
|
41
44
|
|
|
42
45
|
[](https://pypi.org/project/gfp-mcp/)
|
|
43
46
|
[](https://pypi.org/project/gfp-mcp/)
|
|
44
|
-
[](https://github.com/doplaydo/gfp-mcp/actions)
|
|
45
47
|
[](https://opensource.org/licenses/MIT)
|
|
46
48
|
|
|
47
49
|
Model Context Protocol (MCP) server for GDSFactory+ that enables AI assistants like Claude to design and build photonic integrated circuits.
|
|
@@ -50,88 +52,71 @@ Model Context Protocol (MCP) server for GDSFactory+ that enables AI assistants l
|
|
|
50
52
|
|
|
51
53
|
This MCP server connects AI assistants to [GDSFactory+](https://gdsfactory.com), allowing you to design photonic ICs through natural language. Build components, run verification checks, and manage multiple projects directly from Claude Code or Claude Desktop.
|
|
52
54
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
### 1. Install Prerequisites
|
|
55
|
+
## Prerequisites
|
|
56
56
|
|
|
57
57
|
- Python 3.10 or higher
|
|
58
58
|
- VSCode with the [GDSFactory+ extension](https://marketplace.visualstudio.com/items?itemName=gdsfactory.gdsfactoryplus) installed
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
## Installation
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
Choose your AI assistant below and follow the instructions.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
### 1. Cursor
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
uv tool install gfp-mcp
|
|
68
|
-
```
|
|
66
|
+
**One-click install:**
|
|
69
67
|
|
|
70
|
-
|
|
71
|
-
<summary>Ephemeral approach</summary>
|
|
68
|
+
[](cursor://anysphere.cursor-deeplink/mcp/install?name=gdsfactoryplus&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnZnAtbWNwIiwiZ2ZwLW1jcC1zZXJ2ZSJdfQ%3D%3D)
|
|
72
69
|
|
|
73
|
-
|
|
70
|
+
**Manual setup:**
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
uvx --from gfp-mcp gfp-mcp-serve
|
|
77
|
-
```
|
|
78
|
-
</details>
|
|
79
|
-
|
|
80
|
-
<details>
|
|
81
|
-
<summary><strong>Alternative: pip install</strong></summary>
|
|
72
|
+
Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for global access):
|
|
82
73
|
|
|
83
|
-
```
|
|
84
|
-
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"gdsfactoryplus": {
|
|
78
|
+
"command": "uvx",
|
|
79
|
+
"args": ["--from", "gfp-mcp", "gfp-mcp-serve"]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
85
83
|
```
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
### 2. Claude Code
|
|
88
86
|
|
|
89
|
-
|
|
87
|
+
Run the following command:
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
```bash
|
|
90
|
+
claude mcp add gdsfactoryplus -- uvx --from gfp-mcp gfp-mcp-serve
|
|
91
|
+
```
|
|
93
92
|
|
|
94
|
-
|
|
93
|
+
Or add to `.claude/settings.json` manually:
|
|
95
94
|
|
|
96
95
|
```json
|
|
97
96
|
{
|
|
98
97
|
"mcpServers": {
|
|
99
98
|
"gdsfactoryplus": {
|
|
100
|
-
"command": "
|
|
101
|
-
"args": []
|
|
102
|
-
"env": {
|
|
103
|
-
"GFP_API_URL": "http://localhost:8787"
|
|
104
|
-
}
|
|
99
|
+
"command": "uvx",
|
|
100
|
+
"args": ["--from", "gfp-mcp", "gfp-mcp-serve"]
|
|
105
101
|
}
|
|
106
102
|
}
|
|
107
103
|
}
|
|
108
104
|
```
|
|
109
105
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
claude mcp add gdsfactoryplus -- gfp-mcp-serve
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
</details>
|
|
117
|
-
|
|
118
|
-
<details>
|
|
119
|
-
<summary><strong>Claude Desktop</strong></summary>
|
|
106
|
+
### 3. Claude Desktop
|
|
120
107
|
|
|
121
108
|
Add to your config file:
|
|
122
109
|
|
|
123
|
-
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
124
|
-
|
|
125
|
-
**
|
|
126
|
-
|
|
127
|
-
**Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
110
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
111
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
112
|
+
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
128
113
|
|
|
129
114
|
```json
|
|
130
115
|
{
|
|
131
116
|
"mcpServers": {
|
|
132
117
|
"gdsfactoryplus": {
|
|
133
|
-
"command": "
|
|
134
|
-
"args": []
|
|
118
|
+
"command": "uvx",
|
|
119
|
+
"args": ["--from", "gfp-mcp", "gfp-mcp-serve"]
|
|
135
120
|
}
|
|
136
121
|
}
|
|
137
122
|
}
|
|
@@ -139,16 +124,21 @@ Add to your config file:
|
|
|
139
124
|
|
|
140
125
|
Restart Claude Desktop after adding the configuration.
|
|
141
126
|
|
|
142
|
-
|
|
127
|
+
### 4. Other MCP Clients
|
|
143
128
|
|
|
144
|
-
|
|
145
|
-
|
|
129
|
+
Install `gfp-mcp` and run the server:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
uvx --from gfp-mcp gfp-mcp-serve
|
|
133
|
+
```
|
|
146
134
|
|
|
147
|
-
|
|
135
|
+
Or install globally first, then reference `gfp-mcp-serve` in your client's MCP configuration:
|
|
148
136
|
|
|
149
|
-
|
|
137
|
+
```bash
|
|
138
|
+
uv tool install gfp-mcp
|
|
139
|
+
```
|
|
150
140
|
|
|
151
|
-
|
|
141
|
+
## Start Designing
|
|
152
142
|
|
|
153
143
|
The MCP server automatically discovers running GDSFactory+ servers via the registry (`~/.gdsfactory/server-registry.json`). On startup, it will log all discovered projects.
|
|
154
144
|
|
|
@@ -162,14 +152,19 @@ Try these commands with your AI assistant:
|
|
|
162
152
|
|
|
163
153
|
## Available Tools
|
|
164
154
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
155
|
+
| Tool | Description |
|
|
156
|
+
|------|-------------|
|
|
157
|
+
| **list_projects** | List all running GDSFactory+ server instances |
|
|
158
|
+
| **get_project_info** | Get detailed information about a specific project |
|
|
159
|
+
| **build_cells** | Build one or more GDS cells by name (pass a list, can be single-item) |
|
|
160
|
+
| **list_cells** | List all available photonic components |
|
|
161
|
+
| **get_cell_info** | Get detailed component metadata |
|
|
162
|
+
| **check_drc** | Run Design Rule Check verification with structured violation reports |
|
|
163
|
+
| **check_connectivity** | Run connectivity verification |
|
|
164
|
+
| **check_lvs** | Run Layout vs. Schematic verification |
|
|
165
|
+
| **simulate_component** | Run SAX circuit simulations with custom parameters |
|
|
166
|
+
| **list_samples** | List available sample files from GDSFactory+ General PDK projects |
|
|
167
|
+
| **get_sample_file** | Get the content of a specific sample file from a project |
|
|
173
168
|
|
|
174
169
|
## Multi-Project Support
|
|
175
170
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/gfp-mcp/)
|
|
4
4
|
[](https://pypi.org/project/gfp-mcp/)
|
|
5
|
-
[](https://github.com/doplaydo/gfp-mcp/actions)
|
|
6
5
|
[](https://opensource.org/licenses/MIT)
|
|
7
6
|
|
|
8
7
|
Model Context Protocol (MCP) server for GDSFactory+ that enables AI assistants like Claude to design and build photonic integrated circuits.
|
|
@@ -11,88 +10,71 @@ Model Context Protocol (MCP) server for GDSFactory+ that enables AI assistants l
|
|
|
11
10
|
|
|
12
11
|
This MCP server connects AI assistants to [GDSFactory+](https://gdsfactory.com), allowing you to design photonic ICs through natural language. Build components, run verification checks, and manage multiple projects directly from Claude Code or Claude Desktop.
|
|
13
12
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
### 1. Install Prerequisites
|
|
13
|
+
## Prerequisites
|
|
17
14
|
|
|
18
15
|
- Python 3.10 or higher
|
|
19
16
|
- VSCode with the [GDSFactory+ extension](https://marketplace.visualstudio.com/items?itemName=gdsfactory.gdsfactoryplus) installed
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
## Installation
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
Choose your AI assistant below and follow the instructions.
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
### 1. Cursor
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
uv tool install gfp-mcp
|
|
29
|
-
```
|
|
24
|
+
**One-click install:**
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
<summary>Ephemeral approach</summary>
|
|
26
|
+
[](cursor://anysphere.cursor-deeplink/mcp/install?name=gdsfactoryplus&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnZnAtbWNwIiwiZ2ZwLW1jcC1zZXJ2ZSJdfQ%3D%3D)
|
|
33
27
|
|
|
34
|
-
|
|
28
|
+
**Manual setup:**
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
uvx --from gfp-mcp gfp-mcp-serve
|
|
38
|
-
```
|
|
39
|
-
</details>
|
|
40
|
-
|
|
41
|
-
<details>
|
|
42
|
-
<summary><strong>Alternative: pip install</strong></summary>
|
|
30
|
+
Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for global access):
|
|
43
31
|
|
|
44
|
-
```
|
|
45
|
-
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"gdsfactoryplus": {
|
|
36
|
+
"command": "uvx",
|
|
37
|
+
"args": ["--from", "gfp-mcp", "gfp-mcp-serve"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
46
41
|
```
|
|
47
42
|
|
|
48
|
-
|
|
43
|
+
### 2. Claude Code
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
Run the following command:
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
```bash
|
|
48
|
+
claude mcp add gdsfactoryplus -- uvx --from gfp-mcp gfp-mcp-serve
|
|
49
|
+
```
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
Or add to `.claude/settings.json` manually:
|
|
56
52
|
|
|
57
53
|
```json
|
|
58
54
|
{
|
|
59
55
|
"mcpServers": {
|
|
60
56
|
"gdsfactoryplus": {
|
|
61
|
-
"command": "
|
|
62
|
-
"args": []
|
|
63
|
-
"env": {
|
|
64
|
-
"GFP_API_URL": "http://localhost:8787"
|
|
65
|
-
}
|
|
57
|
+
"command": "uvx",
|
|
58
|
+
"args": ["--from", "gfp-mcp", "gfp-mcp-serve"]
|
|
66
59
|
}
|
|
67
60
|
}
|
|
68
61
|
}
|
|
69
62
|
```
|
|
70
63
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
claude mcp add gdsfactoryplus -- gfp-mcp-serve
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
</details>
|
|
78
|
-
|
|
79
|
-
<details>
|
|
80
|
-
<summary><strong>Claude Desktop</strong></summary>
|
|
64
|
+
### 3. Claude Desktop
|
|
81
65
|
|
|
82
66
|
Add to your config file:
|
|
83
67
|
|
|
84
|
-
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
85
|
-
|
|
86
|
-
**
|
|
87
|
-
|
|
88
|
-
**Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
68
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
69
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
70
|
+
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
89
71
|
|
|
90
72
|
```json
|
|
91
73
|
{
|
|
92
74
|
"mcpServers": {
|
|
93
75
|
"gdsfactoryplus": {
|
|
94
|
-
"command": "
|
|
95
|
-
"args": []
|
|
76
|
+
"command": "uvx",
|
|
77
|
+
"args": ["--from", "gfp-mcp", "gfp-mcp-serve"]
|
|
96
78
|
}
|
|
97
79
|
}
|
|
98
80
|
}
|
|
@@ -100,16 +82,21 @@ Add to your config file:
|
|
|
100
82
|
|
|
101
83
|
Restart Claude Desktop after adding the configuration.
|
|
102
84
|
|
|
103
|
-
|
|
85
|
+
### 4. Other MCP Clients
|
|
104
86
|
|
|
105
|
-
|
|
106
|
-
|
|
87
|
+
Install `gfp-mcp` and run the server:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
uvx --from gfp-mcp gfp-mcp-serve
|
|
91
|
+
```
|
|
107
92
|
|
|
108
|
-
|
|
93
|
+
Or install globally first, then reference `gfp-mcp-serve` in your client's MCP configuration:
|
|
109
94
|
|
|
110
|
-
|
|
95
|
+
```bash
|
|
96
|
+
uv tool install gfp-mcp
|
|
97
|
+
```
|
|
111
98
|
|
|
112
|
-
|
|
99
|
+
## Start Designing
|
|
113
100
|
|
|
114
101
|
The MCP server automatically discovers running GDSFactory+ servers via the registry (`~/.gdsfactory/server-registry.json`). On startup, it will log all discovered projects.
|
|
115
102
|
|
|
@@ -123,14 +110,19 @@ Try these commands with your AI assistant:
|
|
|
123
110
|
|
|
124
111
|
## Available Tools
|
|
125
112
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
113
|
+
| Tool | Description |
|
|
114
|
+
|------|-------------|
|
|
115
|
+
| **list_projects** | List all running GDSFactory+ server instances |
|
|
116
|
+
| **get_project_info** | Get detailed information about a specific project |
|
|
117
|
+
| **build_cells** | Build one or more GDS cells by name (pass a list, can be single-item) |
|
|
118
|
+
| **list_cells** | List all available photonic components |
|
|
119
|
+
| **get_cell_info** | Get detailed component metadata |
|
|
120
|
+
| **check_drc** | Run Design Rule Check verification with structured violation reports |
|
|
121
|
+
| **check_connectivity** | Run connectivity verification |
|
|
122
|
+
| **check_lvs** | Run Layout vs. Schematic verification |
|
|
123
|
+
| **simulate_component** | Run SAX circuit simulations with custom parameters |
|
|
124
|
+
| **list_samples** | List available sample files from GDSFactory+ General PDK projects |
|
|
125
|
+
| **get_sample_file** | Get the content of a specific sample file from a project |
|
|
134
126
|
|
|
135
127
|
## Multi-Project Support
|
|
136
128
|
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
"""MCP
|
|
1
|
+
"""GDSFactory+ MCP Server.
|
|
2
2
|
|
|
3
3
|
This package provides a Model Context Protocol (MCP) server that exposes
|
|
4
4
|
GDSFactory+ operations as tools for AI assistants. The server uses STDIO
|
|
5
5
|
transport and proxies requests to the FastAPI backend.
|
|
6
6
|
|
|
7
7
|
Architecture:
|
|
8
|
-
-
|
|
8
|
+
- Tool handlers in gfp_mcp/tools/ with co-located definitions and transformers
|
|
9
9
|
- STDIO transport for universal compatibility
|
|
10
|
-
- HTTP proxy to FastAPI backend
|
|
10
|
+
- HTTP proxy to FastAPI backend via client.py
|
|
11
|
+
- Multi-project routing via server registry
|
|
11
12
|
- Zero changes to existing FastAPI server
|
|
12
|
-
- No database conflicts (only FastAPI touches SQLite)
|
|
13
13
|
|
|
14
14
|
Usage:
|
|
15
|
-
from
|
|
15
|
+
from gfp_mcp import main
|
|
16
16
|
main()
|
|
17
17
|
|
|
18
18
|
Or via CLI:
|
|
19
|
-
gfp
|
|
19
|
+
gfp-mcp-serve
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
22
|
from __future__ import annotations
|
|
@@ -25,18 +25,20 @@ from .client import FastAPIClient
|
|
|
25
25
|
from .config import MCPConfig
|
|
26
26
|
from .resources import get_all_resources, get_resource_content
|
|
27
27
|
from .server import create_server, main, run_server
|
|
28
|
-
from .tools import get_all_tools, get_tool_by_name
|
|
28
|
+
from .tools import get_all_tools, get_handler, get_tool_by_name
|
|
29
29
|
|
|
30
30
|
__all__ = [
|
|
31
|
+
"__version__",
|
|
31
32
|
"FastAPIClient",
|
|
32
33
|
"MCPConfig",
|
|
33
34
|
"create_server",
|
|
34
35
|
"main",
|
|
35
36
|
"run_server",
|
|
36
37
|
"get_all_tools",
|
|
38
|
+
"get_handler",
|
|
37
39
|
"get_tool_by_name",
|
|
38
40
|
"get_all_resources",
|
|
39
41
|
"get_resource_content",
|
|
40
42
|
]
|
|
41
43
|
|
|
42
|
-
__version__ = "0.
|
|
44
|
+
__version__ = "0.3.3"
|
|
@@ -294,17 +294,3 @@ class FastAPIClient:
|
|
|
294
294
|
}
|
|
295
295
|
for server in servers
|
|
296
296
|
]
|
|
297
|
-
|
|
298
|
-
async def get_project_info(self, project: str) -> dict[str, Any]:
|
|
299
|
-
"""Get detailed information about a specific project.
|
|
300
|
-
|
|
301
|
-
Args:
|
|
302
|
-
project: Project name or path
|
|
303
|
-
|
|
304
|
-
Returns:
|
|
305
|
-
Project information from the server's /info endpoint
|
|
306
|
-
|
|
307
|
-
Raises:
|
|
308
|
-
ValueError: If project not found
|
|
309
|
-
"""
|
|
310
|
-
return await self.request("GET", "/info", project=project)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""Configuration management for MCP standalone server."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Final
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import tomllib # Python 3.11+
|
|
11
|
+
except ImportError:
|
|
12
|
+
import tomli as tomllib # type: ignore[import-not-found]
|
|
13
|
+
|
|
14
|
+
__all__ = ["MCPConfig", "get_gfp_api_key", "set_gfp_api_key"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MCPConfig:
|
|
18
|
+
"""Configuration for MCP standalone server.
|
|
19
|
+
|
|
20
|
+
Manages environment variables and default settings for the MCP server
|
|
21
|
+
that proxies requests to the FastAPI backend.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
API_URL: Final[str | None] = os.getenv("GFP_API_URL")
|
|
25
|
+
|
|
26
|
+
TIMEOUT: Final[int] = int(os.getenv("GFP_MCP_TIMEOUT", "300"))
|
|
27
|
+
|
|
28
|
+
DEBUG: Final[bool] = os.getenv("GFP_MCP_DEBUG", "false").lower() in (
|
|
29
|
+
"true",
|
|
30
|
+
"1",
|
|
31
|
+
"yes",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
REGISTRY_API_URL: Final[str] = "https://registry.gdsfactory.com"
|
|
35
|
+
|
|
36
|
+
MAX_RETRIES: Final[int] = 3
|
|
37
|
+
RETRY_BACKOFF: Final[float] = 0.5 # Initial backoff in seconds
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def get_api_url(cls, override: str | None = None) -> str | None:
|
|
41
|
+
"""Get the FastAPI base URL.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
override: Optional URL to override the environment variable
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
The API base URL or None if not configured
|
|
48
|
+
"""
|
|
49
|
+
return override or cls.API_URL
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def get_timeout(cls) -> int:
|
|
53
|
+
"""Get the timeout for tool calls.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Timeout in seconds
|
|
57
|
+
"""
|
|
58
|
+
return cls.TIMEOUT
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _read_api_key_from_toml(file_path: Path) -> str | None:
|
|
62
|
+
"""Read the API key from a TOML configuration file.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
file_path: Path to the TOML file.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
The API key string, or None if not found or file doesn't exist.
|
|
69
|
+
"""
|
|
70
|
+
if not file_path.exists():
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
with open(file_path, "rb") as f:
|
|
75
|
+
config = tomllib.load(f)
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
config.get("tool", {}).get("gdsfactoryplus", {}).get("api", {}).get("key")
|
|
79
|
+
)
|
|
80
|
+
except Exception:
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def get_gfp_api_key() -> str | None:
|
|
85
|
+
"""Retrieve the GFP API key from environment variables or config files.
|
|
86
|
+
|
|
87
|
+
Checks sources in priority order:
|
|
88
|
+
1. GFP_API_KEY environment variable
|
|
89
|
+
2. ~/.gdsfactory/gdsfactoryplus.toml
|
|
90
|
+
3. ./pyproject.toml
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
The API key string, or None if not found.
|
|
94
|
+
"""
|
|
95
|
+
# 1. Check environment variable (highest priority)
|
|
96
|
+
api_key = os.environ.get("GFP_API_KEY")
|
|
97
|
+
if api_key:
|
|
98
|
+
return api_key
|
|
99
|
+
|
|
100
|
+
# 2. Check global config file: ~/.gdsfactory/gdsfactoryplus.toml
|
|
101
|
+
global_config_path = Path.home() / ".gdsfactory" / "gdsfactoryplus.toml"
|
|
102
|
+
api_key = _read_api_key_from_toml(global_config_path)
|
|
103
|
+
if api_key:
|
|
104
|
+
return api_key
|
|
105
|
+
|
|
106
|
+
# 3. Check local project config: ./pyproject.toml
|
|
107
|
+
local_config_path = Path.cwd() / "pyproject.toml"
|
|
108
|
+
api_key = _read_api_key_from_toml(local_config_path)
|
|
109
|
+
if api_key:
|
|
110
|
+
return api_key
|
|
111
|
+
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def set_gfp_api_key(api_key: str) -> None:
|
|
116
|
+
"""Save the GFP API key to the global config file.
|
|
117
|
+
|
|
118
|
+
Writes to: ~/.gdsfactory/gdsfactoryplus.toml
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
api_key: The API key to save.
|
|
122
|
+
|
|
123
|
+
Raises:
|
|
124
|
+
ValueError: If api_key is empty or None.
|
|
125
|
+
"""
|
|
126
|
+
if not api_key:
|
|
127
|
+
raise ValueError("API key is required")
|
|
128
|
+
|
|
129
|
+
config_dir = Path.home() / ".gdsfactory"
|
|
130
|
+
config_path = config_dir / "gdsfactoryplus.toml"
|
|
131
|
+
|
|
132
|
+
# Create directory if it doesn't exist
|
|
133
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
134
|
+
|
|
135
|
+
# Load existing config or create new one
|
|
136
|
+
config: dict = {}
|
|
137
|
+
if config_path.exists():
|
|
138
|
+
with open(config_path, "rb") as f:
|
|
139
|
+
config = tomllib.load(f)
|
|
140
|
+
|
|
141
|
+
# Set the API key in the nested structure
|
|
142
|
+
if "tool" not in config:
|
|
143
|
+
config["tool"] = {}
|
|
144
|
+
if "gdsfactoryplus" not in config["tool"]:
|
|
145
|
+
config["tool"]["gdsfactoryplus"] = {}
|
|
146
|
+
if "api" not in config["tool"]["gdsfactoryplus"]:
|
|
147
|
+
config["tool"]["gdsfactoryplus"]["api"] = {}
|
|
148
|
+
|
|
149
|
+
config["tool"]["gdsfactoryplus"]["api"]["key"] = api_key
|
|
150
|
+
|
|
151
|
+
# Write back to file using tomli_w if available, otherwise manual formatting
|
|
152
|
+
try:
|
|
153
|
+
import tomli_w
|
|
154
|
+
|
|
155
|
+
with open(config_path, "wb") as f:
|
|
156
|
+
tomli_w.dump(config, f)
|
|
157
|
+
except ImportError:
|
|
158
|
+
# Fallback: write TOML manually for this simple structure
|
|
159
|
+
with open(config_path, "w") as f:
|
|
160
|
+
f.write("[tool.gdsfactoryplus.api]\n")
|
|
161
|
+
f.write(f'key = "{api_key}"\n')
|