pcp-mcp 1.3.2__py3-none-any.whl → 1.4.0__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/tools/system.py CHANGED
@@ -1,9 +1,11 @@
1
1
  """System health tools for clumped metric queries."""
2
2
 
3
3
  from datetime import datetime, timezone
4
- from typing import TYPE_CHECKING, Annotated, Any, Literal, Optional
4
+ from typing import Annotated, Any, Literal, Optional
5
5
 
6
6
  from fastmcp import Context
7
+ from fastmcp.tools import tool
8
+ from fastmcp.tools.tool import ToolResult
7
9
  from mcp.types import ToolAnnotations
8
10
  from pydantic import Field
9
11
 
@@ -39,8 +41,13 @@ from pcp_mcp.utils.builders import (
39
41
  )
40
42
  from pcp_mcp.utils.extractors import get_scalar_value
41
43
 
42
- if TYPE_CHECKING:
43
- from fastmcp import FastMCP
44
+ __all__ = [
45
+ "get_system_snapshot",
46
+ "quick_health",
47
+ "get_process_top",
48
+ "smart_diagnose",
49
+ "get_filesystem_usage",
50
+ ]
44
51
 
45
52
  TOOL_ANNOTATIONS = ToolAnnotations(readOnlyHint=True, openWorldHint=True)
46
53
 
