gitrama-mcp 1.0.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.
- gitrama_mcp-1.0.0/.gitignore +12 -0
- gitrama_mcp-1.0.0/LICENSE +21 -0
- gitrama_mcp-1.0.0/PKG-INFO +343 -0
- gitrama_mcp-1.0.0/README.md +317 -0
- gitrama_mcp-1.0.0/configs/claude_desktop_config.json +8 -0
- gitrama_mcp-1.0.0/configs/cursor_mcp.json +10 -0
- gitrama_mcp-1.0.0/configs/vscode_settings.json +12 -0
- gitrama_mcp-1.0.0/pyproject.toml +42 -0
- gitrama_mcp-1.0.0/src/gitrama_mcp/__init__.py +3 -0
- gitrama_mcp-1.0.0/src/gitrama_mcp/__main__.py +4 -0
- gitrama_mcp-1.0.0/src/gitrama_mcp/server.py +407 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alfonso Harding / One Great Dev
|
|
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,343 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gitrama-mcp
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MCP Server for Gitrama — AI-powered Git intelligence for your IDE
|
|
5
|
+
Project-URL: Homepage, https://gitrama.ai
|
|
6
|
+
Project-URL: Repository, https://github.com/onegreatdev/gitrama-mcp
|
|
7
|
+
Project-URL: Documentation, https://gitrama.ai/docs
|
|
8
|
+
Project-URL: Issues, https://github.com/onegreatdev/gitrama-mcp/issues
|
|
9
|
+
Author-email: Alfonso Harding <alfonso@onegreatdev.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: ai,claude,commit,cursor,git,gitrama,mcp
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: gitrama>=1.0.3
|
|
24
|
+
Requires-Dist: mcp>=1.2.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# 🌿 Gitrama MCP Server
|
|
28
|
+
|
|
29
|
+
> AI-powered Git intelligence for your IDE — smart commits, branch names, PR descriptions, changelogs, and workflow management.
|
|
30
|
+
|
|
31
|
+
[](https://pypi.org/project/gitrama-mcp/)
|
|
32
|
+
[](https://pypi.org/project/gitrama-mcp/)
|
|
33
|
+
[](LICENSE)
|
|
34
|
+
|
|
35
|
+
## What is this?
|
|
36
|
+
|
|
37
|
+
Gitrama MCP Server exposes [Gitrama](https://gitrama.ai)'s CLI as **10 MCP tools** that any AI assistant can use. Instead of typing `gtr commit` in your terminal, your AI assistant calls the tool directly — analyzing your code changes, generating commit messages, suggesting branch names, and more.
|
|
38
|
+
|
|
39
|
+
**Works with:** Cursor · Claude Desktop · Claude Code · Windsurf · VS Code (Copilot) · Zed · any MCP-compatible client
|
|
40
|
+
|
|
41
|
+
## Install (< 60 seconds)
|
|
42
|
+
|
|
43
|
+
### Step 1: Install the package
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install gitrama-mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or with uv:
|
|
50
|
+
```bash
|
|
51
|
+
uv pip install gitrama-mcp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This installs both the MCP server and the `gitrama` CLI.
|
|
55
|
+
|
|
56
|
+
### Step 2: Connect to your IDE
|
|
57
|
+
|
|
58
|
+
<details>
|
|
59
|
+
<summary><b>Cursor</b></summary>
|
|
60
|
+
|
|
61
|
+
Add to `.cursor/mcp.json` in your project (or global settings):
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"gitrama": {
|
|
67
|
+
"command": "gitrama-mcp"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
</details>
|
|
73
|
+
|
|
74
|
+
<details>
|
|
75
|
+
<summary><b>Claude Desktop</b></summary>
|
|
76
|
+
|
|
77
|
+
Add to `claude_desktop_config.json`:
|
|
78
|
+
|
|
79
|
+
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
80
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"gitrama": {
|
|
86
|
+
"command": "gitrama-mcp"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
<details>
|
|
94
|
+
<summary><b>Claude Code</b></summary>
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
claude mcp add gitrama gitrama-mcp
|
|
98
|
+
```
|
|
99
|
+
</details>
|
|
100
|
+
|
|
101
|
+
<details>
|
|
102
|
+
<summary><b>VS Code (Copilot)</b></summary>
|
|
103
|
+
|
|
104
|
+
Add to `.vscode/settings.json`:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"mcp": {
|
|
109
|
+
"servers": {
|
|
110
|
+
"gitrama": {
|
|
111
|
+
"command": "gitrama-mcp"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
</details>
|
|
118
|
+
|
|
119
|
+
<details>
|
|
120
|
+
<summary><b>Windsurf</b></summary>
|
|
121
|
+
|
|
122
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"mcpServers": {
|
|
127
|
+
"gitrama": {
|
|
128
|
+
"command": "gitrama-mcp"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
</details>
|
|
134
|
+
|
|
135
|
+
<details>
|
|
136
|
+
<summary><b>Zed</b></summary>
|
|
137
|
+
|
|
138
|
+
Add to Zed settings (`⌘,`):
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"context_servers": {
|
|
143
|
+
"gitrama": {
|
|
144
|
+
"command": {
|
|
145
|
+
"path": "gitrama-mcp"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
</details>
|
|
152
|
+
|
|
153
|
+
### Step 3: Done.
|
|
154
|
+
|
|
155
|
+
Ask your AI: *"Commit my staged changes"* — and watch it call `gitrama_commit`.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Tools (10)
|
|
160
|
+
|
|
161
|
+
### Commit Intelligence
|
|
162
|
+
|
|
163
|
+
| Tool | Description |
|
|
164
|
+
|------|-------------|
|
|
165
|
+
| `gitrama_commit` | Generate an AI commit message for staged changes |
|
|
166
|
+
| `gitrama_stage_and_commit` | Stage files + commit in one step |
|
|
167
|
+
| `gitrama_commit_quality` | Analyze quality of recent commit messages |
|
|
168
|
+
|
|
169
|
+
### Branch Management
|
|
170
|
+
|
|
171
|
+
| Tool | Description |
|
|
172
|
+
|------|-------------|
|
|
173
|
+
| `gitrama_branch` | Create a new branch |
|
|
174
|
+
| `gitrama_branch_suggest` | Get AI-suggested branch names from a description |
|
|
175
|
+
|
|
176
|
+
### PR & Changelog
|
|
177
|
+
|
|
178
|
+
| Tool | Description |
|
|
179
|
+
|------|-------------|
|
|
180
|
+
| `gitrama_pr` | Generate a PR description from branch diff |
|
|
181
|
+
| `gitrama_changelog` | Generate a changelog between refs |
|
|
182
|
+
|
|
183
|
+
### Stream (Workflow) Management
|
|
184
|
+
|
|
185
|
+
| Tool | Description |
|
|
186
|
+
|------|-------------|
|
|
187
|
+
| `gitrama_stream_status` | Show current workflow stream |
|
|
188
|
+
| `gitrama_stream_switch` | Switch to a different stream |
|
|
189
|
+
| `gitrama_stream_list` | List all streams in the repo |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Tool Details
|
|
194
|
+
|
|
195
|
+
### `gitrama_commit`
|
|
196
|
+
|
|
197
|
+
Generate an AI-powered commit message for staged changes.
|
|
198
|
+
|
|
199
|
+
**Parameters:**
|
|
200
|
+
| Parameter | Type | Default | Description |
|
|
201
|
+
|-----------|------|---------|-------------|
|
|
202
|
+
| `message_type` | string | `"conventional"` | Style: `"conventional"`, `"detailed"`, or `"simple"` |
|
|
203
|
+
| `context` | string | `""` | Optional context (e.g., `"fixing auth bug"`) |
|
|
204
|
+
| `model` | string | `""` | AI model override (e.g., `"gpt-4o"`, `"claude-sonnet-4-20250514"`) |
|
|
205
|
+
|
|
206
|
+
**Example prompt:** *"Commit my changes with a conventional message, context: refactoring the payment module"*
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### `gitrama_stage_and_commit`
|
|
211
|
+
|
|
212
|
+
Stage files and commit in one step.
|
|
213
|
+
|
|
214
|
+
**Parameters:**
|
|
215
|
+
| Parameter | Type | Default | Description |
|
|
216
|
+
|-----------|------|---------|-------------|
|
|
217
|
+
| `files` | string | `"."` | Files to stage (`.` for all, or space-separated paths) |
|
|
218
|
+
| `message_type` | string | `"conventional"` | Commit style |
|
|
219
|
+
| `context` | string | `""` | Optional context |
|
|
220
|
+
| `model` | string | `""` | AI model override |
|
|
221
|
+
|
|
222
|
+
**Example prompt:** *"Stage and commit all my changes"*
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### `gitrama_commit_quality`
|
|
227
|
+
|
|
228
|
+
Analyze recent commit message quality.
|
|
229
|
+
|
|
230
|
+
**Parameters:**
|
|
231
|
+
| Parameter | Type | Default | Description |
|
|
232
|
+
|-----------|------|---------|-------------|
|
|
233
|
+
| `count` | int | `10` | Number of commits to analyze (1-50) |
|
|
234
|
+
|
|
235
|
+
**Example prompt:** *"How good are our last 20 commit messages?"*
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### `gitrama_branch_suggest`
|
|
240
|
+
|
|
241
|
+
Get AI-suggested branch names.
|
|
242
|
+
|
|
243
|
+
**Parameters:**
|
|
244
|
+
| Parameter | Type | Default | Description |
|
|
245
|
+
|-----------|------|---------|-------------|
|
|
246
|
+
| `description` | string | *required* | Task description |
|
|
247
|
+
| `model` | string | `""` | AI model override |
|
|
248
|
+
|
|
249
|
+
**Example prompt:** *"Suggest a branch name for adding OAuth2 support"*
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
### `gitrama_pr`
|
|
254
|
+
|
|
255
|
+
Generate a PR description.
|
|
256
|
+
|
|
257
|
+
**Parameters:**
|
|
258
|
+
| Parameter | Type | Default | Description |
|
|
259
|
+
|-----------|------|---------|-------------|
|
|
260
|
+
| `base` | string | `""` | Target branch (default: main/master) |
|
|
261
|
+
| `model` | string | `""` | AI model override |
|
|
262
|
+
|
|
263
|
+
**Example prompt:** *"Write a PR description for this branch"*
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### `gitrama_changelog`
|
|
268
|
+
|
|
269
|
+
Generate a changelog.
|
|
270
|
+
|
|
271
|
+
**Parameters:**
|
|
272
|
+
| Parameter | Type | Default | Description |
|
|
273
|
+
|-----------|------|---------|-------------|
|
|
274
|
+
| `since` | string | `""` | Start ref (tag, branch, hash) |
|
|
275
|
+
| `until` | string | `""` | End ref (default: HEAD) |
|
|
276
|
+
| `format` | string | `"markdown"` | `"markdown"` or `"json"` |
|
|
277
|
+
| `model` | string | `""` | AI model override |
|
|
278
|
+
|
|
279
|
+
**Example prompt:** *"Generate a changelog since v1.0.0"*
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Configuration
|
|
284
|
+
|
|
285
|
+
### Environment Variables
|
|
286
|
+
|
|
287
|
+
| Variable | Default | Description |
|
|
288
|
+
|----------|---------|-------------|
|
|
289
|
+
| `GTR_CWD` | `os.getcwd()` | Working directory for git operations |
|
|
290
|
+
| `GTR_MCP_TRANSPORT` | `"stdio"` | Transport: `"stdio"` or `"streamable-http"` |
|
|
291
|
+
| `GTR_MCP_HOST` | `"0.0.0.0"` | HTTP host (when using streamable-http) |
|
|
292
|
+
| `GTR_MCP_PORT` | `"8765"` | HTTP port (when using streamable-http) |
|
|
293
|
+
|
|
294
|
+
### HTTP Transport (for CI/CD)
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
GTR_MCP_TRANSPORT=streamable-http GTR_MCP_PORT=8765 gitrama-mcp
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Then connect your client to `http://localhost:8765/mcp`.
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Requirements
|
|
305
|
+
|
|
306
|
+
- Python 3.10+
|
|
307
|
+
- Git installed and in PATH
|
|
308
|
+
- A Gitrama API key or local Ollama instance
|
|
309
|
+
|
|
310
|
+
Set your API key:
|
|
311
|
+
```bash
|
|
312
|
+
gtr config --key YOUR_API_KEY
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Or use a local model:
|
|
316
|
+
```bash
|
|
317
|
+
gtr config --provider ollama --model llama3
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Development
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
git clone https://github.com/onegreatdev/gitrama-mcp.git
|
|
326
|
+
cd gitrama-mcp
|
|
327
|
+
pip install -e ".[dev]"
|
|
328
|
+
|
|
329
|
+
# Test with MCP Inspector
|
|
330
|
+
mcp dev src/gitrama_mcp/server.py
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
MIT — see [LICENSE](LICENSE).
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
Built by [Alfonso Harding](https://linkedin.com/in/alfonsoharding) · [gitrama.ai](https://gitrama.ai)
|
|
342
|
+
|
|
343
|
+
🌿
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# 🌿 Gitrama MCP Server
|
|
2
|
+
|
|
3
|
+
> AI-powered Git intelligence for your IDE — smart commits, branch names, PR descriptions, changelogs, and workflow management.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/gitrama-mcp/)
|
|
6
|
+
[](https://pypi.org/project/gitrama-mcp/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## What is this?
|
|
10
|
+
|
|
11
|
+
Gitrama MCP Server exposes [Gitrama](https://gitrama.ai)'s CLI as **10 MCP tools** that any AI assistant can use. Instead of typing `gtr commit` in your terminal, your AI assistant calls the tool directly — analyzing your code changes, generating commit messages, suggesting branch names, and more.
|
|
12
|
+
|
|
13
|
+
**Works with:** Cursor · Claude Desktop · Claude Code · Windsurf · VS Code (Copilot) · Zed · any MCP-compatible client
|
|
14
|
+
|
|
15
|
+
## Install (< 60 seconds)
|
|
16
|
+
|
|
17
|
+
### Step 1: Install the package
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install gitrama-mcp
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or with uv:
|
|
24
|
+
```bash
|
|
25
|
+
uv pip install gitrama-mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This installs both the MCP server and the `gitrama` CLI.
|
|
29
|
+
|
|
30
|
+
### Step 2: Connect to your IDE
|
|
31
|
+
|
|
32
|
+
<details>
|
|
33
|
+
<summary><b>Cursor</b></summary>
|
|
34
|
+
|
|
35
|
+
Add to `.cursor/mcp.json` in your project (or global settings):
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"gitrama": {
|
|
41
|
+
"command": "gitrama-mcp"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
</details>
|
|
47
|
+
|
|
48
|
+
<details>
|
|
49
|
+
<summary><b>Claude Desktop</b></summary>
|
|
50
|
+
|
|
51
|
+
Add to `claude_desktop_config.json`:
|
|
52
|
+
|
|
53
|
+
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
54
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"gitrama": {
|
|
60
|
+
"command": "gitrama-mcp"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
</details>
|
|
66
|
+
|
|
67
|
+
<details>
|
|
68
|
+
<summary><b>Claude Code</b></summary>
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
claude mcp add gitrama gitrama-mcp
|
|
72
|
+
```
|
|
73
|
+
</details>
|
|
74
|
+
|
|
75
|
+
<details>
|
|
76
|
+
<summary><b>VS Code (Copilot)</b></summary>
|
|
77
|
+
|
|
78
|
+
Add to `.vscode/settings.json`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"mcp": {
|
|
83
|
+
"servers": {
|
|
84
|
+
"gitrama": {
|
|
85
|
+
"command": "gitrama-mcp"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
<details>
|
|
94
|
+
<summary><b>Windsurf</b></summary>
|
|
95
|
+
|
|
96
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"gitrama": {
|
|
102
|
+
"command": "gitrama-mcp"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
</details>
|
|
108
|
+
|
|
109
|
+
<details>
|
|
110
|
+
<summary><b>Zed</b></summary>
|
|
111
|
+
|
|
112
|
+
Add to Zed settings (`⌘,`):
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"context_servers": {
|
|
117
|
+
"gitrama": {
|
|
118
|
+
"command": {
|
|
119
|
+
"path": "gitrama-mcp"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
</details>
|
|
126
|
+
|
|
127
|
+
### Step 3: Done.
|
|
128
|
+
|
|
129
|
+
Ask your AI: *"Commit my staged changes"* — and watch it call `gitrama_commit`.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Tools (10)
|
|
134
|
+
|
|
135
|
+
### Commit Intelligence
|
|
136
|
+
|
|
137
|
+
| Tool | Description |
|
|
138
|
+
|------|-------------|
|
|
139
|
+
| `gitrama_commit` | Generate an AI commit message for staged changes |
|
|
140
|
+
| `gitrama_stage_and_commit` | Stage files + commit in one step |
|
|
141
|
+
| `gitrama_commit_quality` | Analyze quality of recent commit messages |
|
|
142
|
+
|
|
143
|
+
### Branch Management
|
|
144
|
+
|
|
145
|
+
| Tool | Description |
|
|
146
|
+
|------|-------------|
|
|
147
|
+
| `gitrama_branch` | Create a new branch |
|
|
148
|
+
| `gitrama_branch_suggest` | Get AI-suggested branch names from a description |
|
|
149
|
+
|
|
150
|
+
### PR & Changelog
|
|
151
|
+
|
|
152
|
+
| Tool | Description |
|
|
153
|
+
|------|-------------|
|
|
154
|
+
| `gitrama_pr` | Generate a PR description from branch diff |
|
|
155
|
+
| `gitrama_changelog` | Generate a changelog between refs |
|
|
156
|
+
|
|
157
|
+
### Stream (Workflow) Management
|
|
158
|
+
|
|
159
|
+
| Tool | Description |
|
|
160
|
+
|------|-------------|
|
|
161
|
+
| `gitrama_stream_status` | Show current workflow stream |
|
|
162
|
+
| `gitrama_stream_switch` | Switch to a different stream |
|
|
163
|
+
| `gitrama_stream_list` | List all streams in the repo |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Tool Details
|
|
168
|
+
|
|
169
|
+
### `gitrama_commit`
|
|
170
|
+
|
|
171
|
+
Generate an AI-powered commit message for staged changes.
|
|
172
|
+
|
|
173
|
+
**Parameters:**
|
|
174
|
+
| Parameter | Type | Default | Description |
|
|
175
|
+
|-----------|------|---------|-------------|
|
|
176
|
+
| `message_type` | string | `"conventional"` | Style: `"conventional"`, `"detailed"`, or `"simple"` |
|
|
177
|
+
| `context` | string | `""` | Optional context (e.g., `"fixing auth bug"`) |
|
|
178
|
+
| `model` | string | `""` | AI model override (e.g., `"gpt-4o"`, `"claude-sonnet-4-20250514"`) |
|
|
179
|
+
|
|
180
|
+
**Example prompt:** *"Commit my changes with a conventional message, context: refactoring the payment module"*
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### `gitrama_stage_and_commit`
|
|
185
|
+
|
|
186
|
+
Stage files and commit in one step.
|
|
187
|
+
|
|
188
|
+
**Parameters:**
|
|
189
|
+
| Parameter | Type | Default | Description |
|
|
190
|
+
|-----------|------|---------|-------------|
|
|
191
|
+
| `files` | string | `"."` | Files to stage (`.` for all, or space-separated paths) |
|
|
192
|
+
| `message_type` | string | `"conventional"` | Commit style |
|
|
193
|
+
| `context` | string | `""` | Optional context |
|
|
194
|
+
| `model` | string | `""` | AI model override |
|
|
195
|
+
|
|
196
|
+
**Example prompt:** *"Stage and commit all my changes"*
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### `gitrama_commit_quality`
|
|
201
|
+
|
|
202
|
+
Analyze recent commit message quality.
|
|
203
|
+
|
|
204
|
+
**Parameters:**
|
|
205
|
+
| Parameter | Type | Default | Description |
|
|
206
|
+
|-----------|------|---------|-------------|
|
|
207
|
+
| `count` | int | `10` | Number of commits to analyze (1-50) |
|
|
208
|
+
|
|
209
|
+
**Example prompt:** *"How good are our last 20 commit messages?"*
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### `gitrama_branch_suggest`
|
|
214
|
+
|
|
215
|
+
Get AI-suggested branch names.
|
|
216
|
+
|
|
217
|
+
**Parameters:**
|
|
218
|
+
| Parameter | Type | Default | Description |
|
|
219
|
+
|-----------|------|---------|-------------|
|
|
220
|
+
| `description` | string | *required* | Task description |
|
|
221
|
+
| `model` | string | `""` | AI model override |
|
|
222
|
+
|
|
223
|
+
**Example prompt:** *"Suggest a branch name for adding OAuth2 support"*
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### `gitrama_pr`
|
|
228
|
+
|
|
229
|
+
Generate a PR description.
|
|
230
|
+
|
|
231
|
+
**Parameters:**
|
|
232
|
+
| Parameter | Type | Default | Description |
|
|
233
|
+
|-----------|------|---------|-------------|
|
|
234
|
+
| `base` | string | `""` | Target branch (default: main/master) |
|
|
235
|
+
| `model` | string | `""` | AI model override |
|
|
236
|
+
|
|
237
|
+
**Example prompt:** *"Write a PR description for this branch"*
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### `gitrama_changelog`
|
|
242
|
+
|
|
243
|
+
Generate a changelog.
|
|
244
|
+
|
|
245
|
+
**Parameters:**
|
|
246
|
+
| Parameter | Type | Default | Description |
|
|
247
|
+
|-----------|------|---------|-------------|
|
|
248
|
+
| `since` | string | `""` | Start ref (tag, branch, hash) |
|
|
249
|
+
| `until` | string | `""` | End ref (default: HEAD) |
|
|
250
|
+
| `format` | string | `"markdown"` | `"markdown"` or `"json"` |
|
|
251
|
+
| `model` | string | `""` | AI model override |
|
|
252
|
+
|
|
253
|
+
**Example prompt:** *"Generate a changelog since v1.0.0"*
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Configuration
|
|
258
|
+
|
|
259
|
+
### Environment Variables
|
|
260
|
+
|
|
261
|
+
| Variable | Default | Description |
|
|
262
|
+
|----------|---------|-------------|
|
|
263
|
+
| `GTR_CWD` | `os.getcwd()` | Working directory for git operations |
|
|
264
|
+
| `GTR_MCP_TRANSPORT` | `"stdio"` | Transport: `"stdio"` or `"streamable-http"` |
|
|
265
|
+
| `GTR_MCP_HOST` | `"0.0.0.0"` | HTTP host (when using streamable-http) |
|
|
266
|
+
| `GTR_MCP_PORT` | `"8765"` | HTTP port (when using streamable-http) |
|
|
267
|
+
|
|
268
|
+
### HTTP Transport (for CI/CD)
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
GTR_MCP_TRANSPORT=streamable-http GTR_MCP_PORT=8765 gitrama-mcp
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Then connect your client to `http://localhost:8765/mcp`.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Requirements
|
|
279
|
+
|
|
280
|
+
- Python 3.10+
|
|
281
|
+
- Git installed and in PATH
|
|
282
|
+
- A Gitrama API key or local Ollama instance
|
|
283
|
+
|
|
284
|
+
Set your API key:
|
|
285
|
+
```bash
|
|
286
|
+
gtr config --key YOUR_API_KEY
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Or use a local model:
|
|
290
|
+
```bash
|
|
291
|
+
gtr config --provider ollama --model llama3
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Development
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
git clone https://github.com/onegreatdev/gitrama-mcp.git
|
|
300
|
+
cd gitrama-mcp
|
|
301
|
+
pip install -e ".[dev]"
|
|
302
|
+
|
|
303
|
+
# Test with MCP Inspector
|
|
304
|
+
mcp dev src/gitrama_mcp/server.py
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
MIT — see [LICENSE](LICENSE).
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
Built by [Alfonso Harding](https://linkedin.com/in/alfonsoharding) · [gitrama.ai](https://gitrama.ai)
|
|
316
|
+
|
|
317
|
+
🌿
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "gitrama-mcp"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "MCP Server for Gitrama — AI-powered Git intelligence for your IDE"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Alfonso Harding", email = "alfonso@onegreatdev.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["mcp", "git", "ai", "commit", "gitrama", "cursor", "claude"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Topic :: Software Development :: Version Control :: Git",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"mcp>=1.2.0",
|
|
29
|
+
"gitrama>=1.0.3",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://gitrama.ai"
|
|
34
|
+
Repository = "https://github.com/onegreatdev/gitrama-mcp"
|
|
35
|
+
Documentation = "https://gitrama.ai/docs"
|
|
36
|
+
Issues = "https://github.com/onegreatdev/gitrama-mcp/issues"
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
gitrama-mcp = "gitrama_mcp.server:main"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.wheel]
|
|
42
|
+
packages = ["src/gitrama_mcp"]
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Gitrama MCP Server — 10 tools for AI-powered Git intelligence.
|
|
3
|
+
|
|
4
|
+
Exposes Gitrama's CLI capabilities as MCP tools for use in:
|
|
5
|
+
- Cursor
|
|
6
|
+
- Claude Desktop
|
|
7
|
+
- Claude Code
|
|
8
|
+
- Windsurf
|
|
9
|
+
- VS Code (Copilot)
|
|
10
|
+
- Zed
|
|
11
|
+
- CI/CD pipelines
|
|
12
|
+
|
|
13
|
+
Transport: stdio (default) or streamable-http
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
from typing import Optional
|
|
22
|
+
|
|
23
|
+
from mcp.server.fastmcp import FastMCP
|
|
24
|
+
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
# Server initialisation
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
mcp = FastMCP(
|
|
30
|
+
"gitrama",
|
|
31
|
+
instructions=(
|
|
32
|
+
"AI-powered Git intelligence — smart commits, branch naming, "
|
|
33
|
+
"PR descriptions, changelogs, and stream-based workflow management. "
|
|
34
|
+
"Requires `gitrama` CLI installed (pip install gitrama)."
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
# Helpers
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
def _get_cwd() -> str:
|
|
43
|
+
"""Return the working directory — prefer GTR_CWD env var, then os.getcwd()."""
|
|
44
|
+
return os.environ.get("GTR_CWD", os.getcwd())
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def _run_gtr(args: list[str], cwd: Optional[str] = None, timeout: int = 120) -> dict:
|
|
48
|
+
"""
|
|
49
|
+
Run a `gtr` CLI command and return structured output.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
dict with keys: success (bool), stdout (str), stderr (str), returncode (int)
|
|
53
|
+
"""
|
|
54
|
+
cmd = ["gtr"] + args
|
|
55
|
+
work_dir = cwd or _get_cwd()
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
proc = await asyncio.create_subprocess_exec(
|
|
59
|
+
*cmd,
|
|
60
|
+
stdout=asyncio.subprocess.PIPE,
|
|
61
|
+
stderr=asyncio.subprocess.PIPE,
|
|
62
|
+
cwd=work_dir,
|
|
63
|
+
)
|
|
64
|
+
stdout_bytes, stderr_bytes = await asyncio.wait_for(
|
|
65
|
+
proc.communicate(), timeout=timeout
|
|
66
|
+
)
|
|
67
|
+
stdout = stdout_bytes.decode("utf-8", errors="replace").strip()
|
|
68
|
+
stderr = stderr_bytes.decode("utf-8", errors="replace").strip()
|
|
69
|
+
return {
|
|
70
|
+
"success": proc.returncode == 0,
|
|
71
|
+
"stdout": stdout,
|
|
72
|
+
"stderr": stderr,
|
|
73
|
+
"returncode": proc.returncode,
|
|
74
|
+
}
|
|
75
|
+
except asyncio.TimeoutError:
|
|
76
|
+
return {
|
|
77
|
+
"success": False,
|
|
78
|
+
"stdout": "",
|
|
79
|
+
"stderr": f"Command timed out after {timeout}s: {' '.join(cmd)}",
|
|
80
|
+
"returncode": -1,
|
|
81
|
+
}
|
|
82
|
+
except FileNotFoundError:
|
|
83
|
+
return {
|
|
84
|
+
"success": False,
|
|
85
|
+
"stdout": "",
|
|
86
|
+
"stderr": (
|
|
87
|
+
"gitrama CLI not found. Install with: pip install gitrama\n"
|
|
88
|
+
"Docs: https://gitrama.ai"
|
|
89
|
+
),
|
|
90
|
+
"returncode": -1,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _format_result(result: dict, context: str = "") -> str:
|
|
95
|
+
"""Format a CLI result into a clean MCP response."""
|
|
96
|
+
if result["success"]:
|
|
97
|
+
return result["stdout"] if result["stdout"] else f"✅ {context or 'Done'}"
|
|
98
|
+
else:
|
|
99
|
+
msg = result["stderr"] or result["stdout"] or "Unknown error"
|
|
100
|
+
return f"❌ Error: {msg}"
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# ---------------------------------------------------------------------------
|
|
104
|
+
# Tool 1: gitrama_commit
|
|
105
|
+
# ---------------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
@mcp.tool()
|
|
108
|
+
async def gitrama_commit(
|
|
109
|
+
message_type: str = "conventional",
|
|
110
|
+
context: str = "",
|
|
111
|
+
model: str = "",
|
|
112
|
+
) -> str:
|
|
113
|
+
"""
|
|
114
|
+
Generate an AI-powered commit message for currently staged changes.
|
|
115
|
+
|
|
116
|
+
Analyzes the git diff of staged files and produces a high-quality,
|
|
117
|
+
contextual commit message. Requires files to be staged first (git add).
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
message_type: Commit message style — "conventional" (default),
|
|
121
|
+
"detailed", or "simple".
|
|
122
|
+
context: Optional context to guide the AI (e.g., "fixing auth bug",
|
|
123
|
+
"refactoring payment module").
|
|
124
|
+
model: Optional AI model override (e.g., "gpt-4o", "claude-sonnet-4-20250514",
|
|
125
|
+
"ollama/llama3").
|
|
126
|
+
"""
|
|
127
|
+
args = ["commit", "--type", message_type]
|
|
128
|
+
if context:
|
|
129
|
+
args.extend(["--context", context])
|
|
130
|
+
if model:
|
|
131
|
+
args.extend(["--model", model])
|
|
132
|
+
# Use --yes to auto-confirm in non-interactive mode
|
|
133
|
+
args.append("--yes")
|
|
134
|
+
|
|
135
|
+
result = await _run_gtr(args)
|
|
136
|
+
return _format_result(result, "Commit created")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# ---------------------------------------------------------------------------
|
|
140
|
+
# Tool 2: gitrama_stage_and_commit
|
|
141
|
+
# ---------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
@mcp.tool()
|
|
144
|
+
async def gitrama_stage_and_commit(
|
|
145
|
+
files: str = ".",
|
|
146
|
+
message_type: str = "conventional",
|
|
147
|
+
context: str = "",
|
|
148
|
+
model: str = "",
|
|
149
|
+
) -> str:
|
|
150
|
+
"""
|
|
151
|
+
Stage files and create an AI-powered commit in one step.
|
|
152
|
+
|
|
153
|
+
Equivalent to `git add <files> && gtr commit`. Stages the specified
|
|
154
|
+
files (or all changes), then generates and applies an AI commit message.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
files: Files to stage — "." for all changes (default), or
|
|
158
|
+
space-separated paths (e.g., "src/auth.py tests/test_auth.py").
|
|
159
|
+
message_type: Commit style — "conventional", "detailed", or "simple".
|
|
160
|
+
context: Optional context to guide the AI.
|
|
161
|
+
model: Optional AI model override.
|
|
162
|
+
"""
|
|
163
|
+
# Stage files first
|
|
164
|
+
file_list = files.split() if files != "." else ["."]
|
|
165
|
+
stage_cmd = ["git", "add"] + file_list
|
|
166
|
+
try:
|
|
167
|
+
stage_proc = await asyncio.create_subprocess_exec(
|
|
168
|
+
*stage_cmd,
|
|
169
|
+
stdout=asyncio.subprocess.PIPE,
|
|
170
|
+
stderr=asyncio.subprocess.PIPE,
|
|
171
|
+
cwd=_get_cwd(),
|
|
172
|
+
)
|
|
173
|
+
await stage_proc.communicate()
|
|
174
|
+
except Exception as e:
|
|
175
|
+
return f"❌ Failed to stage files: {e}"
|
|
176
|
+
|
|
177
|
+
# Now commit
|
|
178
|
+
return await gitrama_commit(
|
|
179
|
+
message_type=message_type,
|
|
180
|
+
context=context,
|
|
181
|
+
model=model,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# ---------------------------------------------------------------------------
|
|
186
|
+
# Tool 3: gitrama_commit_quality
|
|
187
|
+
# ---------------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
@mcp.tool()
|
|
190
|
+
async def gitrama_commit_quality(
|
|
191
|
+
count: int = 10,
|
|
192
|
+
) -> str:
|
|
193
|
+
"""
|
|
194
|
+
Analyze the quality of recent commit messages in the repository.
|
|
195
|
+
|
|
196
|
+
Scores commits on clarity, specificity, and conventional format adherence.
|
|
197
|
+
Returns a quality report with per-commit scores and suggestions.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
count: Number of recent commits to analyze (default: 10, max: 50).
|
|
201
|
+
"""
|
|
202
|
+
count = min(max(count, 1), 50)
|
|
203
|
+
result = await _run_gtr(["commit", "--quality", "--count", str(count)])
|
|
204
|
+
return _format_result(result, "Commit quality analysis complete")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# ---------------------------------------------------------------------------
|
|
208
|
+
# Tool 4: gitrama_branch
|
|
209
|
+
# ---------------------------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
@mcp.tool()
|
|
212
|
+
async def gitrama_branch(
|
|
213
|
+
name: str,
|
|
214
|
+
base: str = "",
|
|
215
|
+
) -> str:
|
|
216
|
+
"""
|
|
217
|
+
Create a new git branch with the specified name.
|
|
218
|
+
|
|
219
|
+
Creates and checks out a new branch. Use gitrama_branch_suggest to
|
|
220
|
+
get AI-suggested branch names first.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
name: Branch name (e.g., "feat/user-auth", "fix/payment-timeout").
|
|
224
|
+
base: Base branch to create from (default: current branch).
|
|
225
|
+
"""
|
|
226
|
+
args = ["branch", name]
|
|
227
|
+
if base:
|
|
228
|
+
args.extend(["--base", base])
|
|
229
|
+
result = await _run_gtr(args)
|
|
230
|
+
return _format_result(result, f"Branch '{name}' created")
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# ---------------------------------------------------------------------------
|
|
234
|
+
# Tool 5: gitrama_branch_suggest
|
|
235
|
+
# ---------------------------------------------------------------------------
|
|
236
|
+
|
|
237
|
+
@mcp.tool()
|
|
238
|
+
async def gitrama_branch_suggest(
|
|
239
|
+
description: str,
|
|
240
|
+
model: str = "",
|
|
241
|
+
) -> str:
|
|
242
|
+
"""
|
|
243
|
+
Get AI-suggested branch names based on a task description.
|
|
244
|
+
|
|
245
|
+
Analyzes the description and suggests properly formatted branch names
|
|
246
|
+
following conventional patterns (feat/, fix/, chore/, etc.).
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
description: What you're working on (e.g., "add user authentication
|
|
250
|
+
with OAuth2", "fix timeout in payment processing").
|
|
251
|
+
model: Optional AI model override.
|
|
252
|
+
"""
|
|
253
|
+
args = ["branch", "--suggest", description]
|
|
254
|
+
if model:
|
|
255
|
+
args.extend(["--model", model])
|
|
256
|
+
result = await _run_gtr(args)
|
|
257
|
+
return _format_result(result, "Branch suggestions generated")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
# ---------------------------------------------------------------------------
|
|
261
|
+
# Tool 6: gitrama_pr
|
|
262
|
+
# ---------------------------------------------------------------------------
|
|
263
|
+
|
|
264
|
+
@mcp.tool()
|
|
265
|
+
async def gitrama_pr(
|
|
266
|
+
base: str = "",
|
|
267
|
+
model: str = "",
|
|
268
|
+
) -> str:
|
|
269
|
+
"""
|
|
270
|
+
Generate an AI-powered pull request description.
|
|
271
|
+
|
|
272
|
+
Analyzes the diff between the current branch and the base branch,
|
|
273
|
+
then generates a comprehensive PR description with title, summary,
|
|
274
|
+
changes list, and testing notes.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
base: Target branch for the PR (default: main or master).
|
|
278
|
+
model: Optional AI model override.
|
|
279
|
+
"""
|
|
280
|
+
args = ["pr"]
|
|
281
|
+
if base:
|
|
282
|
+
args.extend(["--base", base])
|
|
283
|
+
if model:
|
|
284
|
+
args.extend(["--model", model])
|
|
285
|
+
result = await _run_gtr(args)
|
|
286
|
+
return _format_result(result, "PR description generated")
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
# ---------------------------------------------------------------------------
|
|
290
|
+
# Tool 7: gitrama_changelog
|
|
291
|
+
# ---------------------------------------------------------------------------
|
|
292
|
+
|
|
293
|
+
@mcp.tool()
|
|
294
|
+
async def gitrama_changelog(
|
|
295
|
+
since: str = "",
|
|
296
|
+
until: str = "",
|
|
297
|
+
format: str = "markdown",
|
|
298
|
+
model: str = "",
|
|
299
|
+
) -> str:
|
|
300
|
+
"""
|
|
301
|
+
Generate an AI-powered changelog from commit history.
|
|
302
|
+
|
|
303
|
+
Groups commits by type (features, fixes, etc.) and produces a
|
|
304
|
+
human-readable changelog. Great for release notes.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
since: Start ref — tag, branch, or commit hash (e.g., "v1.0.0").
|
|
308
|
+
Defaults to the last tag.
|
|
309
|
+
until: End ref (default: HEAD).
|
|
310
|
+
format: Output format — "markdown" (default) or "json".
|
|
311
|
+
model: Optional AI model override.
|
|
312
|
+
"""
|
|
313
|
+
args = ["changelog"]
|
|
314
|
+
if since:
|
|
315
|
+
args.extend(["--since", since])
|
|
316
|
+
if until:
|
|
317
|
+
args.extend(["--until", until])
|
|
318
|
+
if format:
|
|
319
|
+
args.extend(["--format", format])
|
|
320
|
+
if model:
|
|
321
|
+
args.extend(["--model", model])
|
|
322
|
+
result = await _run_gtr(args)
|
|
323
|
+
return _format_result(result, "Changelog generated")
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
# ---------------------------------------------------------------------------
|
|
327
|
+
# Tool 8: gitrama_stream_status
|
|
328
|
+
# ---------------------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
@mcp.tool()
|
|
331
|
+
async def gitrama_stream_status() -> str:
|
|
332
|
+
"""
|
|
333
|
+
Show the current Gitrama stream (workflow context).
|
|
334
|
+
|
|
335
|
+
Streams are Gitrama's concept of workflow focus — they track what
|
|
336
|
+
you're working on and influence AI suggestions. Returns the active
|
|
337
|
+
stream name, description, and associated branch.
|
|
338
|
+
"""
|
|
339
|
+
result = await _run_gtr(["stream", "status"])
|
|
340
|
+
return _format_result(result, "Stream status retrieved")
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
# ---------------------------------------------------------------------------
|
|
344
|
+
# Tool 9: gitrama_stream_switch
|
|
345
|
+
# ---------------------------------------------------------------------------
|
|
346
|
+
|
|
347
|
+
@mcp.tool()
|
|
348
|
+
async def gitrama_stream_switch(
|
|
349
|
+
name: str,
|
|
350
|
+
description: str = "",
|
|
351
|
+
) -> str:
|
|
352
|
+
"""
|
|
353
|
+
Switch to a different Gitrama stream (workflow context).
|
|
354
|
+
|
|
355
|
+
Creates a new stream or switches to an existing one. Streams help
|
|
356
|
+
the AI understand what you're working on for better suggestions.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
name: Stream name (e.g., "auth-refactor", "payment-v2").
|
|
360
|
+
description: Optional description of the stream's purpose.
|
|
361
|
+
"""
|
|
362
|
+
args = ["stream", "switch", name]
|
|
363
|
+
if description:
|
|
364
|
+
args.extend(["--description", description])
|
|
365
|
+
result = await _run_gtr(args)
|
|
366
|
+
return _format_result(result, f"Switched to stream '{name}'")
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
# ---------------------------------------------------------------------------
|
|
370
|
+
# Tool 10: gitrama_stream_list
|
|
371
|
+
# ---------------------------------------------------------------------------
|
|
372
|
+
|
|
373
|
+
@mcp.tool()
|
|
374
|
+
async def gitrama_stream_list() -> str:
|
|
375
|
+
"""
|
|
376
|
+
List all Gitrama streams in the current repository.
|
|
377
|
+
|
|
378
|
+
Shows all defined streams with their names, descriptions,
|
|
379
|
+
and associated branches. The active stream is highlighted.
|
|
380
|
+
"""
|
|
381
|
+
result = await _run_gtr(["stream", "list"])
|
|
382
|
+
return _format_result(result, "Streams listed")
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
# ---------------------------------------------------------------------------
|
|
386
|
+
# Entry point
|
|
387
|
+
# ---------------------------------------------------------------------------
|
|
388
|
+
|
|
389
|
+
def main():
|
|
390
|
+
"""Run the Gitrama MCP server."""
|
|
391
|
+
transport = os.environ.get("GTR_MCP_TRANSPORT", "stdio")
|
|
392
|
+
|
|
393
|
+
if transport == "stdio":
|
|
394
|
+
mcp.run(transport="stdio")
|
|
395
|
+
elif transport == "streamable-http":
|
|
396
|
+
host = os.environ.get("GTR_MCP_HOST", "0.0.0.0")
|
|
397
|
+
port = int(os.environ.get("GTR_MCP_PORT", "8765"))
|
|
398
|
+
mcp.settings.host = host
|
|
399
|
+
mcp.settings.port = port
|
|
400
|
+
mcp.run(transport="streamable-http")
|
|
401
|
+
else:
|
|
402
|
+
print(f"Unknown transport: {transport}. Use 'stdio' or 'streamable-http'.", file=sys.stderr)
|
|
403
|
+
sys.exit(1)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
if __name__ == "__main__":
|
|
407
|
+
main()
|