gibson-cli 0.7.8__py3-none-any.whl → 0.8.0__py3-none-any.whl

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.
bin/build.sh CHANGED
@@ -1,2 +1,2 @@
1
1
  rm -rf dist gibson_cli.egg-info
2
- python3 -m build
2
+ PYTHONMEM=1G python3 -m build
gibson/api/BaseApi.py CHANGED
@@ -1,4 +1,3 @@
1
- import os
2
1
  import pprint
3
2
 
4
3
  import requests
@@ -16,6 +15,16 @@ class BaseApi:
16
15
  def base_url(self):
17
16
  return f"{self.configuration.api_domain()}/{self.VERSION}"
18
17
 
18
+ def delete(self, endpoint):
19
+ r = requests.delete(self.url(endpoint), headers=self.headers())
20
+
21
+ if r.status_code == 401 and self.refresh_auth_tokens():
22
+ r = requests.delete(self.url(endpoint), headers=self.headers())
23
+
24
+ self.__raise_for_status(r)
25
+
26
+ return r
27
+
19
28
  def get(self, endpoint):
20
29
  r = requests.get(self.url(endpoint), headers=self.headers())
21
30
 
@@ -37,7 +46,17 @@ class BaseApi:
37
46
 
38
47
  return headers
39
48
 
40
- def post(self, endpoint, json: dict):
49
+ def patch(self, endpoint, json: dict):
50
+ r = requests.patch(self.url(endpoint), headers=self.headers(), json=json)
51
+
52
+ if r.status_code == 401 and self.refresh_auth_tokens():
53
+ r = requests.patch(self.url(endpoint), headers=self.headers(), json=json)
54
+
55
+ self.__raise_for_status(r)
56
+
57
+ return r
58
+
59
+ def post(self, endpoint: str = "", json: dict = None):
41
60
  r = requests.post(self.url(endpoint), headers=self.headers(), json=json)
42
61
 
43
62
  if r.status_code == 401 and self.refresh_auth_tokens():
@@ -78,10 +97,9 @@ class BaseApi:
78
97
  )
79
98
  return True
80
99
 
81
- def url(self, endpoint):
82
- if self.PREFIX:
83
- return f"{self.base_url()}/{self.PREFIX}/{endpoint}"
84
- return f"{self.base_url()}/{endpoint}"
100
+ def url(self, endpoint: str):
101
+ base = f"{self.base_url()}/{self.PREFIX}" if self.PREFIX else self.base_url()
102
+ return f"{base}/{endpoint}" if endpoint else base
85
103
 
86
104
  def __raise_for_status(self, r):
87
105
  if r.status_code == 401:
gibson/api/ProjectApi.py CHANGED
@@ -9,5 +9,38 @@ class ProjectApi(BaseApi):
9
9
  self.configuration = configuration
10
10
  self.configuration.require_login()
11
11
 
12
- def all_projects(self):
12
+ def list(self):
13
13
  return self.get("all")["projects"]
14
+
15
+ def create(self):
16
+ return self.post().json()
17
+
18
+ def database_schema(self, uuid: str):
19
+ return self.get(f"{uuid}/schema/deployed")
20
+
21
+ def lookup(self, uuid: str):
22
+ return self.get(f"{uuid}")
23
+
24
+ def deploy(self, uuid: str):
25
+ return self.post(f"{uuid}/deploy")
26
+
27
+ def mcp(self, uuid: str):
28
+ return self.get(f"{uuid}/mcp")
29
+
30
+ def schema(self, uuid: str):
31
+ return self.get(f"{uuid}/schema")
32
+
33
+ def structure(self, uuid: str):
34
+ return self.get(f"{uuid}/structure")
35
+
36
+ def submit_message(self, uuid: str, message: str):
37
+ if not message:
38
+ raise ValueError("Message is required")
39
+
40
+ return self.post(f"{uuid}/conversation", {"content": message}).json()
41
+
42
+ def update(self, uuid: str, name: str):
43
+ if not name:
44
+ raise ValueError("Name is required")
45
+
46
+ return self.put(f"{uuid}", {"name": name}).json()
@@ -186,10 +186,10 @@ class Entity(BaseCommand):
186
186
 