@@ -164,278 +171,302 @@ async def _fetch_system_snapshot(
164
171
  return snapshot
165
172
 
166
173
 
167
- def register_system_tools(mcp: "FastMCP") -> None:
168
- """Register system health tools with the MCP server."""
169
-
170
- @mcp.tool(
171
- annotations=TOOL_ANNOTATIONS,
172
- output_schema=SystemSnapshot.model_json_schema(),
173
- icons=[ICON_SYSTEM],
174
- tags=TAGS_SYSTEM,
175
- )
176
- async def get_system_snapshot(
177
- ctx: Context,
178
- categories: Annotated[
179
- Optional[list[str]],
180
- Field(
181
- default=None,
182
- description=(
183
- "Categories to include: cpu, memory, disk, network, load. "
184
- "Defaults to all five if not specified."
185
- ),
186
- ),
187
- ] = None,
188
- sample_interval: Annotated[
189
- float,
190
- Field(
191
- default=1.0,
192
- ge=0.1,
193
- le=10.0,
194
- description="Seconds between samples for rate calculation",
174
+ @tool(
175
+ annotations=TOOL_ANNOTATIONS,
176
+ icons=[ICON_SYSTEM],
177
+ tags=TAGS_SYSTEM,
178
+ timeout=30.0,
179
+ )
180
+ async def get_system_snapshot(
181
+ ctx: Context,
182
+ categories: Annotated[
183
+ Optional[list[str]],
184
+ Field(
185
+ default=None,
186
+ description=(
187
+ "Categories to include: cpu, memory, disk, network, load. "
188
+ "Defaults to all five if not specified."
195
189
  ),
196
- ] = 1.0,
197
- host: Annotated[
198
- Optional[str],
199
- Field(description="Target pmcd host to query (default: server's configured target)"),
200
- ] = None,
201
- ) -> SystemSnapshot:
202
- """Get a point-in-time system health overview.
203
-
204
- Returns CPU, memory, disk I/O, network I/O, and load metrics in a single
205
- call. For rate metrics (CPU %, disk I/O, network throughput), takes two
206
- samples to calculate per-second rates.
207
-
208
- Use this tool FIRST for system troubleshooting. It automatically handles
209
- counter-to-rate conversion. Do NOT use query_metrics() for CPU, disk, or
210
- network counters - those return raw cumulative values since boot.
211
-
212
- Examples:
213
- get_system_snapshot() - Quick health check (all categories)
214
- get_system_snapshot(categories=["cpu", "memory"]) - CPU and memory only
215
- get_system_snapshot(categories=["cpu", "load"]) - CPU and load averages
216
- get_system_snapshot(categories=["disk", "network"]) - I/O analysis
217
- get_system_snapshot(host="web1.example.com") - Query remote host
218
- """
219
- if categories is None:
220
- categories = ["cpu", "memory", "disk", "network", "load"]
221
- return await _fetch_system_snapshot(ctx, categories, sample_interval, host)
222
-
223
- @mcp.tool(
224
- annotations=TOOL_ANNOTATIONS,
225
- output_schema=SystemSnapshot.model_json_schema(),
226
- icons=[ICON_HEALTH],
227
- tags=TAGS_HEALTH,
190
+ ),
191
+ ] = None,
192
+ sample_interval: Annotated[
193
+ float,
194
+ Field(
195
+ default=1.0,
196
+ ge=0.1,
197
+ le=10.0,
198
+ description="Seconds between samples for rate calculation",
199
+ ),
200
+ ] = 1.0,
201
+ host: Annotated[
202
+ Optional[str],
203
+ Field(description="Target pmcd host to query (default: server's configured target)"),
204
+ ] = None,
205
+ ) -> ToolResult:
206
+ """Get a point-in-time system health overview.
207
+
208
+ Returns CPU, memory, disk I/O, network I/O, and load metrics in a single
209
+ call. For rate metrics (CPU %, disk I/O, network throughput), takes two
210
+ samples to calculate per-second rates.
211
+
212
+ Use this tool FIRST for system troubleshooting. It automatically handles
213
+ counter-to-rate conversion. Do NOT use query_metrics() for CPU, disk, or
214
+ network counters - those return raw cumulative values since boot.
215
+
216
+ Examples:
217
+ get_system_snapshot() - Quick health check (all categories)
218
+ get_system_snapshot(categories=["cpu", "memory"]) - CPU and memory only
219
+ get_system_snapshot(categories=["cpu", "load"]) - CPU and load averages
220
+ get_system_snapshot(categories=["disk", "network"]) - I/O analysis
221
+ get_system_snapshot(host="web1.example.com") - Query remote host
222
+ """
223
+ if categories is None:
224
+ categories = ["cpu", "memory", "disk", "network", "load"]
225
+ result = await _fetch_system_snapshot(ctx, categories, sample_interval, host)
226
+ return ToolResult(
227
+ content=result.model_dump_json(),
228
+ structured_content=result.model_dump(),
228
229
  )
229
- async def quick_health(
230
- ctx: Context,
231
- host: Annotated[
232
- Optional[str],
233
- Field(description="Target pmcd host to query (default: server's configured target)"),
234
- ] = None,
235
- ) -> SystemSnapshot:
236
- """Fast system health check returning only CPU and memory metrics.
237
-
238
- Use this for rapid status checks when you don't need disk/network/load
239
- details. Uses a shorter sample interval (0.5s) for faster results.
240
-
241
- Examples:
242
- quick_health() - Fast health check on default host
243
- quick_health(host="web1.example.com") - Fast check on remote host
244
- """
245
- return await _fetch_system_snapshot(ctx, ["cpu", "memory"], 0.5, host)
246
-
247
- @mcp.tool(
248
- annotations=TOOL_ANNOTATIONS,
249
- output_schema=ProcessTopResult.model_json_schema(),
250
- icons=[ICON_PROCESS],
251
- tags=TAGS_PROCESS,
230
+
231
+
232
+ @tool(
233
+ annotations=TOOL_ANNOTATIONS,
234
+ icons=[ICON_HEALTH],
235
+ tags=TAGS_HEALTH,
236
+ timeout=30.0,
237
+ )
238
+ async def quick_health(
239
+ ctx: Context,
240
+ host: Annotated[
241
+ Optional[str],
242
+ Field(description="Target pmcd host to query (default: server's configured target)"),
243
+ ] = None,
244
+ ) -> ToolResult:
245
+ """Fast system health check returning only CPU and memory metrics.
246
+
247
+ Use this for rapid status checks when you don't need disk/network/load
248
+ details. Uses a shorter sample interval (0.5s) for faster results.
249
+
250
+ Examples:
251
+ quick_health() - Fast health check on default host
252
+ quick_health(host="web1.example.com") - Fast check on remote host
253
+ """
254
+ result = await _fetch_system_snapshot(ctx, ["cpu", "memory"], 0.5, host)
255
+ return ToolResult(
256
+ content=result.model_dump_json(),
257
+ structured_content=result.model_dump(),
252
258
  )
253
- async def get_process_top(
254
- ctx: Context,
255
- sort_by: Annotated[
256
- Literal["cpu", "memory", "io"],
257
- Field(description="Resource to sort by"),
258
- ] = "cpu",
259
- limit: Annotated[
260
- int,
261
- Field(default=10, ge=1, le=50, description="Number of processes to return"),
262
- ] = 10,
263
- sample_interval: Annotated[
264
- float,
265
- Field(
266
- default=1.0,
267
- ge=0.5,
268
- le=5.0,
269
- description="Seconds to sample for CPU/IO rates",
270
- ),
271
- ] = 1.0,
272
- host: Annotated[
273
- Optional[str],
274
- Field(description="Target pmcd host to query (default: server's configured target)"),
275
- ] = None,
276
- ) -> ProcessTopResult:
277
- """Get top processes by resource consumption.
278
-
279
- For CPU and I/O, takes two samples to calculate rates. Memory is instantaneous.
280
- Returns the top N processes sorted by the requested resource.
281
-
282
- Examples:
283
- get_process_top() - Top 10 by CPU (default)
284
- get_process_top(sort_by="memory", limit=20) - Top 20 memory consumers
285
- get_process_top(sort_by="io", sample_interval=2.0) - Top I/O with longer sample
286
- get_process_top(host="db1.example.com") - Query remote host
287
- """
288
- all_metrics = (
289
- PROCESS_METRICS["info"] + PROCESS_METRICS["memory"] + PROCESS_METRICS.get(sort_by, [])
290
- )
291
- if sort_by == "cpu":
292
- all_metrics.extend(PROCESS_METRICS["cpu"])
293
- elif sort_by == "io":
294
- all_metrics.extend(PROCESS_METRICS["io"])
295
-
296
- all_metrics = list(set(all_metrics))
297
- system_metrics = ["hinv.ncpu", "mem.physmem"]
298
-
299
- counter_metrics = {
300
- "proc.psinfo.utime",
301
- "proc.psinfo.stime",
302
- "proc.io.read_bytes",
303
- "proc.io.write_bytes",
304
- }
305
-
306
- from pcp_mcp.errors import handle_pcp_error
307
-
308
- async def report_progress(current: float, total: float, message: str) -> None:
309
- await ctx.report_progress(current, total, message)
310
-
311
- async with get_client_for_host(ctx, host) as client:
312
- try:
313
- proc_data = await client.fetch_with_rates(
314
- all_metrics, counter_metrics, sample_interval, progress_callback=report_progress
315
- )
316
- sys_data = await client.fetch(system_metrics)
317
- except Exception as e:
318
- raise handle_pcp_error(e, "fetching process data") from e
319
-
320
- await ctx.report_progress(92, 100, "Processing results...")
321
-
322
- ncpu = get_scalar_value(sys_data, "hinv.ncpu", 1)
323
- total_mem = get_scalar_value(sys_data, "mem.physmem", 1) * 1024
324
-
325
- processes = build_process_list(proc_data, sort_by, total_mem, ncpu)
326
- processes.sort(key=lambda p: get_sort_key(p, sort_by), reverse=True)
327
- processes = processes[:limit]
328
-
329
- assessment = assess_processes(processes, sort_by, ncpu)
330
-
331
- await ctx.report_progress(100, 100, "Complete")
332
- return ProcessTopResult(
333
- timestamp=datetime.now(timezone.utc).isoformat(),
334
- hostname=client.target_host,
335
- sort_by=sort_by,
336
- sample_interval=sample_interval,
337
- processes=processes,
338
- total_memory_bytes=int(total_mem),
339
- ncpu=ncpu,
340
- assessment=assessment,
341
- )
342
259
 
343
- @mcp.tool(
344
- annotations=TOOL_ANNOTATIONS,
345
- output_schema=DiagnosisResult.model_json_schema(),
346
- icons=[ICON_DIAGNOSE],
347
- tags=TAGS_DIAGNOSE,
260
+
261
+ @tool(
262
+ annotations=TOOL_ANNOTATIONS,
263
+ icons=[ICON_PROCESS],
264
+ tags=TAGS_PROCESS,
265
+ timeout=30.0,
266
+ )
267
+ async def get_process_top(
268
+ ctx: Context,
269
+ sort_by: Annotated[
270
+ Literal["cpu", "memory", "io"],
271
+ Field(description="Resource to sort by"),
272
+ ] = "cpu",
273
+ limit: Annotated[
274
+ int,
275
+ Field(default=10, ge=1, le=50, description="Number of processes to return"),
276
+ ] = 10,
277
+ sample_interval: Annotated[
278
+ float,
279
+ Field(
280
+ default=1.0,
281
+ ge=0.5,
282
+ le=5.0,
283
+ description="Seconds to sample for CPU/IO rates",
284
+ ),
285
+ ] = 1.0,
286
+ host: Annotated[
287
+ Optional[str],
288
+ Field(description="Target pmcd host to query (default: server's configured target)"),
289
+ ] = None,
290
+ ) -> ToolResult:
291
+ """Get top processes by resource consumption.
292
+
293
+ For CPU and I/O, takes two samples to calculate rates. Memory is instantaneous.
294
+ Returns the top N processes sorted by the requested resource.
295
+
296
+ Examples:
297
+ get_process_top() - Top 10 by CPU (default)
298
+ get_process_top(sort_by="memory", limit=20) - Top 20 memory consumers
299
+ get_process_top(sort_by="io", sample_interval=2.0) - Top I/O with longer sample
300
+ get_process_top(host="db1.example.com") - Query remote host
301
+ """
302
+ all_metrics = (
303
+ PROCESS_METRICS["info"] + PROCESS_METRICS["memory"] + PROCESS_METRICS.get(sort_by, [])
348
304
  )
349
- async def smart_diagnose(
350
- ctx: Context,
351
- host: Annotated[
352
- Optional[str],
353
- Field(description="Target pmcd host to query (default: server's configured target)"),
354
- ] = None,
355
- ) -> DiagnosisResult:
356
- """Use LLM to analyze system metrics and provide diagnosis.
357
-
358
- Collects a quick system snapshot (CPU, memory, load) and asks the
359
- connected LLM to analyze the metrics and provide actionable insights.
360
-
361
- This tool demonstrates FastMCP's LLM sampling capability, where the
362
- MCP server can request LLM assistance for complex analysis tasks.
363
-
364
- Examples:
365
- smart_diagnose() - Analyze default host
366
- smart_diagnose(host="db1.example.com") - Analyze remote host
367
- """
368
- from pcp_mcp.errors import handle_pcp_error
305
+ if sort_by == "cpu":
306
+ all_metrics.extend(PROCESS_METRICS["cpu"])
307
+ elif sort_by == "io":
308
+ all_metrics.extend(PROCESS_METRICS["io"])
369
309
 
310
+ all_metrics = list(set(all_metrics))
311
+ system_metrics = ["hinv.ncpu", "mem.physmem"]
312
+
313
+ counter_metrics = {
314
+ "proc.psinfo.utime",
315
+ "proc.psinfo.stime",
316
+ "proc.io.read_bytes",
317
+ "proc.io.write_bytes",
318
+ }
319
+
320
+ from pcp_mcp.errors import handle_pcp_error
321
+
322
+ async def report_progress(current: float, total: float, message: str) -> None:
323
+ await ctx.report_progress(current, total, message)
324
+
325
+ async with get_client_for_host(ctx, host) as client:
370
326
  try:
371
- snapshot = await _fetch_system_snapshot(ctx, ["cpu", "memory", "load"], 0.5, host)
327
+ proc_data = await client.fetch_with_rates(
328
+ all_metrics, counter_metrics, sample_interval, progress_callback=report_progress
329
+ )
330
+ sys_data = await client.fetch(system_metrics)
372
331
  except Exception as e:
373
- raise handle_pcp_error(e, "fetching metrics for diagnosis") from e
332
+ raise handle_pcp_error(e, "fetching process data") from e
333
+
334
+ await ctx.report_progress(92, 100, "Processing results...")
335
+
336
+ ncpu = get_scalar_value(sys_data, "hinv.ncpu", 1)
337
+ total_mem = get_scalar_value(sys_data, "mem.physmem", 1) * 1024
338
+
339
+ processes = build_process_list(proc_data, sort_by, total_mem, ncpu)
340
+ processes.sort(key=lambda p: get_sort_key(p, sort_by), reverse=True)
341
+ processes = processes[:limit]
374
342
 
375
- metrics_summary = _format_snapshot_for_llm(snapshot)
343
+ assessment = assess_processes(processes, sort_by, ncpu)
376
344
 
377
- system_prompt = (
378
- "You are a system performance analyst. Analyze the metrics and provide:\n"
379
- "1. A brief diagnosis (2-3 sentences)\n"
380
- "2. A severity level: 'healthy', 'warning', or 'critical'\n"
381
- "3. Up to 3 actionable recommendations\n\n"
382
- "Be concise and focus on actionable insights."
345
+ await ctx.report_progress(100, 100, "Complete")
346
+ result = ProcessTopResult(
347
+ timestamp=datetime.now(timezone.utc).isoformat(),
348
+ hostname=client.target_host,
349
+ sort_by=sort_by,
350
+ sample_interval=sample_interval,
351
+ processes=processes,
352
+ total_memory_bytes=int(total_mem),
353
+ ncpu=ncpu,
354
+ assessment=assessment,
355
+ )
356
+ return ToolResult(
357
+ content=result.model_dump_json(),
358
+ structured_content=result.model_dump(),
383
359
  )
384
360
 
385
- try:
386
- sampling_result = await ctx.sample(
387
- messages=f"Analyze these system metrics:\n\n{metrics_summary}",
388
- system_prompt=system_prompt,
389
- max_tokens=500,
390
- result_type=DiagnosisResult,
391
- )
392
- result = sampling_result.result
393
- result.timestamp = snapshot.timestamp
394
- result.hostname = snapshot.hostname
395
- return result
396
- except Exception:
397
- return _build_fallback_diagnosis(snapshot)
398
-
399
- @mcp.tool(
400
- annotations=TOOL_ANNOTATIONS,
401
- output_schema=FilesystemSnapshot.model_json_schema(),
402
- icons=[ICON_FILESYSTEM],
403
- tags=TAGS_FILESYSTEM,
361
+
362
+ @tool(
363
+ annotations=TOOL_ANNOTATIONS,
364
+ icons=[ICON_DIAGNOSE],
365
+ tags=TAGS_DIAGNOSE,
366
+ timeout=30.0,
367
+ )
368
+ async def smart_diagnose(
369
+ ctx: Context,
370
+ host: Annotated[
371
+ Optional[str],
372
+ Field(description="Target pmcd host to query (default: server's configured target)"),
373
+ ] = None,
374
+ ) -> ToolResult:
375
+ """Use LLM to analyze system metrics and provide diagnosis.
376
+
377
+ Collects a quick system snapshot (CPU, memory, load) and asks the
378
+ connected LLM to analyze the metrics and provide actionable insights.
379
+
380
+ This tool demonstrates FastMCP's LLM sampling capability, where the
381
+ MCP server can request LLM assistance for complex analysis tasks.
382
+
383
+ Examples:
384
+ smart_diagnose() - Analyze default host
385
+ smart_diagnose(host="db1.example.com") - Analyze remote host
386
+ """
387
+ from pcp_mcp.errors import handle_pcp_error
388
+
389
+ try:
390
+ snapshot = await _fetch_system_snapshot(ctx, ["cpu", "memory", "load"], 0.5, host)
391
+ except Exception as e:
392
+ raise handle_pcp_error(e, "fetching metrics for diagnosis") from e
393
+
394
+ metrics_summary = _format_snapshot_for_llm(snapshot)
395
+
396
+ system_prompt = (
397
+ "You are a system performance analyst. Analyze the metrics and provide:\n"
398
+ "1. A brief diagnosis (2-3 sentences)\n"
399
+ "2. A severity level: 'healthy', 'warning', or 'critical'\n"
400
+ "3. Up to 3 actionable recommendations\n\n"
401
+ "Be concise and focus on actionable insights."
404
402
  )
405
- async def get_filesystem_usage(
406
- ctx: Context,
407
- host: Annotated[
408
- Optional[str],
409
- Field(description="Target pmcd host to query (default: server's configured target)"),
410
- ] = None,
411
- ) -> FilesystemSnapshot:
412
- """Get mounted filesystem usage (similar to df command).
413
-
414
- Returns capacity, used, available, and percent full for each mounted
415
- filesystem. Useful for monitoring disk space and identifying filesystems
416
- that may need attention.
417
-
418
- Examples:
419
- get_filesystem_usage() - Check all filesystems on default host
420
- get_filesystem_usage(host="db1.example.com") - Check remote host
421
- """
422
- from pcp_mcp.errors import handle_pcp_error
423
-
424
- async with get_client_for_host(ctx, host) as client:
425
- try:
426
- response = await client.fetch(FILESYSTEM_METRICS)
427
- except Exception as e:
428
- raise handle_pcp_error(e, "fetching filesystem metrics") from e
429
-
430
- filesystems = _build_filesystem_list(response)
431
- assessment = _assess_filesystems(filesystems)
432
-
433
- return FilesystemSnapshot(
434
- timestamp=datetime.now(timezone.utc).isoformat(),
435
- hostname=client.target_host,
436
- filesystems=filesystems,
437
- assessment=assessment,
438
- )
403
+
404
+ try:
405
+ sampling_result = await ctx.sample(
406
+ messages=f"Analyze these system metrics:\n\n{metrics_summary}",
407
+ system_prompt=system_prompt,
408
+ max_tokens=500,
409
+ result_type=DiagnosisResult,
410
+ )
411
+ result = sampling_result.result
412
+ result.timestamp = snapshot.timestamp
413
+ result.hostname = snapshot.hostname
414
+ return ToolResult(
415
+ content=result.model_dump_json(),
416
+ structured_content=result.model_dump(),
417
+ )
418
+ except Exception:
419
+ result = _build_fallback_diagnosis(snapshot)
420
+ return ToolResult(
421
+ content=result.model_dump_json(),
422
+ structured_content=result.model_dump(),
423
+ )
424
+
425
+
426
+ @tool(
427
+ annotations=TOOL_ANNOTATIONS,
428
+ icons=[ICON_FILESYSTEM],
429
+ tags=TAGS_FILESYSTEM,
430
+ timeout=30.0,
431
+ )
432
+ async def get_filesystem_usage(
433
+ ctx: Context,
434
+ host: Annotated[
435
+ Optional[str],
436
+ Field(description="Target pmcd host to query (default: server's configured target)"),
437
+ ] = None,
438
+ ) -> ToolResult:
439
+ """Get mounted filesystem usage (similar to df command).
440
+
441
+ Returns capacity, used, available, and percent full for each mounted
442
+ filesystem. Useful for monitoring disk space and identifying filesystems
443
+ that may need attention.
444
+
445
+ Examples:
446
+ get_filesystem_usage() - Check all filesystems on default host
447
+ get_filesystem_usage(host="db1.example.com") - Check remote host
448
+ """
449
+ from pcp_mcp.errors import handle_pcp_error
450
+
451
+ async with get_client_for_host(ctx, host) as client:
452
+ try:
453
+ response = await client.fetch(FILESYSTEM_METRICS)
454
+ except Exception as e:
455
+ raise handle_pcp_error(e, "fetching filesystem metrics") from e
456
+
457
+ filesystems = _build_filesystem_list(response)
458
+ assessment = _assess_filesystems(filesystems)
459
+
460
+ result = FilesystemSnapshot(
461
+ timestamp=datetime.now(timezone.utc).isoformat(),
462
+ hostname=client.target_host,
463
+ filesystems=filesystems,
464
+ assessment=assessment,
465
+ )
466
+ return ToolResult(
467
+ content=result.model_dump_json(),
468
+ structured_content=result.model_dump(),
469
+ )
439
470
 
440
471
 
441
472
  def _build_filesystem_list(response: dict) -> list[FilesystemInfo]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pcp-mcp
3
- Version: 1.3.2
3
+ Version: 1.4.0
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
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.14
18
18
  Classifier: Topic :: System :: Monitoring
19
19
  Classifier: Typing :: Typed
20
20
  Requires-Dist: cachetools>=5.0
21
- Requires-Dist: fastmcp>=2.0.0
21
+ Requires-Dist: fastmcp>=3.0.0b1
22
22
  Requires-Dist: httpx>=0.27
23
23
  Requires-Dist: pydantic-settings>=2.0.0
24
24
  Requires-Dist: typing-extensions>=4.0 ; python_full_version < '3.11'
@@ -0,0 +1,28 @@
1
+ pcp_mcp/AGENTS.md,sha256=kfitTd6NuPieWLTAl9-m-i93URL1DD7yu-AnK8kA8Yw,2407
2
+ pcp_mcp/__init__.py,sha256=5SKlrOQTqKxcWRvmBwmeXJapTqKggal8L89UxxwHTaQ,1949
3
+ pcp_mcp/client.py,sha256=ZGWGXYn77_hbZ81O0vxjXubY9eRpOZWs2cLxqLO3pf8,9188
4
+ pcp_mcp/config.py,sha256=gm-Sp1y-f3ZGZQk_ercMuKCojG145Fu6UjrvjRQUnpg,3526
5
+ pcp_mcp/context.py,sha256=5M6l72phsijPr96PXpZDm1rd_Uvo7mY_LuiLdeiW2SE,2801
6
+ pcp_mcp/errors.py,sha256=uixDH3NiteHuHr4-EIVM9XrsKirxkhe2L90fnjsKxOY,1737
7
+ pcp_mcp/icons.py,sha256=_ZrllbTM8Jp74EBpIIX5BaL8pN_1Ld6n29NWKoGAJD8,1625
8
+ pcp_mcp/middleware.py,sha256=oUSdaCHSy1gVkKyeC2J8ASfhJep-3KvY8GFYRFWUvJ0,2387
9
+ pcp_mcp/models.py,sha256=EPm1R7_qRLDFoqAzwegiv15KpHrmTJTjPD1LpxQdgoc,8202
10
+ pcp_mcp/prompts/__init__.py,sha256=g97146MaOnWDx2KdhRXdwXiUR5wx71lvU4iPwbC_Zj4,1015
11
+ pcp_mcp/prompts/cpu.py,sha256=s_sux0Q9YulPTuvbgw8StzpfB-omzBmMe7Wyf4kBlv4,2909
12
+ pcp_mcp/prompts/diagnose.py,sha256=y_pMKBdmiZ6Q6PjEtCd_9tgR9Sm3udMHyDgqt1BJe4E,2076
13
+ pcp_mcp/prompts/disk.py,sha256=8QJumxpcPvPV0jA4fDIj1q0v1yT1mNA1Apg9nBQFpsc,2701
14
+ pcp_mcp/prompts/memory.py,sha256=WyJEvEG0rQUJwmlCuJEIp5uTH3EudZF-OSb-U_K-TK0,2118
15
+ pcp_mcp/prompts/network.py,sha256=-9ei4yNgQVgvkMKb5OgBsYU5CiPWZhJDyP3kCO5Ihmo,2879
16
+ pcp_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ pcp_mcp/server.py,sha256=2A-1KzAp436qy29cP6jf6Npah6EvFJ-eiDCHUMhfQ4A,4779
18
+ pcp_mcp/tools/AGENTS.md,sha256=1yt_W-TYlGA0aWJYCM7D0i2D4899E6_kIhyoqP1np-g,1963
19
+ pcp_mcp/tools/__init__.py,sha256=7TRaPUx4pYzAj2aW0lULA1vws04K6_CUsnkO5aAUEK8,889
20
+ pcp_mcp/tools/metrics.py,sha256=MrctKTC6eNvj6GPQw4ZMbuE6lb5-G1HtdRAYzL7Oc78,6574
21
+ pcp_mcp/tools/system.py,sha256=T9WceT9D35WPTu9xCO9VpCoDny3YF476SQTsMVKGe8o,20454
22
+ pcp_mcp/utils/__init__.py,sha256=tTbcqrCV9pBBm7N3MwEI37Lc0JM1CVbw_etw36ejRWc,884
23
+ pcp_mcp/utils/builders.py,sha256=n13Ou6cb1-YToG-M31J8_jWajq8ioJx6tJTKnqaQiio,10293
24
+ pcp_mcp/utils/extractors.py,sha256=fy6aCI23JuGt73oIDxwPW_K4B0fJkFCF1VxYkBst0Y4,2279
25
+ pcp_mcp-1.4.0.dist-info/WHEEL,sha256=iHtWm8nRfs0VRdCYVXocAWFW8ppjHL-uTJkAdZJKOBM,80
26
+ pcp_mcp-1.4.0.dist-info/entry_points.txt,sha256=PhVo92EGoS05yEpHVRyKEsxKya_bWlPLodp-g4tr2Rg,42
27
+ pcp_mcp-1.4.0.dist-info/METADATA,sha256=Xpcjk0GKCQLp38fNZYwJMmnhdCGIsAkMA7WvS3JMI-8,6847
28
+ pcp_mcp-1.4.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.29
2
+ Generator: uv 0.9.30
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any