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.
Files changed (54) hide show
  1. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/PKG-INFO +59 -64
  2. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/README.md +55 -63
  3. {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/__init__.py +10 -8
  4. {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/client.py +0 -14
  5. gfp_mcp-0.3.3/gfp_mcp/config.py +161 -0
  6. gfp_mcp-0.3.3/gfp_mcp/render.py +139 -0
  7. gfp_mcp-0.3.3/gfp_mcp/samples.py +206 -0
  8. gfp_mcp-0.3.3/gfp_mcp/server.py +235 -0
  9. gfp_mcp-0.3.3/gfp_mcp/tools/__init__.py +134 -0
  10. gfp_mcp-0.3.3/gfp_mcp/tools/base.py +235 -0
  11. gfp_mcp-0.3.3/gfp_mcp/tools/bbox.py +115 -0
  12. gfp_mcp-0.3.3/gfp_mcp/tools/build.py +159 -0
  13. gfp_mcp-0.3.3/gfp_mcp/tools/cells.py +103 -0
  14. gfp_mcp-0.3.3/gfp_mcp/tools/connectivity.py +70 -0
  15. gfp_mcp-0.3.3/gfp_mcp/tools/drc.py +379 -0
  16. gfp_mcp-0.3.3/gfp_mcp/tools/freeze.py +82 -0
  17. gfp_mcp-0.3.3/gfp_mcp/tools/lvs.py +86 -0
  18. gfp_mcp-0.3.3/gfp_mcp/tools/pdk.py +47 -0
  19. gfp_mcp-0.3.3/gfp_mcp/tools/port.py +82 -0
  20. gfp_mcp-0.3.3/gfp_mcp/tools/project.py +160 -0
  21. gfp_mcp-0.3.3/gfp_mcp/tools/samples.py +215 -0
  22. gfp_mcp-0.3.3/gfp_mcp/tools/simulation.py +153 -0
  23. gfp_mcp-0.3.3/gfp_mcp/utils.py +55 -0
  24. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/gfp_mcp.egg-info/PKG-INFO +59 -64
  25. gfp_mcp-0.3.3/gfp_mcp.egg-info/SOURCES.txt +45 -0
  26. gfp_mcp-0.3.3/gfp_mcp.egg-info/entry_points.txt +2 -0
  27. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/gfp_mcp.egg-info/requires.txt +4 -0
  28. gfp_mcp-0.3.3/gfp_mcp.egg-info/top_level.txt +1 -0
  29. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/pyproject.toml +7 -3
  30. gfp_mcp-0.3.3/tests/test_gfp_phase4.py +308 -0
  31. gfp_mcp-0.3.3/tests/test_gfp_server.py +331 -0
  32. gfp_mcp-0.3.3/tests/test_gfp_tool_handlers.py +594 -0
  33. gfp_mcp-0.3.3/tests/test_gfp_tools_base.py +313 -0
  34. gfp_mcp-0.3.3/tests/test_gfp_tools_init.py +166 -0
  35. gfp_mcp-0.3.3/tests/test_gfp_utils.py +83 -0
  36. gfp_mcp-0.3.3/tests/test_mcp_config.py +208 -0
  37. gfp_mcp-0.2.4/tests/test_mcp_mappings.py → gfp_mcp-0.3.3/tests/test_mcp_handlers.py +319 -127
  38. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/tests/test_mcp_integration.py +103 -91
  39. gfp_mcp-0.3.3/tests/test_mcp_render.py +299 -0
  40. gfp_mcp-0.3.3/tests/test_mcp_samples.py +491 -0
  41. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/tests/test_mcp_tools.py +65 -61
  42. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/tests/test_registry.py +1 -1
  43. gfp_mcp-0.2.4/gfp_mcp.egg-info/SOURCES.txt +0 -21
  44. gfp_mcp-0.2.4/gfp_mcp.egg-info/entry_points.txt +0 -2
  45. gfp_mcp-0.2.4/gfp_mcp.egg-info/top_level.txt +0 -1
  46. gfp_mcp-0.2.4/mcp_standalone/config.py +0 -50
  47. gfp_mcp-0.2.4/mcp_standalone/mappings.py +0 -565
  48. gfp_mcp-0.2.4/mcp_standalone/server.py +0 -282
  49. gfp_mcp-0.2.4/mcp_standalone/tools.py +0 -466
  50. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/LICENSE +0 -0
  51. {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/registry.py +0 -0
  52. {gfp_mcp-0.2.4/mcp_standalone → gfp_mcp-0.3.3/gfp_mcp}/resources.py +0 -0
  53. {gfp_mcp-0.2.4 → gfp_mcp-0.3.3}/gfp_mcp.egg-info/dependency_links.txt +0 -0
  54. {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.2.4
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
  [![PyPI version](https://img.shields.io/pypi/v/gfp-mcp.svg)](https://pypi.org/project/gfp-mcp/)
43
46
  [![Python versions](https://img.shields.io/pypi/pyversions/gfp-mcp.svg)](https://pypi.org/project/gfp-mcp/)
44
- [![Tests](https://github.com/doplaydo/gfp-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/doplaydo/gfp-mcp/actions)
45
47
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
- ## Quick Start
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
- ### 2. Install the MCP Server
60
+ ## Installation
61
61
 
62
- **With uv (recommended):**
62
+ Choose your AI assistant below and follow the instructions.
63
63
 
64
- If you don't have `uv` installed, see the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).
64
+ ### 1. Cursor
65
65
 
66
- ```bash
67
- uv tool install gfp-mcp
68
- ```
66
+ **One-click install:**
69
67
 
70
- <details>
71
- <summary>Ephemeral approach</summary>
68
+ [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](cursor://anysphere.cursor-deeplink/mcp/install?name=gdsfactoryplus&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnZnAtbWNwIiwiZ2ZwLW1jcC1zZXJ2ZSJdfQ%3D%3D)
72
69
 
73
- Run without installing:
70
+ **Manual setup:**
74
71
 
75
- ```bash
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
- ```bash
84
- pip install gfp-mcp
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
- </details>
85
+ ### 2. Claude Code
88
86
 
89
- ### 3. Connect to Your AI Assistant
87
+ Run the following command:
90
88
 
91
- <details>
92
- <summary><strong>Claude Code</strong></summary>
89
+ ```bash
90
+ claude mcp add gdsfactoryplus -- uvx --from gfp-mcp gfp-mcp-serve
91
+ ```
93
92
 
94
- Add to `.claude/settings.json`:
93
+ Or add to `.claude/settings.json` manually:
95
94
 
96
95
  ```json
97
96
  {
98
97
  "mcpServers": {
99
98
  "gdsfactoryplus": {
100
- "command": "gfp-mcp-serve",
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
- Or use the CLI:
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
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
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": "gfp-mcp-serve",
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
- </details>
127
+ ### 4. Other MCP Clients
143
128
 
144
- <details>
145
- <summary><strong>Cursor</strong></summary>
129
+ Install `gfp-mcp` and run the server:
130
+
131
+ ```bash
132
+ uvx --from gfp-mcp gfp-mcp-serve
133
+ ```
146
134
 
147
- Coming soon. Follow the MCP integration instructions for Cursor when available.
135
+ Or install globally first, then reference `gfp-mcp-serve` in your client's MCP configuration:
148
136
 
149
- </details>
137
+ ```bash
138
+ uv tool install gfp-mcp
139
+ ```
150
140
 
151
- ### 4. Start Designing
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
- - **build_cells** - Build one or more GDS cells by name (pass a list, can be single-item)
166
- - **list_cells** - List all available photonic components
167
- - **get_cell_info** - Get detailed component metadata
168
- - **list_projects** - List all running GDSFactory+ server instances
169
- - **get_project_info** - Get detailed information about a specific project
170
- - **check_drc** - Run Design Rule Check verification (returns structured format with all violations including simplified location data for LLM-friendly troubleshooting)
171
- - **check_connectivity** - Run connectivity verification
172
- - **check_lvs** - Run Layout vs. Schematic verification
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
  [![PyPI version](https://img.shields.io/pypi/v/gfp-mcp.svg)](https://pypi.org/project/gfp-mcp/)
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/gfp-mcp.svg)](https://pypi.org/project/gfp-mcp/)
5
- [![Tests](https://github.com/doplaydo/gfp-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/doplaydo/gfp-mcp/actions)
6
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
- ## Quick Start
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
- ### 2. Install the MCP Server
18
+ ## Installation
22
19
 
23
- **With uv (recommended):**
20
+ Choose your AI assistant below and follow the instructions.
24
21
 
25
- If you don't have `uv` installed, see the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).
22
+ ### 1. Cursor
26
23
 
27
- ```bash
28
- uv tool install gfp-mcp
29
- ```
24
+ **One-click install:**
30
25
 
31
- <details>
32
- <summary>Ephemeral approach</summary>
26
+ [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](cursor://anysphere.cursor-deeplink/mcp/install?name=gdsfactoryplus&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJnZnAtbWNwIiwiZ2ZwLW1jcC1zZXJ2ZSJdfQ%3D%3D)
33
27
 
34
- Run without installing:
28
+ **Manual setup:**
35
29
 
36
- ```bash
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
- ```bash
45
- pip install gfp-mcp
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
- </details>
43
+ ### 2. Claude Code
49
44
 
50
- ### 3. Connect to Your AI Assistant
45
+ Run the following command:
51
46
 
52
- <details>
53
- <summary><strong>Claude Code</strong></summary>
47
+ ```bash
48
+ claude mcp add gdsfactoryplus -- uvx --from gfp-mcp gfp-mcp-serve
49
+ ```
54
50
 
55
- Add to `.claude/settings.json`:
51
+ Or add to `.claude/settings.json` manually:
56
52
 
57
53
  ```json
58
54
  {
59
55
  "mcpServers": {
60
56
  "gdsfactoryplus": {
61
- "command": "gfp-mcp-serve",
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
- Or use the CLI:
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
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
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": "gfp-mcp-serve",
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
- </details>
85
+ ### 4. Other MCP Clients
104
86
 
105
- <details>
106
- <summary><strong>Cursor</strong></summary>
87
+ Install `gfp-mcp` and run the server:
88
+
89
+ ```bash
90
+ uvx --from gfp-mcp gfp-mcp-serve
91
+ ```
107
92
 
108
- Coming soon. Follow the MCP integration instructions for Cursor when available.
93
+ Or install globally first, then reference `gfp-mcp-serve` in your client's MCP configuration:
109
94
 
110
- </details>
95
+ ```bash
96
+ uv tool install gfp-mcp
97
+ ```
111
98
 
112
- ### 4. Start Designing
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
- - **build_cells** - Build one or more GDS cells by name (pass a list, can be single-item)
127
- - **list_cells** - List all available photonic components
128
- - **get_cell_info** - Get detailed component metadata
129
- - **list_projects** - List all running GDSFactory+ server instances
130
- - **get_project_info** - Get detailed information about a specific project
131
- - **check_drc** - Run Design Rule Check verification (returns structured format with all violations including simplified location data for LLM-friendly troubleshooting)
132
- - **check_connectivity** - Run connectivity verification
133
- - **check_lvs** - Run Layout vs. Schematic verification
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 Standalone Server for GDSFactory+.
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
- - Standalone MCP server (this package)
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 gdsfactoryplus.mcp_standalone import main
15
+ from gfp_mcp import main
16
16
  main()
17
17
 
18
18
  Or via CLI:
19
- gfp mcp-serve
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.2.4"
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')