phpray
Ask an agent why a PHP site is slow: every request with its SQL, HTTP calls, errors and N+1.
Should I use this
Quality & Safety
Findings (1)
- LOWin phpray_components
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"phpray": {
"url": "https://phpray.dev/mcp"
}
}
}Remote endpoints
https://phpray.dev/mcpstreamable-httpWhat it can do
Tool inventory
Tools (10)
🟢phpray_sites
List the PHP sites this token can see, with requests, p95 latency and error rate. Start here: every other tool needs a site_id from this list.
Input Schema
{
"type": "object",
"properties": {}
}⚪phpray_overview(site_id, window_minutes)
Headline numbers for one site over a time window: requests, errors, p50/p95/p99 latency, database share and N+1 count. Use this before digging into anything else.
Input Schema
{
"type": "object",
"properties": {
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"window_minutes": {
"description": "How far back to look, in minutes. Default 60.",
"type": "integer"
}
},
"required": [
"site_id"
]
}⚪phpray_slow_pages(limit, site_id, window_minutes)
The slowest URLs on a site, with request counts and p95, from the request timeseries. Answers "which page is slow".
Input Schema
{
"type": "object",
"properties": {
"limit": {
"description": "How many URLs to return. Default 25.",
"type": "integer"
},
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"window_minutes": {
"description": "How far back to look. Default 1440.",
"type": "integer"
}
},
"required": [
"site_id"
]
}🟢phpray_slow_queries(limit, site_id, window_minutes)
SQL fingerprints ordered by time spent, with call counts and the caller when known. Literals are already masked. Answers "which query is slow".
Input Schema
{
"type": "object",
"properties": {
"limit": {
"description": "How many queries to return. Default 20.",
"type": "integer"
},
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"window_minutes": {
"description": "How far back to look. Default 1440.",
"type": "integer"
}
},
"required": [
"site_id"
]
}⚪phpray_components(limit, site_id, window_minutes)
Time attributed to each plugin, theme or vendor package on profiled requests. Answers "which plugin is slowing the site down". Empty when function profiling is off.
Input Schema
{
"type": "object",
"properties": {
"limit": {
"description": "How many components to return. Default 20.",
"type": "integer"
},
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"window_minutes": {
"description": "How far back to look. Default 1440.",
"type": "integer"
}
},
"required": [
"site_id"
]
}⚪phpray_errors(limit, site_id, window_minutes)
Requests that failed on a site: PHP errors and warnings with file and line where PHP raised one, plus 5xx responses that carry no PHP error. Pass an id to phpray_trace to see what one of them did.
Input Schema
{
"type": "object",
"properties": {
"limit": {
"description": "How many to return. Default 20.",
"type": "integer"
},
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"window_minutes": {
"description": "How far back to look. Default 1440.",
"type": "integer"
}
},
"required": [
"site_id"
]
}🟢phpray_traces(limit, min_ms, site_id, status, window_minutes)
Recent requests for a site. Filter with min_ms and status to find the bad ones, then pass an id to phpray_trace.
Input Schema
{
"type": "object",
"properties": {
"limit": {
"description": "How many to return. Default 50.",
"type": "integer"
},
"min_ms": {
"description": "Only requests slower than this.",
"type": "integer"
},
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"status": {
"description": "Only this HTTP status, e.g. 500.",
"type": "integer"
},
"window_minutes": {
"description": "How far back to look. Default 1440.",
"type": "integer"
}
},
"required": [
"site_id"
]
}⚪phpray_trace(trace_id)
One request in full: wall time split into PHP, database and outbound HTTP, every query, every external call, errors, and the component breakdown when the request was profiled.
Input Schema
{
"type": "object",
"properties": {
"trace_id": {
"description": "Trace id from phpray_traces.",
"type": "string"
}
},
"required": [
"trace_id"
]
}🟡phpray_compare(from_a, from_b, site_id, to_a, to_b)
Two time ranges for one site side by side. Use it to check whether a deployment, a plugin update or a configuration change made things better or worse.
Input Schema
{
"type": "object",
"properties": {
"from_a": {
"description": "Start of range A (the earlier one), unix seconds. Without any range: the day before yesterday's 24 h against the last 24 h.",
"type": "integer"
},
"from_b": {
"description": "Start of range B, unix seconds.",
"type": "integer"
},
"site_id": {
"description": "Site id from phpray_sites.",
"type": "string"
},
"to_a": {
"description": "End of range A, unix seconds.",
"type": "integer"
},
"to_b": {
"description": "End of range B, unix seconds.",
"type": "integer"
}
},
"required": [
"site_id"
]
}⚪phpray_alerts
Alerts currently firing across every site this token can see, worst overrun first.
Input Schema
{
"type": "object",
"properties": {}
}Community
Evidence