pcp-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.
pcp_mcp-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: pcp-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for Performance Co-Pilot
5
+ Keywords: mcp,pcp,performance-co-pilot,monitoring,model-context-protocol
6
+ Author: Major Hayden
7
+ Author-email: Major Hayden <major@mhtx.net>
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: System Administrators
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: System :: Monitoring
19
+ Classifier: Typing :: Typed
20
+ Requires-Dist: fastmcp>=2.0.0
21
+ Requires-Dist: httpx>=0.27
22
+ Requires-Dist: pydantic-settings>=2.0.0
23
+ Requires-Dist: typing-extensions>=4.0 ; python_full_version < '3.11'
24
+ Requires-Python: >=3.10
25
+ Project-URL: Homepage, https://github.com/major/pcp-mcp
26
+ Project-URL: Repository, https://github.com/major/pcp-mcp
27
+ Description-Content-Type: text/markdown
28
+
29
+ # pcp-mcp
30
+
31
+ MCP server for [Performance Co-Pilot (PCP)](https://pcp.io/) metrics.
32
+
33
+ Query system performance metrics via the Model Context Protocol - CPU, memory, disk I/O, network, processes, and more.
34
+
35
+ ## 🚀 Installation
36
+
37
+ ```bash
38
+ pip install pcp-mcp
39
+ ```
40
+
41
+ Or with [uv](https://docs.astral.sh/uv/):
42
+
43
+ ```bash
44
+ uv add pcp-mcp
45
+ ```
46
+
47
+ ## 📋 Requirements
48
+
49
+ - **Python**: 3.10+
50
+ - **PCP**: Performance Co-Pilot with `pmproxy` running
51
+ ```bash
52
+ # Fedora/RHEL/CentOS
53
+ sudo dnf install pcp
54
+ sudo systemctl enable --now pmproxy
55
+
56
+ # Ubuntu/Debian
57
+ sudo apt install pcp
58
+ sudo systemctl enable --now pmproxy
59
+ ```
60
+
61
+ ## ⚙️ Configuration
62
+
63
+ Configure via environment variables:
64
+
65
+ | Variable | Description | Default |
66
+ |----------|-------------|---------|
67
+ | `PCP_HOST` | pmproxy host | `localhost` |
68
+ | `PCP_PORT` | pmproxy port | `44322` |
69
+ | `PCP_TARGET_HOST` | Target pmcd host to monitor | `localhost` |
70
+ | `PCP_USE_TLS` | Use HTTPS for pmproxy | `false` |
71
+ | `PCP_TIMEOUT` | Request timeout (seconds) | `30` |
72
+ | `PCP_USERNAME` | HTTP basic auth user | (optional) |
73
+ | `PCP_PASSWORD` | HTTP basic auth password | (optional) |
74
+
75
+ ## 🎯 Usage
76
+
77
+ ### Monitor localhost (default)
78
+
79
+ ```bash
80
+ pcp-mcp
81
+ ```
82
+
83
+ ### Monitor a remote host
84
+
85
+ ```bash
86
+ PCP_TARGET_HOST=webserver1.example.com pcp-mcp
87
+ ```
88
+
89
+ Or use the CLI flag:
90
+
91
+ ```bash
92
+ pcp-mcp --target-host webserver1.example.com
93
+ ```
94
+
95
+ ### Connect to remote pmproxy
96
+
97
+ ```bash
98
+ PCP_HOST=metrics.example.com pcp-mcp
99
+ ```
100
+
101
+ ### Use SSE transport
102
+
103
+ ```bash
104
+ pcp-mcp --transport sse
105
+ ```
106
+
107
+ ## 🔌 MCP Client Configuration
108
+
109
+ ### Claude Desktop
110
+
111
+ Add to `~/.config/claude/claude_desktop_config.json`:
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "pcp": {
117
+ "command": "pcp-mcp"
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ For remote monitoring:
124
+
125
+ ```json
126
+ {
127
+ "mcpServers": {
128
+ "pcp": {
129
+ "command": "pcp-mcp",
130
+ "args": ["--target-host", "webserver1.example.com"]
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ ## 🛠️ Available Tools
137
+
138
+ ### System Monitoring
139
+
140
+ - **`get_system_snapshot`** - Point-in-time system overview (CPU, memory, disk, network, load)
141
+ - **`get_process_top`** - Top processes by CPU, memory, or I/O usage
142
+ - **`query_metrics`** - Fetch current values for specific PCP metrics
143
+ - **`search_metrics`** - Discover available metrics by name pattern
144
+ - **`describe_metric`** - Get detailed metadata about a metric
145
+
146
+ ### Example Queries
147
+
148
+ ```
149
+ "What's the current CPU usage?"
150
+ → Uses get_system_snapshot
151
+
152
+ "Show me the top 10 processes by memory usage"
153
+ → Uses get_process_top(sort_by="memory", limit=10)
154
+
155
+ "What metrics are available for network traffic?"
156
+ → Uses search_metrics(pattern="network")
157
+
158
+ "Get detailed info about kernel.all.load"
159
+ → Uses describe_metric(name="kernel.all.load")
160
+ ```
161
+
162
+ ## 📚 Resources
163
+
164
+ Browse metrics via MCP resources:
165
+
166
+ - `pcp://metrics` - List all available metrics (grouped by prefix)
167
+ - `pcp://system/snapshot` - Latest system snapshot
168
+ - `pcp://processes/top` - Top processes
169
+
170
+ ## 💡 Use Cases
171
+
172
+ ### Performance Troubleshooting
173
+
174
+ Ask Claude to:
175
+ - "Analyze current system performance and identify bottlenecks"
176
+ - "Why is my disk I/O so high?"
177
+ - "Which processes are consuming the most CPU?"
178
+
179
+ ### System Monitoring
180
+
181
+ - "Give me a health check of the production server"
182
+ - "Compare CPU usage over the last minute"
183
+ - "Monitor network traffic on eth0"
184
+
185
+ ### Capacity Planning
186
+
187
+ - "What's the memory utilization trend?"
188
+ - "Show me disk usage across all filesystems"
189
+ - "Analyze process resource consumption patterns"
190
+
191
+ ## 🏗️ Architecture
192
+
193
+ ```
194
+ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
195
+ │ LLM │ ◄─MCP─► │ pcp-mcp │ ◄─HTTP─► │ pmproxy │ ◄─────► │ pmcd │
196
+ └─────────┘ └─────────┘ └─────────┘ └─────────┘
197
+ (REST API) (metrics)
198
+ ```
199
+
200
+ - **pcp-mcp**: FastMCP server exposing PCP metrics via MCP tools
201
+ - **pmproxy**: PCP's REST API server (runs on port 44322 by default)
202
+ - **pmcd**: PCP metrics collector daemon
203
+ - **Remote monitoring**: Set `PCP_TARGET_HOST` to query a different pmcd instance via pmproxy
204
+
205
+ ## 🔧 Development
206
+
207
+ ```bash
208
+ # Install dependencies
209
+ uv sync --dev
210
+
211
+ # Run all checks
212
+ make check
213
+
214
+ # Individual commands
215
+ make lint # ruff check
216
+ make format # ruff format
217
+ make typecheck # ty check
218
+ make test # pytest with coverage
219
+ ```
220
+
221
+ ## 📖 Documentation
222
+
223
+ Full documentation at [https://major.github.io/pcp-mcp](https://major.github.io/pcp-mcp)
224
+
225
+ ## 📄 License
226
+
227
+ MIT
@@ -0,0 +1,199 @@
1
+ # pcp-mcp
2
+
3
+ MCP server for [Performance Co-Pilot (PCP)](https://pcp.io/) metrics.
4
+
5
+ Query system performance metrics via the Model Context Protocol - CPU, memory, disk I/O, network, processes, and more.
6
+
7
+ ## 🚀 Installation
8
+
9
+ ```bash
10
+ pip install pcp-mcp
11
+ ```
12
+
13
+ Or with [uv](https://docs.astral.sh/uv/):
14
+
15
+ ```bash
16
+ uv add pcp-mcp
17
+ ```
18
+
19
+ ## 📋 Requirements
20
+
21
+ - **Python**: 3.10+
22
+ - **PCP**: Performance Co-Pilot with `pmproxy` running
23
+ ```bash
24
+ # Fedora/RHEL/CentOS
25
+ sudo dnf install pcp
26
+ sudo systemctl enable --now pmproxy
27
+
28
+ # Ubuntu/Debian
29
+ sudo apt install pcp
30
+ sudo systemctl enable --now pmproxy
31
+ ```
32
+
33
+ ## ⚙️ Configuration
34
+
35
+ Configure via environment variables:
36
+
37
+ | Variable | Description | Default |
38
+ |----------|-------------|---------|
39
+ | `PCP_HOST` | pmproxy host | `localhost` |
40
+ | `PCP_PORT` | pmproxy port | `44322` |
41
+ | `PCP_TARGET_HOST` | Target pmcd host to monitor | `localhost` |
42
+ | `PCP_USE_TLS` | Use HTTPS for pmproxy | `false` |
43
+ | `PCP_TIMEOUT` | Request timeout (seconds) | `30` |
44
+ | `PCP_USERNAME` | HTTP basic auth user | (optional) |
45
+ | `PCP_PASSWORD` | HTTP basic auth password | (optional) |
46
+
47
+ ## 🎯 Usage
48
+
49
+ ### Monitor localhost (default)
50
+
51
+ ```bash
52
+ pcp-mcp
53
+ ```
54
+
55
+ ### Monitor a remote host
56
+
57
+ ```bash
58
+ PCP_TARGET_HOST=webserver1.example.com pcp-mcp
59
+ ```
60
+
61
+ Or use the CLI flag:
62
+
63
+ ```bash
64
+ pcp-mcp --target-host webserver1.example.com
65
+ ```
66
+
67
+ ### Connect to remote pmproxy
68
+
69
+ ```bash
70
+ PCP_HOST=metrics.example.com pcp-mcp
71
+ ```
72
+
73
+ ### Use SSE transport
74
+
75
+ ```bash
76
+ pcp-mcp --transport sse
77
+ ```
78
+
79
+ ## 🔌 MCP Client Configuration
80
+
81
+ ### Claude Desktop
82
+
83
+ Add to `~/.config/claude/claude_desktop_config.json`:
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "pcp": {
89
+ "command": "pcp-mcp"
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ For remote monitoring:
96
+
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "pcp": {
101
+ "command": "pcp-mcp",
102
+ "args": ["--target-host", "webserver1.example.com"]
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## 🛠️ Available Tools
109
+
110
+ ### System Monitoring
111
+
112
+ - **`get_system_snapshot`** - Point-in-time system overview (CPU, memory, disk, network, load)
113
+ - **`get_process_top`** - Top processes by CPU, memory, or I/O usage
114
+ - **`query_metrics`** - Fetch current values for specific PCP metrics
115
+ - **`search_metrics`** - Discover available metrics by name pattern
116
+ - **`describe_metric`** - Get detailed metadata about a metric
117
+
118
+ ### Example Queries
119
+
120
+ ```
121
+ "What's the current CPU usage?"
122
+ → Uses get_system_snapshot
123
+
124
+ "Show me the top 10 processes by memory usage"
125
+ → Uses get_process_top(sort_by="memory", limit=10)
126
+
127
+ "What metrics are available for network traffic?"
128
+ → Uses search_metrics(pattern="network")
129
+
130
+ "Get detailed info about kernel.all.load"
131
+ → Uses describe_metric(name="kernel.all.load")
132
+ ```
133
+
134
+ ## 📚 Resources
135
+
136
+ Browse metrics via MCP resources:
137
+
138
+ - `pcp://metrics` - List all available metrics (grouped by prefix)
139
+ - `pcp://system/snapshot` - Latest system snapshot
140
+ - `pcp://processes/top` - Top processes
141
+
142
+ ## 💡 Use Cases
143
+
144
+ ### Performance Troubleshooting
145
+
146
+ Ask Claude to:
147
+ - "Analyze current system performance and identify bottlenecks"
148
+ - "Why is my disk I/O so high?"
149
+ - "Which processes are consuming the most CPU?"
150
+
151
+ ### System Monitoring
152
+
153
+ - "Give me a health check of the production server"
154
+ - "Compare CPU usage over the last minute"
155
+ - "Monitor network traffic on eth0"
156
+
157
+ ### Capacity Planning
158
+
159
+ - "What's the memory utilization trend?"
160
+ - "Show me disk usage across all filesystems"
161
+ - "Analyze process resource consumption patterns"
162
+
163
+ ## 🏗️ Architecture
164
+
165
+ ```
166
+ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
167
+ │ LLM │ ◄─MCP─► │ pcp-mcp │ ◄─HTTP─► │ pmproxy │ ◄─────► │ pmcd │
168
+ └─────────┘ └─────────┘ └─────────┘ └─────────┘
169
+ (REST API) (metrics)
170
+ ```
171
+
172
+ - **pcp-mcp**: FastMCP server exposing PCP metrics via MCP tools
173
+ - **pmproxy**: PCP's REST API server (runs on port 44322 by default)
174
+ - **pmcd**: PCP metrics collector daemon
175
+ - **Remote monitoring**: Set `PCP_TARGET_HOST` to query a different pmcd instance via pmproxy
176
+
177
+ ## 🔧 Development
178
+
179
+ ```bash
180
+ # Install dependencies
181
+ uv sync --dev
182
+
183
+ # Run all checks
184
+ make check
185
+
186
+ # Individual commands
187
+ make lint # ruff check
188
+ make format # ruff format
189
+ make typecheck # ty check
190
+ make test # pytest with coverage
191
+ ```
192
+
193
+ ## 📖 Documentation
194
+
195
+ Full documentation at [https://major.github.io/pcp-mcp](https://major.github.io/pcp-mcp)
196
+
197
+ ## 📄 License
198
+
199
+ MIT
@@ -0,0 +1,104 @@
1
+ [project]
2
+ name = "pcp-mcp"
3
+ version = "0.1.0"
4
+ description = "MCP server for Performance Co-Pilot"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ authors = [{ name = "Major Hayden", email = "major@mhtx.net" }]
8
+ requires-python = ">=3.10"
9
+ keywords = ["mcp", "pcp", "performance-co-pilot", "monitoring", "model-context-protocol"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "Intended Audience :: System Administrators",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3.10",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
20
+ "Topic :: System :: Monitoring",
21
+ "Typing :: Typed",
22
+ ]
23
+ dependencies = [
24
+ "fastmcp>=2.0.0",
25
+ "httpx>=0.27",
26
+ "pydantic-settings>=2.0.0",
27
+ "typing_extensions>=4.0; python_version < '3.11'",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/major/pcp-mcp"
32
+ Repository = "https://github.com/major/pcp-mcp"
33
+
34
+ [project.scripts]
35
+ pcp-mcp = "pcp_mcp:main"
36
+
37
+ [build-system]
38
+ requires = ["uv_build>=0.9.18"]
39
+ build-backend = "uv_build"
40
+
41
+ [dependency-groups]
42
+ dev = [
43
+ "pytest>=8",
44
+ "pytest-cov>=6",
45
+ "pytest-asyncio>=0.25",
46
+ "respx>=0.22",
47
+ "ty>=0.0.12",
48
+ "ruff>=0.9",
49
+ "radon>=6",
50
+ "pytest-randomly>=4.0.1",
51
+ "mkdocs-material>=9.5",
52
+ "mkdocstrings[python]>=0.27",
53
+ ]
54
+
55
+ [tool.uv.build-backend]
56
+ module-name = "pcp_mcp"
57
+
58
+ [tool.ruff]
59
+ target-version = "py310"
60
+ line-length = 100
61
+
62
+ [tool.ruff.lint]
63
+ select = ["E", "F", "I", "UP", "B", "SIM", "ASYNC", "D"]
64
+ ignore = [
65
+ "D100", # Missing docstring in public module
66
+ "D104", # Missing docstring in public package
67
+ "D105", # Missing docstring in magic method
68
+ "D107", # Missing docstring in __init__
69
+ ]
70
+
71
+ [tool.ruff.lint.per-file-ignores]
72
+ "tests/**/*.py" = ["D"]
73
+
74
+ [tool.ruff.lint.pydocstyle]
75
+ convention = "google"
76
+
77
+ [tool.pytest.ini_options]
78
+ asyncio_mode = "auto"
79
+ asyncio_default_fixture_loop_scope = "function"
80
+ testpaths = ["tests"]
81
+ addopts = "--cov=pcp_mcp --cov-report=term-missing"
82
+
83
+ [tool.coverage.run]
84
+ source = ["src/pcp_mcp"]
85
+ branch = true
86
+
87
+ [tool.coverage.report]
88
+ exclude_lines = [
89
+ "pragma: no cover",
90
+ "if TYPE_CHECKING:",
91
+ "raise NotImplementedError",
92
+ ]
93
+
94
+ [tool.ty.environment]
95
+ python-version = "3.14"
96
+ python-platform = "linux"
97
+ extra-paths = ["src"]
98
+
99
+ [tool.pyright]
100
+ pythonVersion = "3.10"
101
+ pythonPlatform = "Linux"
102
+ venvPath = "."
103
+ venv = ".venv"
104
+ typeCheckingMode = "standard"
@@ -0,0 +1,59 @@
1
+ """PCP MCP Server - Performance Co-Pilot metrics via Model Context Protocol."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import os
7
+
8
+
9
+ def main() -> None:
10
+ """Run the PCP MCP server."""
11
+ parser = argparse.ArgumentParser(
12
+ description="PCP MCP Server - Performance Co-Pilot Metrics",
13
+ formatter_class=argparse.RawDescriptionHelpFormatter,
14
+ epilog="""
15
+ Environment Variables:
16
+ PCP_HOST pmproxy host (default: localhost)
17
+ PCP_PORT pmproxy port (default: 44322)
18
+ PCP_TARGET_HOST Target pmcd host to monitor (default: localhost)
19
+ PCP_USE_TLS Use HTTPS for pmproxy connection (default: false)
20
+ PCP_TIMEOUT Request timeout in seconds (default: 30)
21
+ PCP_USERNAME HTTP basic auth user (optional)
22
+ PCP_PASSWORD HTTP basic auth password (optional)
23
+
24
+ Examples:
25
+ # Monitor localhost (default)
26
+ pcp-mcp
27
+
28
+ # Monitor a remote host
29
+ PCP_TARGET_HOST=webserver1.example.com pcp-mcp
30
+
31
+ # Connect to pmproxy on a different host
32
+ PCP_HOST=metrics.example.com pcp-mcp
33
+
34
+ # Use SSE transport
35
+ pcp-mcp --transport sse
36
+ """,
37
+ )
38
+ parser.add_argument(
39
+ "--target-host",
40
+ help="Target pmcd host to monitor (overrides PCP_TARGET_HOST)",
41
+ )
42
+ parser.add_argument(
43
+ "--transport",
44
+ choices=["stdio", "sse", "streamable-http"],
45
+ default="stdio",
46
+ help="Transport protocol (default: stdio)",
47
+ )
48
+ args = parser.parse_args()
49
+
50
+ if args.target_host:
51
+ os.environ["PCP_TARGET_HOST"] = args.target_host
52
+
53
+ from pcp_mcp.server import create_server
54
+
55
+ server = create_server()
56
+ server.run(transport=args.transport)
57
+
58
+
59
+ __all__ = ["main"]