187
187
  def __render_workspace(
188
188
  self,
189
- original_entity: StructureEntity | None,
189
+ original_entity: StructureEntity,
190
190
  entity: StructureEntity,
191
191
  model_name: str,
192
- original_model_code: str | None,
192
+ original_model_code: str,
193
193
  model_code: str,
194
194
  ):
195
195
  self.configuration.platform.cmd_clear()
@@ -13,7 +13,7 @@ class Projects(BaseCommand):
13
13
  self.configuration.require_login()
14
14
 
15
15
  with DisappearingSpinner():
16
- projects = ProjectApi(self.configuration).all_projects()
16
+ projects = ProjectApi(self.configuration).list()
17
17
 
18
18
  if len(projects) == 0:
19
19
  self.conversation.type(
@@ -235,6 +235,10 @@ class Configuration:
235
235
  self.require_project()
236
236
  return self.settings[self.project.name]
237
237
 
238
+ def get_project_id(self):
239
+ self.require_project()
240
+ return self.project.id
241
+
238
242
  def get_refresh_token(self):
239
243
  try:
240
244
  with open(f"{self.paths.auth}/{self.API_ENV}", "r") as f:
@@ -329,6 +333,16 @@ class Configuration:
329
333
 
330
334
  return self
331
335
 
336
+ def require_project_id(self) -> str:
337
+ project_id = self.get_project_id()
338
+ if not project_id:
339
+ self.conversation.type(
340
+ "A valid project ID is required to perform this action. Please ensure the project ID is set in your configuration.\n"
341
+ )
342
+ exit(1)
343
+
344
+ return project_id
345
+
332
346
  def require_project_key_or_id(self):
333
347
  if self.project.id:
334
348
  return self
@@ -105,7 +105,7 @@ class Conversation:
105
105
 
106
106
  def message_customize_settings(self):
107
107
  self.type(
108
- f"You can edit the configuration file directly or ask me to do it for you.\n"
108
+ "You can edit the configuration file directly or ask me to do it for you.\n"
109
109
  )
110
110
  self.type(
111
111
  "I will not be able to do much until you modify api::key and "
@@ -220,7 +220,7 @@ class Conversation:
220
220
 
221
221
  def project_api_key_not_set(self, configuration):
222
222
  self.type(
223
- f"\nYou have not set the API key for your project. Please set the API key by executing:\n"
223
+ "\nYou have not set the API key for your project. Please set the API key by executing:\n"
224
224
  )
225
225
  self.newline()
226
226
  self.type(
@@ -1,13 +1,87 @@
1
- import os
1
+ from typing import Dict, List
2
2
 
3
3
  from mcp.server.fastmcp import FastMCP
4
4
 
5
+ from gibson.api.ProjectApi import ProjectApi
6
+ from gibson.core.Configuration import Configuration
7
+
5
8
  mcp = FastMCP("GibsonAI")
6
9
 
10
+ project_api = ProjectApi(Configuration())
11
+
7
12
  # Note: Resources are not yet supported by Cursor, everything must be implemented as a tool
13
+ # See https://docs.cursor.com/context/model-context-protocol#limitations
14
+
15
+
16
+ @mcp.tool()
17
+ def get_projects() -> List[Dict]:
18
+ """Get all GibsonAI projects"""
19
+ return project_api.list()
20
+
21
+
22
+ @mcp.tool()
23
+ def create_project() -> Dict:
24
+ """Create a new GibsonAI project"""
25
+ return project_api.create()
26
+
27
+
28
+ @mcp.tool()
29
+ def get_project_details(uuid: str) -> Dict:
30
+ """Get a GibsonAI project's details"""
31
+ return project_api.lookup(uuid=uuid)
32
+
33
+
34
+ @mcp.tool()
35
+ def get_project_hosted_api_details(uuid: str) -> str:
36
+ """
37
+ Get a GibsonAI project's hosted API details
38
+ This includes necessary context for an LLM to understand and generate API calls related to fetching or modifying the project's data
39
+ """
40
+ return project_api.mcp(uuid=uuid)
41
+
42
+
43
+ @mcp.tool()
44
+ def update_project(uuid: str, project_name: str) -> Dict:
45
+ """
46
+ Update a GibsonAI project's details
47
+ This currently only updates the project's name
48
+ Returns the updated project details
49
+ """
50
+ return project_api.update(uuid=uuid, name=project_name)
51
+
52
+
53
+ @mcp.tool()
54
+ def submit_data_modeling_request(uuid: str, data_modeling_request: str) -> Dict:
55
+ """
56
+ Submit a data modeling request for a GibsonAI project
57
+ This tool fully handles all data modeling, you should provide the user's request as-is
58
+ Returns the response from the LLM
59
+ """
60
+ return project_api.submit_message(uuid=uuid, message=data_modeling_request)
61
+
62
+
63
+ @mcp.tool()
64
+ def deploy_project(uuid: str) -> None:
65
+ """
66
+ Deploy a GibsonAI project's hosted databases
67
+ This deploys both the development and production databases simultaneously and automatically handles the migrations
68
+ """
69
+ project_api.deploy(uuid=uuid)
70
+
71
+
72
+ @mcp.tool()
73
+ def get_project_schema(uuid: str) -> str:
74
+ """
75
+ Get the schema for a GibsonAI project
76
+ This includes any changes made to the schema since the last deployment
77
+ """
78
+ return project_api.schema(uuid=uuid)
8
79
 
9
80
 
10
81
  @mcp.tool()
11
- def get_project_name() -> str:
12
- """Get the gibson project name"""
13
- return os.environ.get("GIBSONAI_PROJECT")
82
+ def get_deployed_schema(uuid: str) -> str:
83
+ """
84
+ Get the deployed schema for a GibsonAI project
85
+ This is the schema that is currently live on the project's hosted databases
86
+ """
87
+ return project_api.database_schema(uuid=uuid)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gibson-cli
3
- Version: 0.7.8
3
+ Version: 0.8.0
4
4
  Summary: Gibson Command Line Interface
5
5
  Author-email: GibsonAI <noc@gibsonai.com>
6
6
  Project-URL: Homepage, https://gibsonai.com/
@@ -39,7 +39,7 @@ Requires-Dist: markupsafe==2.1.5
39
39
  Requires-Dist: mcp==1.6.0
40
40
  Requires-Dist: mdurl==0.1.2
41
41
  Requires-Dist: orjson==3.10.3
42
- Requires-Dist: packaging==23.2
42
+ Requires-Dist: packaging==24.2
43
43
  Requires-Dist: pluggy==1.4.0
44
44
  Requires-Dist: pydantic==2.11.0
45
45
  Requires-Dist: pydantic-core==2.33.0
@@ -79,12 +79,12 @@ Requires-Dist: yaspin==3.1.0
79
79
  # Gibson CLI
80
80
 
81
81
  [![PyPI - Version](https://img.shields.io/pypi/v/gibson-cli)](https://pypi.org/project/gibson-cli/)
82
- ![Python 3.9+](https://img.shields.io/badge/Python-3.9%2B-blue)
82
+ ![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-blue)
83
83
  [![Docs](https://img.shields.io/badge/Docs-https://docs.gibsonai.com-green)](https://docs.gibsonai.com)
84
84
 
85
85
  ## Prerequisites
86
86
 
87
- Gibson currently works on projects that use Python 3.9 or greater, MySQL, SQLAlchemy, Pydantic, Alembic, FastAPI and pytest. It is capable of building a complete application, from database to API end points, using these frameworks. Future enhancements of Gibson will include support for more languages and frameworks.
87
+ Gibson currently works on projects that use Python 3.10 or greater, MySQL, SQLAlchemy, Pydantic, Alembic, FastAPI and pytest. It is capable of building a complete application, from database to API end points, using these frameworks. Future enhancements of Gibson will include support for more languages and frameworks.
88
88
 
89
89
  Portions of the Gibson backend code are written by Gibson. So far, versus a human developer, it has coded 66% of the software and did so in seconds. To get started, read the instructions here.
90
90
 
@@ -196,7 +196,7 @@ All of Gibson's configuration files and caches are stored in `$HOME/.gibson`. Us
196
196
 
197
197
  ## Currently Supported Software
198
198
 
199
- - Python 3.9 or greater
199
+ - Python 3.10 or greater
200
200
  - MySQL
201
201
  - SQLAlchemy
202
202
  - Pydantic
@@ -380,6 +380,25 @@ At the moment, just refer to the base-level schema directly.
380
380
  - e.g. `gibson q add nickname to sql://user`
381
381
  - `gibson code model user`
382
382
 
383
+ ### Setting up the MCP server with Cursor
384
+
385
+ Head over to `Cursor Settings` > `MCP` and click `Add new MCP server`
386
+
387
+ Update the configuration to look like the following:
388
+
389
+ ```json
390
+ {
391
+ "mcpServers": {
392
+ "gibson": {
393
+ "command": "gibson",
394
+ "args": ["mcp", "run"]
395
+ }
396
+ }
397
+ }
398
+ ```
399
+
400
+ That's it! Just make sure you're logged in to the CLI (if you're reading this, you've likely already run `gibson auth login`) and then Cursor's agents will have access to the Gibson MCP server to create + update projects on your behalf, explain how to interact with the database + hosted APIs, and even write working code for you.
401
+
383
402
  ## Contributing
384
403
 
385
404
  - Clone this repository somewhere in your file system
@@ -1,10 +1,10 @@
1
- bin/build.sh,sha256=H3TAd349BECbcK3_t_jW9VzoLInMNrXtaLnXMEVanew,49
1
+ bin/build.sh,sha256=NfwMI06hR9w4VTmttDn5Zlbea7iur8BtfC60JTpMH0g,62
2
2
  bin/clean.sh,sha256=bVJ1aL-IWconmyZ70OAcF0MHiPzpWCejPiIFJ72yFkM,55
3
3
  bin/gibson,sha256=9OiLT8M9kJHA-gTp0pFc8NYbOe6LrQCs_HXgnD-5D3U,843
4
4
  bin/release.sh,sha256=LxPqH5kxhLKvzHaPRLBlq_ApaK7FHEteH4SzeRenidk,49
5
- gibson/api/BaseApi.py,sha256=aQAsL8d_n6qhQaeS2zjcjsGx3AfoZCqf8mi7pbqWCPg,3040
5
+ gibson/api/BaseApi.py,sha256=ngr0XA5J-HEvtDo2z-T-G07GJ-o0i-LBZBpfqwQp834,3691
6
6
  gibson/api/Cli.py,sha256=Qcm5NIQ4x1Wn6KfkrAzwvZeWyt-cKF_xD7_lTWL4Lbw,8071
7
- gibson/api/ProjectApi.py,sha256=T7TqtywJjrzFIfARenQUsrH-80x9Oo1pABbFAdlQkI0,356
7
+ gibson/api/ProjectApi.py,sha256=cyLfHGqTC5Lqyobmq0afe9ntVSZ_QbLBBd6oDDaqWoY,1258
8
8
  gibson/bin/gibson.py,sha256=56fqPBiF47uJvafHyNbWZ4GorcI0Ut98DCXeS7dt2io,420
9
9
  gibson/command/BaseCommand.py,sha256=mmWUO0FxjMCbv3cHWnnasfAWnU_hTuGHUsRVJ4hUcqM,777
10
10
  gibson/command/Build.py,sha256=6lMdTa3HZvcbskoX8iJZJnekiJmyNVSbgGmgvh1v-BM,4421
@@ -26,7 +26,7 @@ gibson/command/auth/Logout.py,sha256=V01q4TdbiBqCnIrM6IA4T25fO6ws0UpXp42I3pwHZVM
26
26
  gibson/command/code/Api.py,sha256=sSvAqEJXdgQjYcu0uiM6ndHE3GnfkfVL6eqP2Otkbww,1002
27
27
  gibson/command/code/Base.py,sha256=YJ2a5Hl0f9NXHUBBPvlt-dUIqEPWQz5vH6-1EHmbFbA,640
28
28
  gibson/command/code/Code.py,sha256=j6RetYcg3RQcpD7lA0MRDof9A9drHPDeGjdsslQtLvM,3773
29
- gibson/command/code/Entity.py,sha256=N1JiJhP9jN4cHODDjOGjBIX-J7doIhe_x3yoofUGQXM,9087
29
+ gibson/command/code/Entity.py,sha256=PhNzpif-qUV9G7V2H6jgfkOWdaSK5GKp-4uNTzuTw6I,9073
30
30
  gibson/command/code/Model.py,sha256=UWSU3tkscWQFHYGSNR82gsiL1SpnEa4fF7UroaKLFlM,1295
31
31
  gibson/command/code/Models.py,sha256=eoUpZHpR0qwNgX60EWfcNz49GHmBw_FGfBuHH2ueZqY,799
32
32
  gibson/command/code/Schema.py,sha256=t1RBuLyb-FkaIz6jBfzoH426B1IK8s_Tps8p3Mh6B6Y,1403
@@ -37,7 +37,7 @@ gibson/command/importer/Import.py,sha256=z3PI1mGyz1IYggZF5gJSfgvheMkZ_o3o2rdRYGd
37
37
  gibson/command/importer/OpenApi.py,sha256=5PL4JlhniPhUidOFxKpC9ao_r8C_qIeCoGyliPd10ig,3745
38
38
  gibson/command/list/Entities.py,sha256=o5Wemlq_EpeObNwJHbCqkUT4nccfu_OOZ_gYWzJ051Y,1223
39
39
  gibson/command/list/List.py,sha256=IA9VYuOiFdweg-6HIBZ5hECnMyNxsoU2dKd-gzRNtio,1107
40
- gibson/command/list/Projects.py,sha256=8kD_Ny-rSsireW69YigJQia4QzvIRQsPnEUVISL0u0Y,1202
40
+ gibson/command/list/Projects.py,sha256=ju82kC3cuvAMGg4YJl1yn0l8t11fa1T5Zvgkl_p9m9U,1194
41
41
  gibson/command/mcp/McpServer.py,sha256=fzeo6gQU0eZL9LA0w5iC1I-wATufIyh23zA7oiYRtGM,810
42
42
  gibson/command/new/Module.py,sha256=PCTt6k54XFzgNjNgwY0FKQFzk0YFoaN_KPZF2sfN_V0,1535
43
43
  gibson/command/new/New.py,sha256=cwsBpZAZH-9se26ywAUFyvrc9L9ezwoERIrRLlDkrzU,1519
@@ -68,8 +68,8 @@ gibson/conf/tests/test_conf_Platform.py,sha256=Zc53IsZmV-hT9VRrZEPNrsuehSdWnJXWK
68
68
  gibson/core/Colors.py,sha256=sllEmJAb2AAUH0e-ZLP1_C8pfz5U_w0fo5kubSH5g1o,3426
69
69
  gibson/core/CommandRouter.py,sha256=P64NCzC2noHauV_cdMU1IzfjgHe1zezDadviaPs3Cds,3320
70
70
  gibson/core/Completions.py,sha256=a26WRh40UpnTT5HGTPT8TCcL8h80HvvZiTJXZofDjx8,1207
71
- gibson/core/Configuration.py,sha256=ryCDvuLzJDIbnjW-ty6HYLuMn0U2EYU__LdsMbu6-KE,15968
72
- gibson/core/Conversation.py,sha256=cl9dHfQDocB78GF3IyS3jve8iYBSXmeF4hwVAPY-vCE,10239
71
+ gibson/core/Configuration.py,sha256=xUul0ckr92e7uvn5t3YM1w6n3uGytvs6l69kx9EotIc,16404
72
+ gibson/core/Conversation.py,sha256=KF7YPXijhhz6HOkife__ycHox4WeRKNHIpv3juDPhq0,10237
73
73
  gibson/core/Diff.py,sha256=onUJ5_0_S1vKAY_oFgX4vmwQo4byrnXLV4w7QSNA8fY,1071
74
74
  gibson/core/Env.py,sha256=08dZRHzzR0ahrbM4S0bXC7V1xhYQkT8Zefs00qUHf0U,498
75
75
  gibson/core/Memory.py,sha256=3ItGef4RCfBplbjxhNyid8eiPVKHmW-DKAMFeYujqN0,4063
@@ -106,7 +106,7 @@ gibson/services/code/customization/CustomizationManager.py,sha256=M2gz98Yo2WTnnh
106
106
  gibson/services/code/customization/Index.py,sha256=4Thf0gZM6VErZJS97w748PRNmHi8QvsyblOLCw1Y_XE,364
107
107
  gibson/services/code/customization/tests/test_code_customization_Authenticator.py,sha256=kKExkLfKPpRA2NQH3fvRCuBEMhCGhR-IvNJqXuyBz3c,1949
108
108
  gibson/services/code/customization/tests/test_code_customization_BaseCustomization.py,sha256=jaEwxxoU7d9ziOtfF21NPmZX2qSRpa-kz_8Ju9BKGts,412
109
- gibson/services/mcp/server.py,sha256=EpoBu9BJP5iO-eNY-29mg0zyDZuxfT2dSUIIWsXSfGk,299
109
+ gibson/services/mcp/server.py,sha256=rIgT9W05wB2hen6v0QQ2J_B9VyJb8htE3tPLTR5Q5FI,2494
110
110
  gibson/structure/Entity.py,sha256=N_Tx8RTs9ySMMgAoR9rVuMcsRgNA7zvNvJBScJLfYE4,675
111
111
  gibson/structure/mysql/Entity.py,sha256=zolt3N_F3WlQtlOqrHflwsJeJ6r6A3MN4LxCzeAbU_k,3693
112
112
  gibson/structure/mysql/testing.py,sha256=al4LI6e3bhjopsR0qTAmaOJyCQXF0_inVQ4xv7VQ6qo,9149
@@ -129,8 +129,8 @@ gibson/tests/test_Env.py,sha256=DPWmP0-aEelducq9bAwv7rKoY2NjWXUeCrzfJDQkn2M,369
129
129
  gibson/tests/test_Memory.py,sha256=YP7owToABAk_-s7fD5UG0HTc4lamDjdA39JUlLnk3Fg,2574
130
130
  gibson/tests/test_utils.py,sha256=r_y-EG05YTCNtL8MWiAK1KmPsmeoMgypKsQC_lVgOtM,559
131
131
  venv/bin/activate_this.py,sha256=E1T7r3559tBsyqFpdcQW0HbY7gDvNiIv5Pc6HQ4bpoA,2383
132
- gibson_cli-0.7.8.dist-info/METADATA,sha256=fm4SkzjQLoNzUgJJsGY4-6G0fb4aP41sWzkH9hISeto,13757
133
- gibson_cli-0.7.8.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
134
- gibson_cli-0.7.8.dist-info/entry_points.txt,sha256=j5VUvq3AzL21xPvVC24zMoXFt-I5lUWulr66nL3OAPM,50
135
- gibson_cli-0.7.8.dist-info/top_level.txt,sha256=fSV3vegbdbSDwiB6n5z3FCeYwkIonzFrx4ek3F_OSdI,16
136
- gibson_cli-0.7.8.dist-info/RECORD,,
132
+ gibson_cli-0.8.0.dist-info/METADATA,sha256=mMAK0s-OPAW6w9kGeC1AfFImfshzMzx16wV_W59wETE,14378
133
+ gibson_cli-0.8.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
134
+ gibson_cli-0.8.0.dist-info/entry_points.txt,sha256=j5VUvq3AzL21xPvVC24zMoXFt-I5lUWulr66nL3OAPM,50
135
+ gibson_cli-0.8.0.dist-info/top_level.txt,sha256=fSV3vegbdbSDwiB6n5z3FCeYwkIonzFrx4ek3F_OSdI,16
136
+ gibson_cli-0.8.0.dist-info/RECORD,,