mcp: guard the connection, not just the first dial
Refresh called alive() with the manager lock held, so a slow health check blocked every other server. It now snapshots the candidates and asks outside the lock. A server that cannot be dialled was retried every minute forever, which for a misconfigured stdio block means re-exec'ing a process 1440 times a day. Dials now back off from one minute to thirty. An allow_private fetcher followed redirects. A LAN MCP endpoint could answer a POST with a redirect to 169.254.169.254 and the guard would go there, because allow_private is what turns the address check off. Redirects are refused outright on that door. The tool catalogue was trimmed by taking the first max_tools entries of whatever order the server sent, so the server chose which of its tools Maven proposed. Over the cap without allow_tools now contributes nothing: refusing is honest, silently keeping the server's pick is not. Descriptions are server-written text that lands in the router prompt and on /tools, so they are capped too. A server block with enabled false was skipped by validation, so a typo in a block written dark surfaced only on the day it was switched on. All blocks are shape-checked now. Configured static headers carry the bearer token a real remote server needs, and host_interval bounds how fast one endpoint is polled. Found in review of #70.
This commit is contained in:
@@ -16,10 +16,20 @@ import (
|
||||
// must not become a hole for some public endpoint that happens to redirect at
|
||||
// the LAN. Rate limiting is per fetcher too, which is the right shape here:
|
||||
// separate servers are separate hosts.
|
||||
//
|
||||
// A server WITH allow_private also gets redirects switched off. Across servers
|
||||
// the per-fetcher split holds the line; within the one server that has the
|
||||
// flag it did not, because allow_private disables the dialer guard on every
|
||||
// hop: http://localhost:9100/mcp answering 302 to
|
||||
// http://169.254.169.254/latest/meta-data/ was followed, up to MaxRedirects. A
|
||||
// local MCP endpoint has no business redirecting, so refusing costs nothing.
|
||||
func WebfetchDoor(limits webfetch.Config) PosterFactory {
|
||||
return func(cfg ServerConfig) (Poster, error) {
|
||||
c := limits
|
||||
c.AllowPrivate = cfg.AllowPrivate
|
||||
if cfg.AllowPrivate {
|
||||
c.MaxRedirects = -1 // negative ⇒ no redirects followed
|
||||
}
|
||||
if c.Timeout <= 0 && cfg.Timeout > 0 {
|
||||
c.Timeout = cfg.Timeout
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user