Compare commits
4 Commits
35d506df77
...
hotfix/too
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c66502e590 | ||
|
|
740ce31469 | ||
| b6983f036d | |||
|
|
21aadf6d82 |
@@ -187,14 +187,16 @@ trap - ERR
|
|||||||
|
|
||||||
# ── 7. RPM + smoke ──
|
# ── 7. RPM + smoke ──
|
||||||
say "7/7 Build/install CLI RPM + smoke tests"
|
say "7/7 Build/install CLI RPM + smoke tests"
|
||||||
bash scripts/release.sh
|
# release.sh already restarts mcplocal and runs the smoke suite against the
|
||||||
systemctl --user restart mcplocal && sleep 2
|
# binary it just installed. This step used to restart and re-run it a second
|
||||||
if pnpm test:smoke > /tmp/deploy-smoke.log 2>&1; then
|
# time, which put two full suites inside a minute and tripped mcpd's rate
|
||||||
grep -E "Tests |passed" /tmp/deploy-smoke.log | tail -2
|
# limiter: the second run failed with 429s and printed a false
|
||||||
|
# "SMOKE TESTS FAILED — consider rollback" over a perfectly healthy deploy.
|
||||||
|
# One run, one verdict.
|
||||||
|
if bash scripts/release.sh; then
|
||||||
say "Deploy complete — $TAG live. Rollback tag: $ROLLBACK_TAG"
|
say "Deploy complete — $TAG live. Rollback tag: $ROLLBACK_TAG"
|
||||||
else
|
else
|
||||||
tail -40 /tmp/deploy-smoke.log
|
warn "RELEASE OR SMOKE TESTS FAILED — system may be unhealthy. Consider rollback:"
|
||||||
warn "SMOKE TESTS FAILED — system may be unhealthy. Consider rollback:"
|
|
||||||
rollback_recipe
|
rollback_recipe
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { McpdClient } from './http/mcpd-client.js';
|
import type { McpdClient } from './http/mcpd-client.js';
|
||||||
import { DISCOVERY_TIMEOUT_MS } from './http/mcpd-client.js';
|
import { DISCOVERY_TIMEOUT_MS, TOOLCALL_TIMEOUT_MS } from './http/mcpd-client.js';
|
||||||
import type { McpRouter } from './router.js';
|
import type { McpRouter } from './router.js';
|
||||||
import { McpdUpstream } from './upstream/mcpd.js';
|
import { McpdUpstream } from './upstream/mcpd.js';
|
||||||
|
|
||||||
@@ -152,6 +152,10 @@ function syncUpstreams(router: McpRouter, mcpdClient: McpdClient, servers: McpdS
|
|||||||
// unreachable upstream cannot stall session init for the full tool-call window.
|
// unreachable upstream cannot stall session init for the full tool-call window.
|
||||||
const discoveryClient = mcpdClient.withTimeout(DISCOVERY_TIMEOUT_MS);
|
const discoveryClient = mcpdClient.withTimeout(DISCOVERY_TIMEOUT_MS);
|
||||||
|
|
||||||
|
// Everything else an upstream receives is a proxied tools/call, which can
|
||||||
|
// legitimately run past the 30s default (browser solvers, PDF extraction).
|
||||||
|
const toolClient = mcpdClient.withTimeout(TOOLCALL_TIMEOUT_MS);
|
||||||
|
|
||||||
// Remove stale upstreams
|
// Remove stale upstreams
|
||||||
const currentNames = new Set(router.getUpstreamNames());
|
const currentNames = new Set(router.getUpstreamNames());
|
||||||
const serverNames = new Set(servers.map((s) => s.name));
|
const serverNames = new Set(servers.map((s) => s.name));
|
||||||
@@ -164,7 +168,7 @@ function syncUpstreams(router: McpRouter, mcpdClient: McpdClient, servers: McpdS
|
|||||||
// Add/update upstreams for each server
|
// Add/update upstreams for each server
|
||||||
for (const server of servers) {
|
for (const server of servers) {
|
||||||
if (!currentNames.has(server.name)) {
|
if (!currentNames.has(server.name)) {
|
||||||
const upstream = new McpdUpstream(server.id, server.name, mcpdClient, server.description, discoveryClient);
|
const upstream = new McpdUpstream(server.id, server.name, toolClient, server.description, discoveryClient);
|
||||||
router.addUpstream(upstream);
|
router.addUpstream(upstream);
|
||||||
}
|
}
|
||||||
registered.push(server.name);
|
registered.push(server.name);
|
||||||
|
|||||||
@@ -62,6 +62,17 @@ export const LONG_RUNNING_TIMEOUT_MS = Number(process.env['MCPLOCAL_LONG_TIMEOUT
|
|||||||
*/
|
*/
|
||||||
export const DISCOVERY_TIMEOUT_MS = Number(process.env['MCPLOCAL_DISCOVERY_TIMEOUT_MS']) || 8_000;
|
export const DISCOVERY_TIMEOUT_MS = Number(process.env['MCPLOCAL_DISCOVERY_TIMEOUT_MS']) || 8_000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Budget for proxied tools/call. The 30s DEFAULT_TIMEOUT_MS is a guaranteed
|
||||||
|
* failure for tools that legitimately run long — web_url_read through a
|
||||||
|
* browser solver, a large PDF extraction, a slow retail site — all of which
|
||||||
|
* died as `mcpd proxy error: mcpd did not respond within 30000ms` while mcpd
|
||||||
|
* was still working. Distinct from LONG_RUNNING_TIMEOUT_MS (chat/inference,
|
||||||
|
* minutes) and DISCOVERY_TIMEOUT_MS (list calls, must stay short so a dead
|
||||||
|
* upstream cannot stall session init). Override via `MCPLOCAL_TOOLCALL_TIMEOUT_MS`.
|
||||||
|
*/
|
||||||
|
export const TOOLCALL_TIMEOUT_MS = Number(process.env['MCPLOCAL_TOOLCALL_TIMEOUT_MS']) || 120_000;
|
||||||
|
|
||||||
export class McpdClient {
|
export class McpdClient {
|
||||||
private readonly baseUrl: string;
|
private readonly baseUrl: string;
|
||||||
private readonly token: string;
|
private readonly token: string;
|
||||||
|
|||||||
@@ -176,9 +176,13 @@ export function registerProjectMcpEndpoint(app: FastifyInstance, mcpdClient: Mcp
|
|||||||
chain.push(createAgentsPlugin());
|
chain.push(createAgentsPlugin());
|
||||||
router.setPlugin(composePlugins(chain));
|
router.setPlugin(composePlugins(chain));
|
||||||
|
|
||||||
// Fetch project instructions and set on router
|
// Fetch project instructions and set on router. Must ride the CALLER's
|
||||||
|
// token (requestClient) like every other downstream call here: in HTTP
|
||||||
|
// mode mcpdClient's own token is empty, mcpd answers 401, and the catch
|
||||||
|
// below swallowed it — every session initialized with no instructions
|
||||||
|
// while nothing looked broken (#113).
|
||||||
try {
|
try {
|
||||||
const instructions = await mcpdClient.get<{ prompt: string; servers: Array<{ name: string; description: string }> }>(
|
const instructions = await requestClient.get<{ prompt: string; servers: Array<{ name: string; description: string }> }>(
|
||||||
`/api/v1/projects/${encodeURIComponent(projectName)}/instructions`,
|
`/api/v1/projects/${encodeURIComponent(projectName)}/instructions`,
|
||||||
);
|
);
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user