Skip to content

Self-host tools/list blocks on sequential stale remote catalog refresh #1519

Description

@salmonumbrella

Summary

On the official self-hosted v1.5.37 image, a remote MCP client shows materially higher end-to-end latency through Executor than through a direct MCP server over the same transport.

Warm downstream work is fast (roughly 50–100 ms), and Executor's own HTTP spans are usually under 100 ms, but end-to-end calls are commonly measured around 4–5.5 seconds. A comparable direct MCP call over the same tunnel is around 1.1 seconds. This does not prove that the steady-state gap is entirely inside Executor, but the current logs do not provide enough timing detail to identify where it is introduced.

Separately, there is a concrete periodic stall: the first tools/list after remote catalogues become stale can block for 12–15 seconds while catalogues refresh.

Environment

  • Executor self-host v1.5.37, official container image
  • Linux amd64
  • Dozens of configured integrations/connections
  • Several thousand persisted tools
  • Streamable HTTP MCP behind a private tunnel
  • Healthy host with no CPU, memory, restart, or OOM pressure

Observed behavior

Most tunnel-to-Executor POST /mcp requests complete in under 100 ms. However, one request took approximately 13 seconds, and the matching application log reported:

executor tool sync preserved catalog
reason: plugin returned an incomplete tool catalog

A separate API execution during the same refresh pattern took approximately 15 seconds.

The source appears to explain this behavior:

  • Remote catalogues expire on a default 15-minute TTL.
  • syncStaleConnectionTools iterates stale connections sequentially.
  • Each produceConnectionTools call is awaited before toolsList returns.
  • Cached catalogues are preserved on failure, but the foreground request still waits for the attempted refresh.

Relevant implementation:

https://github.com/UsefulSoftwareCo/executor/blob/main/packages/core/sdk/src/executor.ts

Expected behavior

  • Return the persisted catalogue immediately when one is available.
  • Refresh stale remote catalogues asynchronously, or concurrently with bounded timeouts.
  • A slow or unavailable integration should not delay unrelated tool discovery.
  • Self-host operators should have a supported way to configure or disable time-based catalogue refresh.
  • Logs or spans should make it possible to separate MCP session setup, catalogue refresh, QuickJS execution, downstream tool time, serialization, and response delivery.

Reproduction outline

  1. Configure multiple remote MCP integrations.
  2. Allow their persisted catalogues to age beyond the default TTL.
  3. Start a fresh MCP session and request tools/list.
  4. Observe that the request waits for stale remote catalogue refreshes.
  5. Repeat immediately and observe that the warm request is much faster.

Questions

  1. Is there currently a supported self-host setting for toolsSyncTtlMs? The SDK accepts null, but the stock self-host configuration does not appear to expose it.
  2. Would serving cached tools first and refreshing in the background be acceptable?
  3. Is there an existing trace/debug mode for breaking down the steady end-to-end MCP latency described above?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions