Serving Markdown to AI agents with PHP content negotiation
Inspecting HTTP headers in PHP lets you serve lean Markdown to agents without duplicate static files.
A PHP service can verify callers and cap request volume before tool calls reach the database; WebAgentScan can help evaluate the exposed endpoint afterward.
A public MCP endpoint can turn an ordinary database query into a repeated, expensive operation. A well-meaning agent may retry. A misconfigured client may send bursts. An unauthorized caller may try the same endpoint until backend resources run short.
For a PHP site exposing tools over the web, the practical answer is to put checks in the request path before any tool handler opens a database connection. That means authenticating callers, throttling requests, and limiting what each tool can do. BuiltToWinWeb’s WebAgentScan can assess a site’s AI-agent readiness and MCP security as a separate evaluation step. It does not replace those runtime controls.
Consider a service that exposes an MCP tool for looking up a customer’s order status. The tool needs to read a small set of records. It does not need unrestricted SQL, access to every customer, or the ability to make unlimited calls.
Write down the tool’s allowed inputs, data scope, and expected call rate before connecting it to the database. This gives you a baseline for deciding which requests to reject and what a reasonable quota looks like. There is no universal safe request limit; it depends on the work each call triggers and the capacity available to the application.
Require a credential for every caller that is permitted to use the endpoint. For a controlled integration, a bearer token can be a straightforward option, provided the client and server can handle it securely. Do not put secrets in a URL, where they can end up in logs or browser history. Send them in an authorization header over HTTPS.
In PHP, check the credential before dispatching a tool call or starting a database transaction. Compare secrets using a constant-time comparison such as hash_equals, and keep the expected secret outside the web root and source repository. Give each client its own credential where practical. That makes revocation and usage limits more precise than sharing one permanent token among every agent.
Authentication requirements differ by client and transport. Preserve the MCP transport’s expected request and error behavior; do not assume that a custom check can replace protocol handling. CORS is not authentication, and a secret embedded in public browser code is not secret.
Apply a request limit immediately after authentication and before invoking the tool. A useful starting policy combines a short-window burst cap with a longer-window quota. Track usage by token, and consider a secondary IP limit for anonymous or malformed traffic. IP addresses alone are a poor identity key: many legitimate users can share one address, while callers can change addresses.
Use a shared limiter store when requests can reach more than one application process or server. A counter held only in one PHP worker will not impose a reliable site-wide limit. Set a maximum number of concurrent tool operations as well. Rate limits reduce volume over time; concurrency caps help contain simultaneous slow queries.
When a caller exceeds its allowance, reject the request before database work and return an appropriate rate-limit response, including a retry hint where the transport permits it. Set request-size and execution-time limits too. A small request can still trigger an expensive query, so validate tool arguments and impose query-level bounds rather than relying on traffic controls alone.
Expose named operations with validated inputs, not a general-purpose query tool. Bind values in database queries, cap result counts, and restrict records to the caller’s authorized scope. Use a database account with only the permissions the tools need. These controls limit damage if a token is misused or a tool is called in an unexpected pattern.
Log denied requests, throttling events, tool names, and execution duration. Avoid logging bearer tokens or sensitive query results. Review patterns that suggest retries or repeated expensive calls, then tune limits against measured workload rather than raising them automatically.
Test valid and invalid credentials, expired or revoked tokens, bursts above the quota, oversized inputs, and concurrent slow calls. Confirm rejected requests do not open database connections. Test across multiple PHP workers if the application runs that way. A limiter that works in a single-process test can fail under real traffic if its counters are local.
After deployment, use WebAgentScan as an evaluation step for the site’s AI-agent readiness and MCP security. Its score is useful as a signal to investigate, not a substitute for load tests, access-control tests, or server logs. For background on the broader endpoint setup, see the earlier guide to resolving readiness issues and securing MCP endpoints.
The trade-off is operational work: credentials need rotation, quotas need tuning, and shared limit state adds a dependency. But those costs are easier to manage than an exposed tool that lets an agent’s retry loop consume the database capacity needed by the rest of the site.
Inspecting HTTP headers in PHP lets you serve lean Markdown to agents without duplicate static files.
A direct evaluation of total cost, runtime performance, and security upkeep between hand-crafted PHP sites and headless web stacks.
Combining CLI asset optimization, pre-merge IDE guardrails, and hosted agent scans keeps custom web builds lean and machine-readable.