deploykar-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.pyc
3
+ venv/
4
+ .venv/
5
+ .env
6
+ .env.*
7
+ !.env.example
8
+ *.egg-info/
9
+ dist/
10
+ build/
11
+ .pytest_cache/
12
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeployKar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.5
2
+ Name: deploykar-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for DeployKar: deploy, monitor and debug your apps from your IDE.
5
+ Project-URL: Homepage, https://deploykar.com
6
+ Author: DeployKar
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Keywords: deploy,deploykar,ide,mcp,model-context-protocol
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Software Development :: Build Tools
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: httpx>=0.27
18
+ Requires-Dist: mcp<3,>=2.3
19
+ Description-Content-Type: text/markdown
20
+
21
+ # DeployKar MCP server
22
+
23
+ Deploy, monitor and debug your [DeployKar](https://deploykar.com) apps from your IDE's AI chat:
24
+ Kiro, Cursor, VS Code (Copilot), Claude Code, Windsurf, or any other MCP client.
25
+
26
+ > "Deploy my app" · "Why did my build fail?" · "Set DATABASE_URL to postgres://…" · "Scale the API to 3 instances"
27
+
28
+ Your IDE's assistant does the thinking. This server only translates its tool calls into DeployKar API
29
+ requests, using a personal API token.
30
+
31
+ ## Setup (2 minutes)
32
+
33
+ You need:
34
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/) installed (it provides the `uvx` command)
35
+ - a DeployKar account. Sign in at **http://187.127.179.204:7100**
36
+ - your app's code in a GitHub repository that DeployKar can access (connect GitHub once in the dashboard)
37
+
38
+ **1. Sign in**
39
+
40
+ First sign in to the DeployKar dashboard in your browser, then run:
41
+
42
+ ```bash
43
+ uvx deploykar-mcp login
44
+ ```
45
+
46
+ Your browser opens DeployKar's approval page. Choose **Deploy** (recommended) or **Read-only** access
47
+ and click **Approve**. The token is saved on your computer, readable only by you:
48
+ `~/.config/deploykar/credentials.json` (Windows: `%APPDATA%\deploykar\credentials.json`).
49
+
50
+ **2. Add DeployKar to your IDE**
51
+
52
+ For Claude Code, create a file named `.mcp.json` in your project folder (or run
53
+ `claude mcp add --scope user deploykar -- uvx deploykar-mcp@latest` to add it for all projects):
54
+
55
+ ```json
56
+ {
57
+ "mcpServers": {
58
+ "deploykar": {
59
+ "command": "uvx",
60
+ "args": ["deploykar-mcp@latest"]
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ The same JSON works in other IDEs:
67
+
68
+ | IDE | Where |
69
+ |---|---|
70
+ | Cursor | `~/.cursor/mcp.json` |
71
+ | Kiro | `~/.kiro/settings/mcp.json` (or `.kiro/settings/mcp.json` in a workspace) |
72
+ | Windsurf | `~/.codeium/windsurf/mcp_config.json` |
73
+
74
+ VS Code (Copilot agent mode) uses `.vscode/mcp.json` with a slightly different shape:
75
+
76
+ ```json
77
+ {
78
+ "servers": {
79
+ "deploykar": {
80
+ "type": "stdio",
81
+ "command": "uvx",
82
+ "args": ["deploykar-mcp@latest"]
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ Open the folder in your IDE, approve the `deploykar` server when asked, and start chatting.
89
+ `@latest` means you get new versions automatically when your IDE restarts the server.
90
+
91
+ **Without the login command** (CI, remote machines, or if you prefer to paste a token): create a token
92
+ on DeployKar's API tokens page (`https://dev-32786578325.deploykar.com/auth/api/v1/api-tokens/authorize`)
93
+ and add it to the config. Don't commit a file that contains a token.
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "deploykar": {
99
+ "command": "uvx",
100
+ "args": ["deploykar-mcp@latest"],
101
+ "env": { "DEPLOYKAR_API_TOKEN": "dk_live_..." }
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ## What you can ask
108
+
109
+ - "Deploy this repo to DeployKar as a frontend"
110
+ - "Deploy my latest changes" (the assistant pushes first, then deploys and waits for the live URL)
111
+ - "Turn on auto-deploy for main"
112
+ - "Why did my last deploy fail? Fix it."
113
+ - "Show me the API's logs from the last few minutes"
114
+ - "Set DATABASE_URL to … and restart"
115
+ - "Scale the API to 3 instances"
116
+
117
+ ## Tools
118
+
119
+ | Tool | What it does |
120
+ |---|---|
121
+ | `check_setup` | Signed-in account, token access level, GitHub connection (with an install link if missing) |
122
+ | `list_projects` | Your projects with status and live URL. Pass `repo_url` to find the project for the current repo |
123
+ | `deploy` | Deploy an existing project, or create one from a GitHub repo URL (frontend or backend) |
124
+ | `get_status` | Deployment status and live URL. `wait=true` follows the build; failures include the error lines |
125
+ | `get_logs` | Build logs (`source="build"`) or live backend logs (`source="runtime"`), with `errors_only` |
126
+ | `list_env_vars` | Environment variable names (never values) |
127
+ | `set_env_var` | Create or update environment variables; `apply_now=true` restarts/redeploys |
128
+ | `scale` | Set the number of instances (1-10) of a backend service |
129
+
130
+ ## How deployments work
131
+
132
+ DeployKar builds from GitHub, not from your local files, exactly like deploying from the dashboard.
133
+ Whatever is pushed to the project's branch is what gets deployed, so the assistant commits and pushes
134
+ your changes (after asking you) before deploying. With auto-deploy enabled, every push to the branch
135
+ deploys automatically and the assistant just follows the deployment for the commit it pushed.
136
+
137
+ ## Security
138
+
139
+ - API tokens are stored hashed by DeployKar, shown once, expire after 30, 90 or 365 days, and can be
140
+ revoked at any time: `uvx deploykar-mcp logout`, or the API tokens page
141
+ (`https://dev-32786578325.deploykar.com/auth/api/v1/api-tokens/manage`).
142
+ - Tokens can only reach a fixed set of endpoints. They can **never** delete projects or deployments,
143
+ remove backends, or manage databases, domains, secret groups or other tokens.
144
+ - Read-only tokens can view projects, statuses and logs, but cannot deploy or read environment variables.
145
+ - Environment variable values are never returned to the assistant.
146
+ - Per-token rate limits apply (120 requests/minute, 30 deploy or scale actions/hour).
147
+
148
+ ## Commands
149
+
150
+ ```text
151
+ uvx deploykar-mcp run the MCP server (your IDE does this)
152
+ uvx deploykar-mcp login sign in via the browser (--no-browser to paste a token instead)
153
+ uvx deploykar-mcp whoami show the current account and token
154
+ uvx deploykar-mcp logout revoke and delete the saved token
155
+ ```
156
+
157
+ Environment variables (all optional):
158
+
159
+ | Variable | Default |
160
+ |---|---|
161
+ | `DEPLOYKAR_API_TOKEN` | the token saved by `login` |
162
+ | `DEPLOYKAR_API_URL` | `https://dev-32786578325.deploykar.com/api/v1` |
163
+ | `DEPLOYKAR_AUTH_URL` | `https://dev-32786578325.deploykar.com/auth/api/v1` |
164
+ | `DEPLOYKAR_DASHBOARD_URL` | `http://187.127.179.204:7100` |
165
+
166
+ ## Troubleshooting
167
+
168
+ - **"Not signed in" / "rejected the API token"**: run `uvx deploykar-mcp login` again, then restart
169
+ the MCP server in your IDE.
170
+ - **The approval page asks you to sign in**: sign in at http://187.127.179.204:7100 in the same
171
+ browser, then reload the approval page.
172
+ - **The server shows "Failed" or "Connection closed", or the IDE says `uvx` was not found**: your
173
+ IDE can't find `uvx`. Restart the IDE completely after installing uv. If that doesn't help, put the
174
+ full path to `uvx` in `"command"`:
175
+ - macOS/Linux: run `which uvx` and use what it prints, e.g. `/Users/you/.local/bin/uvx`
176
+ - Windows: run `where uvx` in PowerShell and use it with forward slashes, e.g.
177
+ `C:/Users/you/.local/bin/uvx.exe`. (Git Bash's `which uvx` prints `/c/Users/...`, which
178
+ Windows doesn't understand: write it as `C:/Users/...`.)
179
+ - **"This API token is read-only"**: sign in again and choose Deploy access.
180
+ - **Deployment built old code**: push your commits; DeployKar builds the latest commit on GitHub.
181
+ - **No build logs**: DeployKar keeps build logs for about an hour after a build.
182
+
183
+ ## Development
184
+
185
+ ```bash
186
+ uv run --group dev pytest
187
+ ```
188
+
189
+ Releases are published to PyPI from GitHub (see `RELEASING.md` in the repository).
190
+
191
+ ## License
192
+
193
+ MIT
@@ -0,0 +1,173 @@
1
+ # DeployKar MCP server
2
+
3
+ Deploy, monitor and debug your [DeployKar](https://deploykar.com) apps from your IDE's AI chat:
4
+ Kiro, Cursor, VS Code (Copilot), Claude Code, Windsurf, or any other MCP client.
5
+
6
+ > "Deploy my app" · "Why did my build fail?" · "Set DATABASE_URL to postgres://…" · "Scale the API to 3 instances"
7
+
8
+ Your IDE's assistant does the thinking. This server only translates its tool calls into DeployKar API
9
+ requests, using a personal API token.
10
+
11
+ ## Setup (2 minutes)
12
+
13
+ You need:
14
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/) installed (it provides the `uvx` command)
15
+ - a DeployKar account. Sign in at **http://187.127.179.204:7100**
16
+ - your app's code in a GitHub repository that DeployKar can access (connect GitHub once in the dashboard)
17
+
18
+ **1. Sign in**
19
+
20
+ First sign in to the DeployKar dashboard in your browser, then run:
21
+
22
+ ```bash
23
+ uvx deploykar-mcp login
24
+ ```
25
+
26
+ Your browser opens DeployKar's approval page. Choose **Deploy** (recommended) or **Read-only** access
27
+ and click **Approve**. The token is saved on your computer, readable only by you:
28
+ `~/.config/deploykar/credentials.json` (Windows: `%APPDATA%\deploykar\credentials.json`).
29
+
30
+ **2. Add DeployKar to your IDE**
31
+
32
+ For Claude Code, create a file named `.mcp.json` in your project folder (or run
33
+ `claude mcp add --scope user deploykar -- uvx deploykar-mcp@latest` to add it for all projects):
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "deploykar": {
39
+ "command": "uvx",
40
+ "args": ["deploykar-mcp@latest"]
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ The same JSON works in other IDEs:
47
+
48
+ | IDE | Where |
49
+ |---|---|
50
+ | Cursor | `~/.cursor/mcp.json` |
51
+ | Kiro | `~/.kiro/settings/mcp.json` (or `.kiro/settings/mcp.json` in a workspace) |
52
+ | Windsurf | `~/.codeium/windsurf/mcp_config.json` |
53
+
54
+ VS Code (Copilot agent mode) uses `.vscode/mcp.json` with a slightly different shape:
55
+
56
+ ```json
57
+ {
58
+ "servers": {
59
+ "deploykar": {
60
+ "type": "stdio",
61
+ "command": "uvx",
62
+ "args": ["deploykar-mcp@latest"]
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ Open the folder in your IDE, approve the `deploykar` server when asked, and start chatting.
69
+ `@latest` means you get new versions automatically when your IDE restarts the server.
70
+
71
+ **Without the login command** (CI, remote machines, or if you prefer to paste a token): create a token
72
+ on DeployKar's API tokens page (`https://dev-32786578325.deploykar.com/auth/api/v1/api-tokens/authorize`)
73
+ and add it to the config. Don't commit a file that contains a token.
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "deploykar": {
79
+ "command": "uvx",
80
+ "args": ["deploykar-mcp@latest"],
81
+ "env": { "DEPLOYKAR_API_TOKEN": "dk_live_..." }
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ ## What you can ask
88
+
89
+ - "Deploy this repo to DeployKar as a frontend"
90
+ - "Deploy my latest changes" (the assistant pushes first, then deploys and waits for the live URL)
91
+ - "Turn on auto-deploy for main"
92
+ - "Why did my last deploy fail? Fix it."
93
+ - "Show me the API's logs from the last few minutes"
94
+ - "Set DATABASE_URL to … and restart"
95
+ - "Scale the API to 3 instances"
96
+
97
+ ## Tools
98
+
99
+ | Tool | What it does |
100
+ |---|---|
101
+ | `check_setup` | Signed-in account, token access level, GitHub connection (with an install link if missing) |
102
+ | `list_projects` | Your projects with status and live URL. Pass `repo_url` to find the project for the current repo |
103
+ | `deploy` | Deploy an existing project, or create one from a GitHub repo URL (frontend or backend) |
104
+ | `get_status` | Deployment status and live URL. `wait=true` follows the build; failures include the error lines |
105
+ | `get_logs` | Build logs (`source="build"`) or live backend logs (`source="runtime"`), with `errors_only` |
106
+ | `list_env_vars` | Environment variable names (never values) |
107
+ | `set_env_var` | Create or update environment variables; `apply_now=true` restarts/redeploys |
108
+ | `scale` | Set the number of instances (1-10) of a backend service |
109
+
110
+ ## How deployments work
111
+
112
+ DeployKar builds from GitHub, not from your local files, exactly like deploying from the dashboard.
113
+ Whatever is pushed to the project's branch is what gets deployed, so the assistant commits and pushes
114
+ your changes (after asking you) before deploying. With auto-deploy enabled, every push to the branch
115
+ deploys automatically and the assistant just follows the deployment for the commit it pushed.
116
+
117
+ ## Security
118
+
119
+ - API tokens are stored hashed by DeployKar, shown once, expire after 30, 90 or 365 days, and can be
120
+ revoked at any time: `uvx deploykar-mcp logout`, or the API tokens page
121
+ (`https://dev-32786578325.deploykar.com/auth/api/v1/api-tokens/manage`).
122
+ - Tokens can only reach a fixed set of endpoints. They can **never** delete projects or deployments,
123
+ remove backends, or manage databases, domains, secret groups or other tokens.
124
+ - Read-only tokens can view projects, statuses and logs, but cannot deploy or read environment variables.
125
+ - Environment variable values are never returned to the assistant.
126
+ - Per-token rate limits apply (120 requests/minute, 30 deploy or scale actions/hour).
127
+
128
+ ## Commands
129
+
130
+ ```text
131
+ uvx deploykar-mcp run the MCP server (your IDE does this)
132
+ uvx deploykar-mcp login sign in via the browser (--no-browser to paste a token instead)
133
+ uvx deploykar-mcp whoami show the current account and token
134
+ uvx deploykar-mcp logout revoke and delete the saved token
135
+ ```
136
+
137
+ Environment variables (all optional):
138
+
139
+ | Variable | Default |
140
+ |---|---|
141
+ | `DEPLOYKAR_API_TOKEN` | the token saved by `login` |
142
+ | `DEPLOYKAR_API_URL` | `https://dev-32786578325.deploykar.com/api/v1` |
143
+ | `DEPLOYKAR_AUTH_URL` | `https://dev-32786578325.deploykar.com/auth/api/v1` |
144
+ | `DEPLOYKAR_DASHBOARD_URL` | `http://187.127.179.204:7100` |
145
+
146
+ ## Troubleshooting
147
+
148
+ - **"Not signed in" / "rejected the API token"**: run `uvx deploykar-mcp login` again, then restart
149
+ the MCP server in your IDE.
150
+ - **The approval page asks you to sign in**: sign in at http://187.127.179.204:7100 in the same
151
+ browser, then reload the approval page.
152
+ - **The server shows "Failed" or "Connection closed", or the IDE says `uvx` was not found**: your
153
+ IDE can't find `uvx`. Restart the IDE completely after installing uv. If that doesn't help, put the
154
+ full path to `uvx` in `"command"`:
155
+ - macOS/Linux: run `which uvx` and use what it prints, e.g. `/Users/you/.local/bin/uvx`
156
+ - Windows: run `where uvx` in PowerShell and use it with forward slashes, e.g.
157
+ `C:/Users/you/.local/bin/uvx.exe`. (Git Bash's `which uvx` prints `/c/Users/...`, which
158
+ Windows doesn't understand: write it as `C:/Users/...`.)
159
+ - **"This API token is read-only"**: sign in again and choose Deploy access.
160
+ - **Deployment built old code**: push your commits; DeployKar builds the latest commit on GitHub.
161
+ - **No build logs**: DeployKar keeps build logs for about an hour after a build.
162
+
163
+ ## Development
164
+
165
+ ```bash
166
+ uv run --group dev pytest
167
+ ```
168
+
169
+ Releases are published to PyPI from GitHub (see `RELEASING.md` in the repository).
170
+
171
+ ## License
172
+
173
+ MIT
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "deploykar-mcp"
7
+ dynamic = ["version"]
8
+ description = "MCP server for DeployKar: deploy, monitor and debug your apps from your IDE."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [{ name = "DeployKar" }]
14
+ keywords = ["deploykar", "mcp", "model-context-protocol", "deploy", "ide"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Topic :: Software Development :: Build Tools",
22
+ ]
23
+ dependencies = [
24
+ "mcp>=2.3,<3",
25
+ "httpx>=0.27",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://deploykar.com"
30
+
31
+ [project.scripts]
32
+ deploykar-mcp = "deploykar_mcp.cli:main"
33
+
34
+ [dependency-groups]
35
+ dev = ["pytest>=8"]
36
+
37
+ # The version lives in one place: src/deploykar_mcp/__init__.py (see RELEASING.md).
38
+ [tool.hatch.version]
39
+ path = "src/deploykar_mcp/__init__.py"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/deploykar_mcp"]
43
+
44
+ [tool.hatch.build.targets.sdist]
45
+ include = ["src", "tests", "README.md", "LICENSE"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
@@ -0,0 +1,3 @@
1
+ """DeployKar MCP server: deploy, monitor and debug DeployKar apps from your IDE."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,4 @@
1
+ from deploykar_mcp.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,130 @@
1
+ """Command line entry point.
2
+
3
+ deploykar-mcp run the MCP server over stdio (what your IDE launches)
4
+ deploykar-mcp login approve access in the browser and save an API token
5
+ deploykar-mcp logout revoke the saved token and delete it
6
+ deploykar-mcp whoami show the account and access level of the current token
7
+ """
8
+ import argparse
9
+ import getpass
10
+ import json
11
+ import sys
12
+
13
+ from deploykar_mcp import __version__
14
+ from deploykar_mcp.config import (
15
+ RUN_COMMAND,
16
+ UVX_ARGS,
17
+ dashboard_url,
18
+ delete_credentials,
19
+ load_settings,
20
+ save_credentials,
21
+ )
22
+ from deploykar_mcp.login import LoginError, browser_login, fetch_token_info, revoke_token
23
+
24
+ IDE_CONFIG = {"mcpServers": {"deploykar": {"command": "uvx", "args": UVX_ARGS}}}
25
+
26
+
27
+ def _err(message: str) -> None:
28
+ print(message, file=sys.stderr)
29
+
30
+
31
+ def _access(scopes: list[str] | None) -> str:
32
+ return "Deploy" if "deploy" in (scopes or []) else "Read-only"
33
+
34
+
35
+ def cmd_serve(_args) -> int:
36
+ import logging
37
+
38
+ from deploykar_mcp.server import create_server
39
+
40
+ # stdout carries the MCP protocol: never print to it here. Logs go to stderr.
41
+ logging.getLogger("httpx").setLevel(logging.WARNING)
42
+ create_server().run("stdio")
43
+ return 0
44
+
45
+
46
+ def cmd_login(args) -> int:
47
+ settings = load_settings()
48
+ api_url = (args.api_url or settings.api_url).rstrip("/")
49
+ auth_url = (args.auth_url or settings.auth_url).rstrip("/")
50
+ print(f"First, make sure you're signed in to DeployKar in your browser: {dashboard_url()}/login\n")
51
+ try:
52
+ if args.token or args.no_browser:
53
+ if args.no_browser and not args.token:
54
+ print(f"Create a token at:\n {auth_url}/api-tokens/authorize\n")
55
+ token = (args.token or getpass.getpass("Paste your DeployKar API token: ")).strip()
56
+ if not token.startswith("dk_live_"):
57
+ _err("That doesn't look like a DeployKar API token (it should start with dk_live_).")
58
+ return 1
59
+ info = fetch_token_info(api_url, token)
60
+ email, scopes = info["user"]["email"], (info.get("token") or {}).get("scopes")
61
+ else:
62
+ result = browser_login(auth_url)
63
+ token, email, scopes = result["token"], result["user"]["email"], result.get("scopes")
64
+ except LoginError as exc:
65
+ _err(f"Login failed: {exc}")
66
+ return 1
67
+ except KeyboardInterrupt:
68
+ _err("\nLogin cancelled.")
69
+ return 130
70
+
71
+ path = save_credentials(token, email, api_url, auth_url)
72
+ print(f"✓ Signed in to DeployKar as {email} ({_access(scopes)} access)")
73
+ print(f" Token saved to {path}")
74
+ if settings.token_source == "env":
75
+ print(" Note: DEPLOYKAR_API_TOKEN is set in your environment and takes precedence over the saved token.")
76
+ print("\nAdd DeployKar to your IDE's MCP settings:\n")
77
+ print(json.dumps(IDE_CONFIG, indent=2))
78
+ print("\nThen restart the MCP server in your IDE and ask: \"deploy my app to DeployKar\".")
79
+ return 0
80
+
81
+
82
+ def cmd_logout(_args) -> int:
83
+ settings = load_settings()
84
+ if settings.token_source != "file":
85
+ if settings.token_source == "env":
86
+ _err("The token comes from DEPLOYKAR_API_TOKEN; remove it from your environment/IDE config instead.")
87
+ else:
88
+ print("Not signed in.")
89
+ return 0
90
+ revoked = revoke_token(settings.auth_url, settings.token)
91
+ delete_credentials()
92
+ print("✓ Signed out. " + ("The token was revoked." if revoked else
93
+ "Could not revoke the token on the server; revoke it from the API tokens page if needed."))
94
+ return 0
95
+
96
+
97
+ def cmd_whoami(_args) -> int:
98
+ settings = load_settings()
99
+ if not settings.token:
100
+ _err(f"Not signed in. Run `{RUN_COMMAND} login`.")
101
+ return 1
102
+ try:
103
+ info = fetch_token_info(settings.api_url, settings.token)
104
+ except LoginError as exc:
105
+ _err(f"Token check failed: {exc}")
106
+ return 1
107
+ token = info.get("token") or {}
108
+ print(f"Account: {info['user']['email']}")
109
+ print(f"Token: {token.get('name')} ({token.get('prefix')}…), {_access(token.get('scopes'))} access")
110
+ print(f"Expires: {token.get('expires_at') or 'never'}")
111
+ print(f"Source: {'DEPLOYKAR_API_TOKEN' if settings.token_source == 'env' else 'saved credentials'}")
112
+ return 0
113
+
114
+
115
+ def main(argv: list[str] | None = None) -> None:
116
+ parser = argparse.ArgumentParser(prog="deploykar-mcp", description="DeployKar MCP server and login helper.")
117
+ parser.add_argument("--version", action="version", version=f"deploykar-mcp {__version__}")
118
+ sub = parser.add_subparsers(dest="command")
119
+ sub.add_parser("serve", help="run the MCP server over stdio (default)")
120
+ login = sub.add_parser("login", help="approve access in the browser and save an API token")
121
+ login.add_argument("--no-browser", action="store_true", help="paste a token created in the dashboard instead")
122
+ login.add_argument("--token", help="save this token (from the API tokens page) without opening a browser")
123
+ login.add_argument("--api-url", help=argparse.SUPPRESS)
124
+ login.add_argument("--auth-url", help=argparse.SUPPRESS)
125
+ sub.add_parser("logout", help="revoke and delete the saved token")
126
+ sub.add_parser("whoami", help="show the current account and token")
127
+ args = parser.parse_args(argv)
128
+
129
+ handlers = {None: cmd_serve, "serve": cmd_serve, "login": cmd_login, "logout": cmd_logout, "whoami": cmd_whoami}
130
+ sys.exit(handlers[args.command](args))