pcp-mcp 1.0.1__py3-none-any.whl → 1.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pcp_mcp/models.py +12 -0
- pcp_mcp/tools/metrics.py +13 -10
- pcp_mcp/tools/system.py +1 -3
- {pcp_mcp-1.0.1.dist-info → pcp_mcp-1.0.3.dist-info}/METADATA +23 -5
- {pcp_mcp-1.0.1.dist-info → pcp_mcp-1.0.3.dist-info}/RECORD +7 -7
- {pcp_mcp-1.0.1.dist-info → pcp_mcp-1.0.3.dist-info}/WHEEL +0 -0
- {pcp_mcp-1.0.1.dist-info → pcp_mcp-1.0.3.dist-info}/entry_points.txt +0 -0
pcp_mcp/models.py
CHANGED
|
@@ -33,6 +33,18 @@ class MetricSearchResult(BaseModel):
|
|
|
33
33
|
help_text: str | None = Field(default=None, description="Brief description")
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
class MetricValueList(BaseModel):
|
|
37
|
+
"""Container for a list of metric values (MCP requires object return types)."""
|
|
38
|
+
|
|
39
|
+
metrics: list[MetricValue] = Field(description="List of metric values")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class MetricSearchResultList(BaseModel):
|
|
43
|
+
"""Container for metric search results (MCP requires object return types)."""
|
|
44
|
+
|
|
45
|
+
results: list[MetricSearchResult] = Field(description="List of matching metrics")
|
|
46
|
+
|
|
47
|
+
|
|
36
48
|
class InstancedMetric(BaseModel):
|
|
37
49
|
"""Metric with per-instance values (e.g., per-CPU, per-disk)."""
|
|
38
50
|
|
pcp_mcp/tools/metrics.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Annotated, Optional
|
|
|
4
4
|
|
|
5
5
|
from fastmcp import Context
|
|
6
6
|
from mcp.types import ToolAnnotations
|
|
7
|
-
from pydantic import Field
|
|
7
|
+
from pydantic import Field
|
|
8
8
|
|
|
9
9
|
from pcp_mcp.context import get_client_for_host
|
|
10
10
|
from pcp_mcp.icons import (
|
|
@@ -14,15 +14,19 @@ from pcp_mcp.icons import (
|
|
|
14
14
|
TAGS_DISCOVERY,
|
|
15
15
|
TAGS_METRICS,
|
|
16
16
|
)
|
|
17
|
-
from pcp_mcp.models import
|
|
17
|
+
from pcp_mcp.models import (
|
|
18
|
+
MetricInfo,
|
|
19
|
+
MetricSearchResult,
|
|
20
|
+
MetricSearchResultList,
|
|
21
|
+
MetricValue,
|
|
22
|
+
MetricValueList,
|
|
23
|
+
)
|
|
18
24
|
from pcp_mcp.utils.extractors import extract_help_text, format_units
|
|
19
25
|
|
|
20
26
|
if TYPE_CHECKING:
|
|
21
27
|
from fastmcp import FastMCP
|
|
22
28
|
|
|
23
29
|
TOOL_ANNOTATIONS = ToolAnnotations(readOnlyHint=True, openWorldHint=True)
|
|
24
|
-
METRIC_VALUE_LIST_SCHEMA = TypeAdapter(list[MetricValue]).json_schema()
|
|
25
|
-
METRIC_SEARCH_LIST_SCHEMA = TypeAdapter(list[MetricSearchResult]).json_schema()
|
|
26
30
|
|
|
27
31
|
|
|
28
32
|
def register_metrics_tools(mcp: "FastMCP") -> None:
|
|
@@ -30,7 +34,6 @@ def register_metrics_tools(mcp: "FastMCP") -> None:
|
|
|
30
34
|
|
|
31
35
|
@mcp.tool(
|
|
32
36
|
annotations=TOOL_ANNOTATIONS,
|
|
33
|
-
output_schema=METRIC_VALUE_LIST_SCHEMA,
|
|
34
37
|
icons=[ICON_METRICS],
|
|
35
38
|
tags=TAGS_METRICS,
|
|
36
39
|
)
|
|
@@ -44,7 +47,7 @@ def register_metrics_tools(mcp: "FastMCP") -> None:
|
|
|
44
47
|
Optional[str],
|
|
45
48
|
Field(description="Target pmcd host to query (default: server's configured target)"),
|
|
46
49
|
] = None,
|
|
47
|
-
) ->
|
|
50
|
+
) -> MetricValueList:
|
|
48
51
|
"""Fetch current values for specific PCP metrics.
|
|
49
52
|
|
|
50
53
|
Returns the current value for each requested metric. For metrics with
|
|
@@ -88,11 +91,10 @@ def register_metrics_tools(mcp: "FastMCP") -> None:
|
|
|
88
91
|
)
|
|
89
92
|
)
|
|
90
93
|
|
|
91
|
-
return results
|
|
94
|
+
return MetricValueList(metrics=results)
|
|
92
95
|
|
|
93
96
|
@mcp.tool(
|
|
94
97
|
annotations=TOOL_ANNOTATIONS,
|
|
95
|
-
output_schema=METRIC_SEARCH_LIST_SCHEMA,
|
|
96
98
|
icons=[ICON_SEARCH],
|
|
97
99
|
tags=TAGS_METRICS | TAGS_DISCOVERY,
|
|
98
100
|
)
|
|
@@ -106,7 +108,7 @@ def register_metrics_tools(mcp: "FastMCP") -> None:
|
|
|
106
108
|
Optional[str],
|
|
107
109
|
Field(description="Target pmcd host to query (default: server's configured target)"),
|
|
108
110
|
] = None,
|
|
109
|
-
) ->
|
|
111
|
+
) -> MetricSearchResultList:
|
|
110
112
|
"""Find PCP metrics matching a name pattern.
|
|
111
113
|
|
|
112
114
|
Use this to discover available metrics before querying them.
|
|
@@ -127,13 +129,14 @@ def register_metrics_tools(mcp: "FastMCP") -> None:
|
|
|
127
129
|
except Exception as e:
|
|
128
130
|
raise handle_pcp_error(e, "searching metrics") from e
|
|
129
131
|
|
|
130
|
-
|
|
132
|
+
results = [
|
|
131
133
|
MetricSearchResult(
|
|
132
134
|
name=m.get("name", ""),
|
|
133
135
|
help_text=extract_help_text(m),
|
|
134
136
|
)
|
|
135
137
|
for m in metrics
|
|
136
138
|
]
|
|
139
|
+
return MetricSearchResultList(results=results)
|
|
137
140
|
|
|
138
141
|
@mcp.tool(
|
|
139
142
|
annotations=TOOL_ANNOTATIONS,
|
pcp_mcp/tools/system.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""System health tools for clumped metric queries."""
|
|
2
2
|
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
3
|
from datetime import datetime, timezone
|
|
6
4
|
from typing import TYPE_CHECKING, Annotated, Literal, Optional
|
|
7
5
|
|
|
@@ -149,7 +147,7 @@ async def _fetch_system_snapshot(
|
|
|
149
147
|
return snapshot
|
|
150
148
|
|
|
151
149
|
|
|
152
|
-
def register_system_tools(mcp: FastMCP) -> None:
|
|
150
|
+
def register_system_tools(mcp: "FastMCP") -> None:
|
|
153
151
|
"""Register system health tools with the MCP server."""
|
|
154
152
|
|
|
155
153
|
@mcp.tool(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pcp-mcp
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: MCP server for Performance Co-Pilot
|
|
5
5
|
Keywords: mcp,pcp,performance-co-pilot,monitoring,model-context-protocol
|
|
6
6
|
Author: Major Hayden
|
|
@@ -41,7 +41,22 @@ Query system performance metrics via the Model Context Protocol - CPU, memory, d
|
|
|
41
41
|
[](https://www.python.org/downloads/)
|
|
42
42
|
[](https://opensource.org/licenses/MIT)
|
|
43
43
|
|
|
44
|
-
## 🚀
|
|
44
|
+
## 🚀 Quick Start (No Install)
|
|
45
|
+
|
|
46
|
+
Run immediately with [uvx](https://docs.astral.sh/uv/) — no installation required:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uvx pcp-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or install as a persistent global tool:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uvx tool install pcp-mcp
|
|
56
|
+
pcp-mcp
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 📦 Installation
|
|
45
60
|
|
|
46
61
|
```bash
|
|
47
62
|
pip install pcp-mcp
|
|
@@ -126,7 +141,8 @@ Add to `~/.config/claude/claude_desktop_config.json`:
|
|
|
126
141
|
{
|
|
127
142
|
"mcpServers": {
|
|
128
143
|
"pcp": {
|
|
129
|
-
"command": "
|
|
144
|
+
"command": "uvx",
|
|
145
|
+
"args": ["pcp-mcp"]
|
|
130
146
|
}
|
|
131
147
|
}
|
|
132
148
|
}
|
|
@@ -138,13 +154,15 @@ For remote monitoring:
|
|
|
138
154
|
{
|
|
139
155
|
"mcpServers": {
|
|
140
156
|
"pcp": {
|
|
141
|
-
"command": "
|
|
142
|
-
"args": ["--target-host", "webserver1.example.com"]
|
|
157
|
+
"command": "uvx",
|
|
158
|
+
"args": ["pcp-mcp", "--target-host", "webserver1.example.com"]
|
|
143
159
|
}
|
|
144
160
|
}
|
|
145
161
|
}
|
|
146
162
|
```
|
|
147
163
|
|
|
164
|
+
> 💡 Using `uvx` means you don't need pcp-mcp installed — it runs directly from PyPI.
|
|
165
|
+
|
|
148
166
|
## 🛠️ Available Tools
|
|
149
167
|
|
|
150
168
|
### System Monitoring
|
|
@@ -6,7 +6,7 @@ pcp_mcp/context.py,sha256=5M6l72phsijPr96PXpZDm1rd_Uvo7mY_LuiLdeiW2SE,2801
|
|
|
6
6
|
pcp_mcp/errors.py,sha256=sIes9OSNdYQeOmwjFknhfXXjBjOOzXmc94bbB-4b_tg,1598
|
|
7
7
|
pcp_mcp/icons.py,sha256=ZTMU4iDR0369NPOsaAyDhu-MngtdkbDY_QZbA6BjwN0,1497
|
|
8
8
|
pcp_mcp/middleware.py,sha256=oUSdaCHSy1gVkKyeC2J8ASfhJep-3KvY8GFYRFWUvJ0,2387
|
|
9
|
-
pcp_mcp/models.py,sha256=
|
|
9
|
+
pcp_mcp/models.py,sha256=A7gJci-Gwzctjc_iEnQrGrJ2xq-CaBuemNiLIeujPk4,7244
|
|
10
10
|
pcp_mcp/prompts/__init__.py,sha256=x3QDidJFt2CeLmFZWGLs673m9L9NUi2IC4Me5A9nxw4,12586
|
|
11
11
|
pcp_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
pcp_mcp/resources/__init__.py,sha256=55Mm2ZCuyyQWWql9N8cLk6ld1pNj3Ezc416jgFX35dU,541
|
|
@@ -15,12 +15,12 @@ pcp_mcp/resources/health.py,sha256=cHnH2aRF4gdeo0AVUDi_qWqHocDSULhlsGpnkS-qobE,3
|
|
|
15
15
|
pcp_mcp/server.py,sha256=N_XknbUCoURd7JQsNO8Tl7i9sdQZetTTE5LFsRjZozs,5030
|
|
16
16
|
pcp_mcp/tools/AGENTS.md,sha256=1yt_W-TYlGA0aWJYCM7D0i2D4899E6_kIhyoqP1np-g,1963
|
|
17
17
|
pcp_mcp/tools/__init__.py,sha256=sXhOqqnUwzSf16QU6eS79LMvXJcv7jqSXQlrpQG4UV0,505
|
|
18
|
-
pcp_mcp/tools/metrics.py,sha256=
|
|
19
|
-
pcp_mcp/tools/system.py,sha256=
|
|
18
|
+
pcp_mcp/tools/metrics.py,sha256=x0HrO_EQMPVM_IE-nC2aIYFqUys9BX15gYyLDMQkEnA,6721
|
|
19
|
+
pcp_mcp/tools/system.py,sha256=X-ubTv-8Mhirmve9iFxwo1WLHb_lQ5akmbJ4OGLWRqI,16811
|
|
20
20
|
pcp_mcp/utils/__init__.py,sha256=tTbcqrCV9pBBm7N3MwEI37Lc0JM1CVbw_etw36ejRWc,884
|
|
21
21
|
pcp_mcp/utils/builders.py,sha256=n13Ou6cb1-YToG-M31J8_jWajq8ioJx6tJTKnqaQiio,10293
|
|
22
22
|
pcp_mcp/utils/extractors.py,sha256=fy6aCI23JuGt73oIDxwPW_K4B0fJkFCF1VxYkBst0Y4,2279
|
|
23
|
-
pcp_mcp-1.0.
|
|
24
|
-
pcp_mcp-1.0.
|
|
25
|
-
pcp_mcp-1.0.
|
|
26
|
-
pcp_mcp-1.0.
|
|
23
|
+
pcp_mcp-1.0.3.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
|
|
24
|
+
pcp_mcp-1.0.3.dist-info/entry_points.txt,sha256=PhVo92EGoS05yEpHVRyKEsxKya_bWlPLodp-g4tr2Rg,42
|
|
25
|
+
pcp_mcp-1.0.3.dist-info/METADATA,sha256=VjDhKh4Dj2RFptMvtXhsVbtJ9PUJiu_ZWx9xw6rVWtU,7024
|
|
26
|
+
pcp_mcp-1.0.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|