mcp-perforce-server 2.1.2 → 3.1.0
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.
- package/README.md +216 -191
- package/dist/p4/parse.d.ts +18 -2
- package/dist/p4/parse.d.ts.map +1 -1
- package/dist/p4/parse.js +162 -1
- package/dist/p4/parse.js.map +1 -1
- package/dist/server.d.ts +17 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +544 -60
- package/dist/server.js.map +1 -1
- package/dist/tools/basic.d.ts +41 -0
- package/dist/tools/basic.d.ts.map +1 -1
- package/dist/tools/basic.js +285 -0
- package/dist/tools/basic.js.map +1 -1
- package/dist/tools/changelist.d.ts +2 -0
- package/dist/tools/changelist.d.ts.map +1 -1
- package/dist/tools/changelist.js +19 -1
- package/dist/tools/changelist.js.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +11 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/workflows.d.ts +40 -0
- package/dist/tools/workflows.d.ts.map +1 -0
- package/dist/tools/workflows.js +475 -0
- package/dist/tools/workflows.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,192 +1,217 @@
|
|
|
1
|
-
# MCP Perforce Server
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/mcp-perforce-server)
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://nodejs.org/)
|
|
6
|
-
[](https://www.typescriptlang.org/)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
##
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
|
134
|
-
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
|
145
|
-
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
|
155
|
-
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
##
|
|
191
|
-
|
|
1
|
+
# MCP Perforce Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/mcp-perforce-server)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://mcpampel.com/repo/iPraBhu/mcp-perforce-server)
|
|
8
|
+
|
|
9
|
+
MCP server for Perforce (P4) with safe defaults, fast execution, and structured JSON responses.
|
|
10
|
+
|
|
11
|
+
> Developed with vibe coding for practical Perforce automation workflows.
|
|
12
|
+
|
|
13
|
+
New to MCP servers? See [What is MCP (Model Context Protocol)?](https://adevguide.com/ai-engineering/llm-agents/what-is-mcp-model-context-protocol/).
|
|
14
|
+
|
|
15
|
+
## Workflow Speed
|
|
16
|
+
|
|
17
|
+
This server includes composite tools that combine multiple Perforce calls into one request so review and sync workflows complete faster with fewer MCP round trips.
|
|
18
|
+
|
|
19
|
+
- `p4.review.bundle`: pending review changelists with optional details and reviewers in one call
|
|
20
|
+
- `p4.change.inspect`: changelist inspection bundle (`describe` + `fixes` + `reviews` + optional diff + optional `filelog`)
|
|
21
|
+
- `p4.path.synccheck`: branch/path sync drift analysis (`interchanges` + optional `integrated`)
|
|
22
|
+
|
|
23
|
+
To return actual changelist diff content via MCP:
|
|
24
|
+
|
|
25
|
+
- `p4.describe` with `includeDiff=true` (optional `diffFormat`: `u`, `c`, `n`, `s`)
|
|
26
|
+
- `p4.change.inspect` with `includeDiff=true`
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g mcp-perforce-server
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
1. Make sure `p4` is installed and available in `PATH`.
|
|
37
|
+
2. Configure Perforce credentials using either `.p4config` in your workspace/project root, or MCP `env` variables.
|
|
38
|
+
3. Add MCP server config in your IDE/client.
|
|
39
|
+
|
|
40
|
+
### Example `.p4config`
|
|
41
|
+
|
|
42
|
+
```ini
|
|
43
|
+
P4PORT=perforce-server:1666
|
|
44
|
+
P4USER=your-username
|
|
45
|
+
P4CLIENT=your-workspace-name
|
|
46
|
+
P4PASSWD=your-password
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Global Install MCP Config (Default Safe Profile)
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"perforce": {
|
|
55
|
+
"command": "mcp-perforce-server"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Local Repo MCP Config (Default Safe Profile)
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"perforce": {
|
|
67
|
+
"command": "node",
|
|
68
|
+
"args": ["/absolute/path/to/mcp-perforce-server/dist/server.js"]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### MCP Config (Default Safe Profile + Credentials in `env`)
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"perforce": {
|
|
80
|
+
"command": "mcp-perforce-server",
|
|
81
|
+
"env": {
|
|
82
|
+
"P4PORT": "ssl:perforce.example.com:1666",
|
|
83
|
+
"P4USER": "your-username",
|
|
84
|
+
"P4CLIENT": "your-workspace-name",
|
|
85
|
+
"P4PASSWD": "your-password-or-ticket"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Defaults are already safe: `P4_READONLY_MODE=true` and `P4_DISABLE_DELETE=true` unless explicitly set to `false`.
|
|
93
|
+
|
|
94
|
+
If you want to pin these explicitly in your client config:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"mcpServers": {
|
|
99
|
+
"perforce": {
|
|
100
|
+
"command": "mcp-perforce-server",
|
|
101
|
+
"env": {
|
|
102
|
+
"P4_READONLY_MODE": "true",
|
|
103
|
+
"P4_DISABLE_DELETE": "true",
|
|
104
|
+
"LOG_LEVEL": "error"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Windows `args` example:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"mcpServers": {
|
|
116
|
+
"perforce": {
|
|
117
|
+
"command": "node",
|
|
118
|
+
"args": ["C:\\Tools\\git-projects\\mcp-perforce-server\\dist\\server.js"]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Default Access Model
|
|
125
|
+
|
|
126
|
+
| Setting | Default | Effect |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| `P4_READONLY_MODE` | `true` | Blocks all write-capable tools. |
|
|
129
|
+
| `P4_DISABLE_DELETE` | `true` | Blocks `p4.delete` even when write mode is enabled. |
|
|
130
|
+
|
|
131
|
+
Write-capable tools blocked when `P4_READONLY_MODE=true`:
|
|
132
|
+
|
|
133
|
+
| Tool |
|
|
134
|
+
|---|
|
|
135
|
+
| `p4.add`, `p4.edit`, `p4.delete`, `p4.revert`, `p4.sync` |
|
|
136
|
+
| `p4.changelist.create`, `p4.changelist.update`, `p4.changelist.submit`, `p4.submit` |
|
|
137
|
+
| `p4.resolve`, `p4.shelve`, `p4.unshelve` |
|
|
138
|
+
| `p4.copy`, `p4.move`, `p4.integrate`, `p4.merge` |
|
|
139
|
+
|
|
140
|
+
## Server Configuration Reference
|
|
141
|
+
|
|
142
|
+
### Runtime, Safety, and Performance
|
|
143
|
+
|
|
144
|
+
| Variable | Default | Description |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `P4_READONLY_MODE` | `true` | Read-only by default. Set to `false` to enable write-capable tools. |
|
|
147
|
+
| `P4_DISABLE_DELETE` | `true` | Delete operations are disabled by default. Set to `false` to allow `p4.delete`. |
|
|
148
|
+
| `P4_PATH` | `p4` / `p4.exe` | Custom path to Perforce CLI executable. |
|
|
149
|
+
| `P4CONFIG` | `.p4config` | `.p4config` file name used for upward discovery. |
|
|
150
|
+
| `LOG_LEVEL` | `warn` | Logging level: `error`, `warn`, `info`, `debug`. |
|
|
151
|
+
| `P4_PRETTY_JSON` | `false` | Pretty-print JSON responses when `true`. |
|
|
152
|
+
| `P4_PERFORMANCE_MODE` | `fast` | Preset: `fast`, `balanced`, `secure`. |
|
|
153
|
+
| `P4_TIMEOUT_MS` | `5000` / `10000` / `15000` | Command timeout in ms (`fast` / `balanced` / `secure`). |
|
|
154
|
+
| `P4_CONFIG_CACHE_TTL` | `600000` / `300000` / `300000` | `.p4config` cache TTL in ms (`fast` / `balanced` / `secure`). |
|
|
155
|
+
| `P4_RESPONSE_CACHE` | `true` | Enable/disable read-result response cache. |
|
|
156
|
+
| `P4_RESPONSE_CACHE_TTL_MS` | `5000` / `3000` / `1000` | Response cache TTL in ms (`fast` / `balanced` / `secure`). |
|
|
157
|
+
| `P4_RESPONSE_CACHE_TTL_MAP` | unset | Per-tool cache TTL overrides (for example `p4.info=30000,p4.review=2000`). |
|
|
158
|
+
| `P4_RESPONSE_CACHE_MAX_ENTRIES` | `400` / `250` / `100` | Max cached read responses (`fast` / `balanced` / `secure`). |
|
|
159
|
+
| `P4_NEGATIVE_CACHE` | `true` | Cache predictable read errors for a short TTL to avoid repeated retries. |
|
|
160
|
+
| `P4_NEGATIVE_CACHE_TTL_MS` | `5000` | Negative-cache TTL in milliseconds. |
|
|
161
|
+
| `P4_WORKFLOW_CONCURRENCY` | `6` | Max concurrent subcalls used by composite workflow tools. |
|
|
162
|
+
| `P4_LOG_PERF_METRICS` | `false` | Enable periodic performance snapshots (cache hit rate, p50/p95 latency, subcall totals). |
|
|
163
|
+
| `P4_LOG_PERF_METRICS_INTERVAL_MS` | `60000` | Interval for performance snapshot logs in milliseconds. |
|
|
164
|
+
| `P4_PERF_METRICS_SAMPLE_SIZE` | `200` | Rolling sample size per tool used to compute p50/p95 latency. |
|
|
165
|
+
| `P4_ENABLE_AUDIT_LOGGING` | `false` / `false` / `true` | Override audit logging (`fast` / `balanced` / `secure`). |
|
|
166
|
+
| `P4_ENABLE_RATE_LIMITING` | `false` / `false` / `true` | Override rate limiting (`fast` / `balanced` / `secure`). |
|
|
167
|
+
| `P4_ENABLE_MEMORY_LIMITS` | `false` / `true` / `true` | Override memory-limit checks (`fast` / `balanced` / `secure`). |
|
|
168
|
+
| `P4_ENABLE_INPUT_SANITIZATION` | `true` | Input sanitization is enabled unless set to `false`. |
|
|
169
|
+
| `P4_MAX_MEMORY_MB` | `512` | Memory limit for command execution and checks. |
|
|
170
|
+
| `P4_AUDIT_RETENTION_DAYS` | `90` | Number of days audit entries are retained. |
|
|
171
|
+
| `P4_RATE_LIMIT_REQUESTS` | `100` | Max requests per rate-limit window. |
|
|
172
|
+
| `P4_RATE_LIMIT_WINDOW_MS` | `600000` | Rate-limit window in milliseconds. |
|
|
173
|
+
| `P4_RATE_LIMIT_BLOCK_MS` | `3600000` | Block duration in milliseconds after exceeding limit. |
|
|
174
|
+
|
|
175
|
+
### Perforce Connection Variables
|
|
176
|
+
|
|
177
|
+
| Variable | Required | Description |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `P4PORT` | Yes | Perforce server address (for example `ssl:perforce.example.com:1666`). |
|
|
180
|
+
| `P4USER` | Yes | Perforce username. |
|
|
181
|
+
| `P4CLIENT` | Yes | Perforce client/workspace name. |
|
|
182
|
+
| `P4PASSWD` | No | Password or ticket (masked in server output). |
|
|
183
|
+
| `P4CHARSET` | No | Character set (for example `utf8`). |
|
|
184
|
+
| `P4COMMANDCHARSET` | No | Command charset override. |
|
|
185
|
+
| `P4LANGUAGE` | No | Localized language setting. |
|
|
186
|
+
| `P4DIFF` | No | Custom diff tool command. |
|
|
187
|
+
| `P4MERGE` | No | Custom merge tool command. |
|
|
188
|
+
| `P4EDITOR` | No | Editor for changelist descriptions/spec forms. |
|
|
189
|
+
|
|
190
|
+
## Tool Coverage
|
|
191
|
+
|
|
192
|
+
- 55 MCP tools covering repository info, file operations, changelists, merge/resolve, review workflows, workflow composites, search, users/clients, jobs, labels/streams, analytics, and compliance.
|
|
193
|
+
- Composite workflow tools are included to reduce request count and speed up common review/sync flows.
|
|
194
|
+
- Includes both:
|
|
195
|
+
- `p4.diff` for workspace/local vs depot diff.
|
|
196
|
+
- `p4.diff2` for depot-to-depot server-side diff.
|
|
197
|
+
- **Tool naming**: All tools use dot notation (e.g., `p4.changes`), but the server also accepts underscore notation (e.g., `p4_changes`) for compatibility with clients that transform tool names.
|
|
198
|
+
|
|
199
|
+
## Documentation
|
|
200
|
+
|
|
201
|
+
- Detailed tool reference: [docs/TOOLS_REFERENCE.md](docs/TOOLS_REFERENCE.md)
|
|
202
|
+
- Docs index: [docs/README.md](docs/README.md)
|
|
203
|
+
- IDE/client setup examples: [MCP_CONFIG_EXAMPLES.md](MCP_CONFIG_EXAMPLES.md)
|
|
204
|
+
- Perforce setup notes: [PERFORCE_SETUP.md](PERFORCE_SETUP.md)
|
|
205
|
+
|
|
206
|
+
## Development
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npm install
|
|
210
|
+
npm run build
|
|
211
|
+
npm test
|
|
212
|
+
npm run test:integration
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
192
217
|
MIT
|
package/dist/p4/parse.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Parse utilities for different p4 output formats
|
|
3
3
|
*/
|
|
4
4
|
export interface ParsedRecord {
|
|
5
|
-
[key: string]: string | number | boolean | undefined | ParsedRecord[];
|
|
5
|
+
[key: string]: string | number | boolean | undefined | ParsedRecord | ParsedRecord[];
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* Parse p4 -ztag output into structured data
|
|
@@ -20,6 +20,18 @@ export declare function parseOpenedOutput(output: string | any): ParsedRecord[];
|
|
|
20
20
|
* Parse p4 changes output into changelist records
|
|
21
21
|
*/
|
|
22
22
|
export declare function parseChangesOutput(output: string | any): ParsedRecord[];
|
|
23
|
+
/**
|
|
24
|
+
* Parse p4 review output into changelist records
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseReviewOutput(output: string | any): ParsedRecord[];
|
|
27
|
+
/**
|
|
28
|
+
* Parse p4 reviews output into reviewer records
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseReviewsOutput(output: string | any): ParsedRecord[];
|
|
31
|
+
/**
|
|
32
|
+
* Parse p4 interchanges output into changelist records
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseInterchangesOutput(output: string | any): ParsedRecord[];
|
|
23
35
|
/**
|
|
24
36
|
* Parse p4 filelog output into file history records
|
|
25
37
|
*/
|
|
@@ -37,7 +49,7 @@ export declare function parseDiffOutput(output: string | any): ParsedRecord;
|
|
|
37
49
|
*/
|
|
38
50
|
export declare function parseDiff2Output(output: string | any, summaryOnly?: boolean): ParsedRecord;
|
|
39
51
|
/**
|
|
40
|
-
* Parse p4 describe
|
|
52
|
+
* Parse p4 describe output into structured changelist data
|
|
41
53
|
*/
|
|
42
54
|
export declare function parseDescribeOutput(output: string | any): ParsedRecord;
|
|
43
55
|
/**
|
|
@@ -144,4 +156,8 @@ export declare function parsePrintOutput(output: string | any): ParsedRecord;
|
|
|
144
156
|
* Parse p4 integrate/merge output into operation records
|
|
145
157
|
*/
|
|
146
158
|
export declare function parseIntegrateOutput(output: string | any): ParsedRecord[];
|
|
159
|
+
/**
|
|
160
|
+
* Parse p4 integrated output into integration records
|
|
161
|
+
*/
|
|
162
|
+
export declare function parseIntegratedOutput(output: string | any): ParsedRecord[];
|
|
147
163
|
//# sourceMappingURL=parse.d.ts.map
|
package/dist/p4/parse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/p4/parse.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/p4/parse.ts"],"names":[],"mappings":"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"}
|