gibson-cli 0.7.7__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 +1 -1
- gibson/api/BaseApi.py +24 -6
- gibson/api/ProjectApi.py +34 -1
- gibson/command/Help.py +6 -2
- gibson/command/code/Entity.py +2 -2
- gibson/command/list/Projects.py +1 -1
- gibson/command/mcp/McpServer.py +25 -0
- gibson/core/CommandRouter.py +3 -0
- gibson/core/Completions.py +2 -2
- gibson/core/Configuration.py +14 -0
- gibson/core/Conversation.py +2 -2
- gibson/services/mcp/server.py +87 -0
- {gibson_cli-0.7.7.dist-info → gibson_cli-0.8.0.dist-info}/METADATA +47 -23
- {gibson_cli-0.7.7.dist-info → gibson_cli-0.8.0.dist-info}/RECORD +18 -15
- {gibson_cli-0.7.7.dist-info → gibson_cli-0.8.0.dist-info}/WHEEL +1 -1
- {gibson_cli-0.7.7.dist-info → gibson_cli-0.8.0.dist-info}/top_level.txt +1 -0
- venv/bin/activate_this.py +59 -0
- {gibson_cli-0.7.7.dist-info → gibson_cli-0.8.0.dist-info}/entry_points.txt +0 -0
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
|
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
|
-
|
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
|
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()
|
gibson/command/Help.py
CHANGED
@@ -3,7 +3,6 @@ from rich.console import Console
|
|
3
3
|
from rich.table import Table
|
4
4
|
from rich.text import Text
|
5
5
|
|
6
|
-
import gibson.core.Colors as Colors
|
7
6
|
from gibson.command.BaseCommand import BaseCommand
|
8
7
|
from gibson.core.Memory import Memory
|
9
8
|
|
@@ -57,7 +56,7 @@ class Help(BaseCommand):
|
|
57
56
|
"memory": None,
|
58
57
|
},
|
59
58
|
"forget": {
|
60
|
-
"description":
|
59
|
+
"description": "delete entities from memory",
|
61
60
|
"subcommands": ["all", "last", "stored"],
|
62
61
|
"memory": "based on user selection",
|
63
62
|
},
|
@@ -72,6 +71,11 @@ class Help(BaseCommand):
|
|
72
71
|
"subcommands": ["entities", "projects"],
|
73
72
|
"memory": None,
|
74
73
|
},
|
74
|
+
"mcp": {
|
75
|
+
"description": "allows tools like Cursor to interact with your gibson project",
|
76
|
+
"subcommands": ["run"],
|
77
|
+
"memory": None,
|
78
|
+
},
|
75
79
|
"merge": {
|
76
80
|
"description": "merge last memory (recent changes) into stored project memory",
|
77
81
|
"subcommands": None,
|
gibson/command/code/Entity.py
CHANGED
@@ -186,10 +186,10 @@ class Entity(BaseCommand):
|
|
186
186
|
|
187
187
|
def __render_workspace(
|
188
188
|
self,
|
189
|
-
original_entity: StructureEntity
|
189
|
+
original_entity: StructureEntity,
|
190
190
|
entity: StructureEntity,
|
191
191
|
model_name: str,
|
192
|
-
original_model_code: str
|
192
|
+
original_model_code: str,
|
193
193
|
model_code: str,
|
194
194
|
):
|
195
195
|
self.configuration.platform.cmd_clear()
|
gibson/command/list/Projects.py
CHANGED
@@ -13,7 +13,7 @@ class Projects(BaseCommand):
|
|
13
13
|
self.configuration.require_login()
|
14
14
|
|
15
15
|
with DisappearingSpinner():
|
16
|
-
projects = ProjectApi(self.configuration).
|
16
|
+
projects = ProjectApi(self.configuration).list()
|
17
17
|
|
18
18
|
if len(projects) == 0:
|
19
19
|
self.conversation.type(
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import signal
|
2
|
+
import sys
|
3
|
+
|
4
|
+
import gibson.core.Colors as Colors
|
5
|
+
from gibson.command.BaseCommand import BaseCommand
|
6
|
+
from gibson.services.mcp.server import mcp
|
7
|
+
|
8
|
+
|
9
|
+
class McpServer(BaseCommand):
|
10
|
+
def execute(self):
|
11
|
+
if len(sys.argv) == 3 and sys.argv[2] == "run":
|
12
|
+
# Setup signal handlers to exit the server
|
13
|
+
signal.signal(signal.SIGTERM, lambda signo, frame: sys.exit(0))
|
14
|
+
signal.signal(signal.SIGINT, lambda signo, frame: sys.exit(0))
|
15
|
+
mcp.run()
|
16
|
+
else:
|
17
|
+
self.usage()
|
18
|
+
|
19
|
+
def usage(self):
|
20
|
+
self.configuration.display_project()
|
21
|
+
self.conversation.type(
|
22
|
+
f"usage: {Colors.command(self.configuration.command, 'mcp', args='run', hint='run the mcp server')}\n"
|
23
|
+
)
|
24
|
+
self.conversation.newline()
|
25
|
+
exit(1)
|
gibson/core/CommandRouter.py
CHANGED
@@ -10,6 +10,7 @@ from gibson.command.Forget import Forget
|
|
10
10
|
from gibson.command.Help import Help
|
11
11
|
from gibson.command.importer.Import import Import
|
12
12
|
from gibson.command.list.List import List
|
13
|
+
from gibson.command.mcp.McpServer import McpServer
|
13
14
|
from gibson.command.Merge import Merge
|
14
15
|
from gibson.command.Modify import Modify
|
15
16
|
from gibson.command.new.New import New
|
@@ -58,6 +59,8 @@ class CommandRouter:
|
|
58
59
|
command = Import(self.configuration)
|
59
60
|
elif sys.argv[1] == "list":
|
60
61
|
command = List(self.configuration)
|
62
|
+
elif sys.argv[1] == "mcp":
|
63
|
+
command = McpServer(self.configuration)
|
61
64
|
elif sys.argv[1] == "merge":
|
62
65
|
command = Merge(self.configuration)
|
63
66
|
elif sys.argv[1] == "modify":
|
gibson/core/Completions.py
CHANGED
@@ -8,7 +8,7 @@ class Completions:
|
|
8
8
|
self.file_name = "bash_completion"
|
9
9
|
|
10
10
|
def install(self):
|
11
|
-
completions_location = f"
|
11
|
+
completions_location = f"{self.user_home}/{self.gibson_config}/{self.file_name}"
|
12
12
|
installation = f"""\n[ -s "{completions_location}" ] && \\. "{completions_location}" # Load gibson auto completion\n"""
|
13
13
|
|
14
14
|
for file in [f"{self.user_home}/.bashrc", f"{self.user_home}/.zshrc"]:
|
@@ -21,7 +21,7 @@ class Completions:
|
|
21
21
|
|
22
22
|
def write(self):
|
23
23
|
try:
|
24
|
-
file = os.path.dirname(__file__) +
|
24
|
+
file = os.path.dirname(__file__) + "/../data/bash-completion.tmpl"
|
25
25
|
with open(file, "r") as f:
|
26
26
|
contents = f.read()
|
27
27
|
except FileNotFoundError:
|
gibson/core/Configuration.py
CHANGED
@@ -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
|
gibson/core/Conversation.py
CHANGED
@@ -105,7 +105,7 @@ class Conversation:
|
|
105
105
|
|
106
106
|
def message_customize_settings(self):
|
107
107
|
self.type(
|
108
|
-
|
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
|
-
|
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(
|
@@ -0,0 +1,87 @@
|
|
1
|
+
from typing import Dict, List
|
2
|
+
|
3
|
+
from mcp.server.fastmcp import FastMCP
|
4
|
+
|
5
|
+
from gibson.api.ProjectApi import ProjectApi
|
6
|
+
from gibson.core.Configuration import Configuration
|
7
|
+
|
8
|
+
mcp = FastMCP("GibsonAI")
|
9
|
+
|
10
|
+
project_api = ProjectApi(Configuration())
|
11
|
+
|
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)
|
79
|
+
|
80
|
+
|
81
|
+
@mcp.tool()
|
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
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: gibson-cli
|
3
|
-
Version: 0.
|
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/
|
@@ -11,55 +11,60 @@ Project-URL: Changelog, https://github.com/gibsonai/cli/releases
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
13
13
|
Classifier: Intended Audience :: Developers
|
14
|
-
Classifier: Programming Language :: Python :: 3.
|
15
|
-
Requires-Python: >=3.
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
15
|
+
Requires-Python: >=3.10
|
16
16
|
Description-Content-Type: text/markdown
|
17
17
|
Requires-Dist: annotated-types==0.6.0
|
18
|
-
Requires-Dist: anyio==4.
|
18
|
+
Requires-Dist: anyio==4.9.0
|
19
19
|
Requires-Dist: certifi==2024.2.2
|
20
20
|
Requires-Dist: charset-normalizer==3.3.2
|
21
21
|
Requires-Dist: click==8.1.7
|
22
22
|
Requires-Dist: dnspython==2.6.1
|
23
|
-
Requires-Dist:
|
23
|
+
Requires-Dist: email-validator==2.1.1
|
24
24
|
Requires-Dist: exceptiongroup==1.2.0
|
25
|
-
Requires-Dist:
|
26
|
-
Requires-Dist:
|
27
|
-
Requires-Dist: fastapi==0.
|
25
|
+
Requires-Dist: faker==24.0.0
|
26
|
+
Requires-Dist: faker-sqlalchemy==0.10.2208140
|
27
|
+
Requires-Dist: fastapi==0.115.12
|
28
28
|
Requires-Dist: fastapi-cli==0.0.2
|
29
29
|
Requires-Dist: h11==0.14.0
|
30
30
|
Requires-Dist: httpcore==1.0.5
|
31
31
|
Requires-Dist: httptools==0.6.1
|
32
32
|
Requires-Dist: httpx==0.27.0
|
33
|
+
Requires-Dist: httpx-sse==0.4.0
|
33
34
|
Requires-Dist: idna==3.6
|
34
35
|
Requires-Dist: iniconfig==2.0.0
|
35
|
-
Requires-Dist:
|
36
|
+
Requires-Dist: jinja2==3.1.4
|
36
37
|
Requires-Dist: markdown-it-py==3.0.0
|
37
|
-
Requires-Dist:
|
38
|
+
Requires-Dist: markupsafe==2.1.5
|
39
|
+
Requires-Dist: mcp==1.6.0
|
38
40
|
Requires-Dist: mdurl==0.1.2
|
39
41
|
Requires-Dist: orjson==3.10.3
|
40
|
-
Requires-Dist: packaging==
|
42
|
+
Requires-Dist: packaging==24.2
|
41
43
|
Requires-Dist: pluggy==1.4.0
|
42
|
-
Requires-Dist: pydantic==2.
|
43
|
-
Requires-Dist:
|
44
|
+
Requires-Dist: pydantic==2.11.0
|
45
|
+
Requires-Dist: pydantic-core==2.33.0
|
46
|
+
Requires-Dist: pydantic-settings==2.8.1
|
44
47
|
Requires-Dist: pyfiglet==1.0.2
|
45
|
-
Requires-Dist:
|
46
|
-
Requires-Dist:
|
48
|
+
Requires-Dist: pygments==2.18.0
|
49
|
+
Requires-Dist: pymysql==1.1.0
|
47
50
|
Requires-Dist: pytest==8.0.1
|
48
51
|
Requires-Dist: python-dateutil==2.9.0.post0
|
49
52
|
Requires-Dist: python-dotenv==1.0.1
|
50
53
|
Requires-Dist: python-multipart==0.0.9
|
51
|
-
Requires-Dist:
|
54
|
+
Requires-Dist: pyyaml==6.0.1
|
52
55
|
Requires-Dist: requests==2.31.0
|
53
56
|
Requires-Dist: rich==13.9.2
|
54
57
|
Requires-Dist: shellingham==1.5.4
|
55
58
|
Requires-Dist: six==1.16.0
|
56
59
|
Requires-Dist: sniffio==1.3.1
|
57
|
-
Requires-Dist:
|
58
|
-
Requires-Dist: starlette==
|
60
|
+
Requires-Dist: sqlalchemy==1.4.41
|
61
|
+
Requires-Dist: sse-starlette==2.2.1
|
62
|
+
Requires-Dist: starlette==0.46.1
|
59
63
|
Requires-Dist: textual==0.83.0
|
60
64
|
Requires-Dist: tomli==2.0.1
|
61
65
|
Requires-Dist: typer==0.12.3
|
62
|
-
Requires-Dist:
|
66
|
+
Requires-Dist: typing-extensions==4.13.0
|
67
|
+
Requires-Dist: typing-inspection==0.4.0
|
63
68
|
Requires-Dist: ujson==5.9.0
|
64
69
|
Requires-Dist: urllib3==1.26.6
|
65
70
|
Requires-Dist: uvicorn==0.29.0
|
@@ -74,12 +79,12 @@ Requires-Dist: yaspin==3.1.0
|
|
74
79
|
# Gibson CLI
|
75
80
|
|
76
81
|
[](https://pypi.org/project/gibson-cli/)
|
77
|
-

|
78
83
|
[](https://docs.gibsonai.com)
|
79
84
|
|
80
85
|
## Prerequisites
|
81
86
|
|
82
|
-
Gibson currently works on projects that use Python 3.
|
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.
|
83
88
|
|
84
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.
|
85
90
|
|
@@ -191,7 +196,7 @@ All of Gibson's configuration files and caches are stored in `$HOME/.gibson`. Us
|
|
191
196
|
|
192
197
|
## Currently Supported Software
|
193
198
|
|
194
|
-
- Python 3.
|
199
|
+
- Python 3.10 or greater
|
195
200
|
- MySQL
|
196
201
|
- SQLAlchemy
|
197
202
|
- Pydantic
|
@@ -375,6 +380,25 @@ At the moment, just refer to the base-level schema directly.
|
|
375
380
|
- e.g. `gibson q add nickname to sql://user`
|
376
381
|
- `gibson code model user`
|
377
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
|
+
|
378
402
|
## Contributing
|
379
403
|
|
380
404
|
- Clone this repository somewhere in your file system
|
@@ -1,10 +1,10 @@
|
|
1
|
-
bin/build.sh,sha256=
|
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=
|
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=
|
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
|
@@ -12,7 +12,7 @@ gibson/command/Conf.py,sha256=yuAGL6M8MUURG4hW3MAW043c-h_ALw3FHWbyCOR8YTQ,2375
|
|
12
12
|
gibson/command/Count.py,sha256=QOagwCwDxUHYPivFntr-RWUmlKWKDHgDIGZBfju6VpY,1040
|
13
13
|
gibson/command/Dev.py,sha256=zbZjsgAKAHlNUflEr_Lj2QmRBXNbIGIHrPJ3t5DcFC8,4213
|
14
14
|
gibson/command/Forget.py,sha256=Fm1mUyZkK3HS5fIVgNaC3d97vcWWQVysdDkg4ciE8Bk,1018
|
15
|
-
gibson/command/Help.py,sha256=
|
15
|
+
gibson/command/Help.py,sha256=Gih3JVZ3SLXrdZPInZccb-NtlzvSUTbTwW2NztKnrbo,6456
|
16
16
|
gibson/command/Merge.py,sha256=R5ybMC1tUR5_T8YyUfXutzFa_V9j1_flv0s7KTJRq0M,1061
|
17
17
|
gibson/command/Modify.py,sha256=XgTM6EodL7sVhWrnWuTCDx2PNJw3xo-aKI80HCmSpV8,1171
|
18
18
|
gibson/command/Question.py,sha256=g8SwopbzeG14WWP0bc-fXIDVqOOicMzjC9YXoGd-NxY,3830
|
@@ -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=
|
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,8 @@ 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=
|
40
|
+
gibson/command/list/Projects.py,sha256=ju82kC3cuvAMGg4YJl1yn0l8t11fa1T5Zvgkl_p9m9U,1194
|
41
|
+
gibson/command/mcp/McpServer.py,sha256=fzeo6gQU0eZL9LA0w5iC1I-wATufIyh23zA7oiYRtGM,810
|
41
42
|
gibson/command/new/Module.py,sha256=PCTt6k54XFzgNjNgwY0FKQFzk0YFoaN_KPZF2sfN_V0,1535
|
42
43
|
gibson/command/new/New.py,sha256=cwsBpZAZH-9se26ywAUFyvrc9L9ezwoERIrRLlDkrzU,1519
|
43
44
|
gibson/command/new/Project.py,sha256=Cw1Z6TvPIGhTi7GiQZ2VFjv6hXdpGKQdX9HuAd5gric,759
|
@@ -65,10 +66,10 @@ gibson/conf/dev/Schema.py,sha256=kOSlX1jEyVb82xd8TO8jEAimLcaefIFJr6d2JYvyTqg,74
|
|
65
66
|
gibson/conf/tests/test_conf_Dependencies.py,sha256=LITeeYiqXM5rKkyWFBqcnMvUR5pzDRuHVAngH372jWc,116
|
66
67
|
gibson/conf/tests/test_conf_Platform.py,sha256=Zc53IsZmV-hT9VRrZEPNrsuehSdWnJXWKGMmOhEqWHo,138
|
67
68
|
gibson/core/Colors.py,sha256=sllEmJAb2AAUH0e-ZLP1_C8pfz5U_w0fo5kubSH5g1o,3426
|
68
|
-
gibson/core/CommandRouter.py,sha256=
|
69
|
-
gibson/core/Completions.py,sha256=
|
70
|
-
gibson/core/Configuration.py,sha256=
|
71
|
-
gibson/core/Conversation.py,sha256=
|
69
|
+
gibson/core/CommandRouter.py,sha256=P64NCzC2noHauV_cdMU1IzfjgHe1zezDadviaPs3Cds,3320
|
70
|
+
gibson/core/Completions.py,sha256=a26WRh40UpnTT5HGTPT8TCcL8h80HvvZiTJXZofDjx8,1207
|
71
|
+
gibson/core/Configuration.py,sha256=xUul0ckr92e7uvn5t3YM1w6n3uGytvs6l69kx9EotIc,16404
|
72
|
+
gibson/core/Conversation.py,sha256=KF7YPXijhhz6HOkife__ycHox4WeRKNHIpv3juDPhq0,10237
|
72
73
|
gibson/core/Diff.py,sha256=onUJ5_0_S1vKAY_oFgX4vmwQo4byrnXLV4w7QSNA8fY,1071
|
73
74
|
gibson/core/Env.py,sha256=08dZRHzzR0ahrbM4S0bXC7V1xhYQkT8Zefs00qUHf0U,498
|
74
75
|
gibson/core/Memory.py,sha256=3ItGef4RCfBplbjxhNyid8eiPVKHmW-DKAMFeYujqN0,4063
|
@@ -105,6 +106,7 @@ gibson/services/code/customization/CustomizationManager.py,sha256=M2gz98Yo2WTnnh
|
|
105
106
|
gibson/services/code/customization/Index.py,sha256=4Thf0gZM6VErZJS97w748PRNmHi8QvsyblOLCw1Y_XE,364
|
106
107
|
gibson/services/code/customization/tests/test_code_customization_Authenticator.py,sha256=kKExkLfKPpRA2NQH3fvRCuBEMhCGhR-IvNJqXuyBz3c,1949
|
107
108
|
gibson/services/code/customization/tests/test_code_customization_BaseCustomization.py,sha256=jaEwxxoU7d9ziOtfF21NPmZX2qSRpa-kz_8Ju9BKGts,412
|
109
|
+
gibson/services/mcp/server.py,sha256=rIgT9W05wB2hen6v0QQ2J_B9VyJb8htE3tPLTR5Q5FI,2494
|
108
110
|
gibson/structure/Entity.py,sha256=N_Tx8RTs9ySMMgAoR9rVuMcsRgNA7zvNvJBScJLfYE4,675
|
109
111
|
gibson/structure/mysql/Entity.py,sha256=zolt3N_F3WlQtlOqrHflwsJeJ6r6A3MN4LxCzeAbU_k,3693
|
110
112
|
gibson/structure/mysql/testing.py,sha256=al4LI6e3bhjopsR0qTAmaOJyCQXF0_inVQ4xv7VQ6qo,9149
|
@@ -126,8 +128,9 @@ gibson/structure/tests/test_structure_Entity.py,sha256=askl8w0p1uqET6HKBogJlRcPP
|
|
126
128
|
gibson/tests/test_Env.py,sha256=DPWmP0-aEelducq9bAwv7rKoY2NjWXUeCrzfJDQkn2M,369
|
127
129
|
gibson/tests/test_Memory.py,sha256=YP7owToABAk_-s7fD5UG0HTc4lamDjdA39JUlLnk3Fg,2574
|
128
130
|
gibson/tests/test_utils.py,sha256=r_y-EG05YTCNtL8MWiAK1KmPsmeoMgypKsQC_lVgOtM,559
|
129
|
-
|
130
|
-
gibson_cli-0.
|
131
|
-
gibson_cli-0.
|
132
|
-
gibson_cli-0.
|
133
|
-
gibson_cli-0.
|
131
|
+
venv/bin/activate_this.py,sha256=E1T7r3559tBsyqFpdcQW0HbY7gDvNiIv5Pc6HQ4bpoA,2383
|
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,,
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2020-202x The virtualenv developers
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
"""
|
23
|
+
Activate virtualenv for current interpreter:
|
24
|
+
|
25
|
+
import runpy
|
26
|
+
runpy.run_path(this_file)
|
27
|
+
|
28
|
+
This can be used when you must use an existing Python interpreter, not the virtualenv bin/python.
|
29
|
+
""" # noqa: D415
|
30
|
+
|
31
|
+
from __future__ import annotations
|
32
|
+
|
33
|
+
import os
|
34
|
+
import site
|
35
|
+
import sys
|
36
|
+
|
37
|
+
try:
|
38
|
+
abs_file = os.path.abspath(__file__)
|
39
|
+
except NameError as exc:
|
40
|
+
msg = "You must use import runpy; runpy.run_path(this_file)"
|
41
|
+
raise AssertionError(msg) from exc
|
42
|
+
|
43
|
+
bin_dir = os.path.dirname(abs_file)
|
44
|
+
base = bin_dir[: -len("bin") - 1] # strip away the bin part from the __file__, plus the path separator
|
45
|
+
|
46
|
+
# prepend bin to PATH (this file is inside the bin directory)
|
47
|
+
os.environ["PATH"] = os.pathsep.join([bin_dir, *os.environ.get("PATH", "").split(os.pathsep)])
|
48
|
+
os.environ["VIRTUAL_ENV"] = base # virtual env is right above bin directory
|
49
|
+
os.environ["VIRTUAL_ENV_PROMPT"] = "" or os.path.basename(base) # noqa: SIM222
|
50
|
+
|
51
|
+
# add the virtual environments libraries to the host python import mechanism
|
52
|
+
prev_length = len(sys.path)
|
53
|
+
for lib in "../lib/python3.10/site-packages".split(os.pathsep):
|
54
|
+
path = os.path.realpath(os.path.join(bin_dir, lib))
|
55
|
+
site.addsitedir(path)
|
56
|
+
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
|
57
|
+
|
58
|
+
sys.real_prefix = sys.prefix
|
59
|
+
sys.prefix = base
|
File without changes
|