You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sub-issue of #382 (part 3 of 3). Extend credit awareness (low-credits advisory note + 402 credit-exhaustion handling) to read_contract, which uses a separate transport and is intentionally excluded from parts 1 and 2.
Depends on part 1 (#393) and part 2 (#394), which establish CreditsExhaustedError, the CreditSink/ContextVar mechanism, and the low-credits note on the HTTP transport.
Background
read_contract does not go through _make_blockscout_http_request. It calls smart-contract functions via web3.py over the PRO API RPC endpoint through WEB3_POOL (blockscout_mcp_server/web3_pool.py). As a result:
The x-credits-remaining header from the RPC responses is not captured, so read_contract responses never carry the low-credits note.
A credit-related 402 on the RPC path would surface as a generic web3 exception, notCreditsExhaustedError.
This means the "applies to every tool" intent of #382 is consciously narrowed in parts 1–2; this issue closes that gap for the web3 transport.
Open questions to resolve
Does the PRO API RPC path consume credits and return x-credits-remaining? (Note: /api/eth-rpc was rejected in direct_api_call per Reject on /api/eth-rpc in direct_api_call #389 — clarify how RPC requests are routed/priced for the web3 pool.)
How to intercept web3 HTTP response headers (e.g. a custom AsyncHTTPProvider / request middleware on the pooled provider) so the value can be fed into the same CreditSink.
How to detect and map an RPC-level credit rejection to CreditsExhaustedError.
Proposed Changes (to be refined after the open questions)
Hook the WEB3_POOL provider so successful RPC responses feed x-credits-remaining into the per-invocation CreditSink (reusing the part-2 mechanism), making the low-credits note appear on read_contract responses.
Map RPC credit-exhaustion to CreditsExhaustedError so read_contract produces the same distinct error as the HTTP-transport tools.
Tests
read_contract populates the CreditSink from RPC responses and surfaces the low-credits note via build_tool_response.
RPC credit-exhaustion maps to CreditsExhaustedError (and REST → 402).
Documentation
SPEC.md: remove/replace the part-1/2 scope note that excludes the web3 path; document the unified behavior.
Description
Sub-issue of #382 (part 3 of 3). Extend credit awareness (low-credits advisory note +
402credit-exhaustion handling) toread_contract, which uses a separate transport and is intentionally excluded from parts 1 and 2.Depends on part 1 (#393) and part 2 (#394), which establish
CreditsExhaustedError, theCreditSink/ContextVarmechanism, and the low-credits note on the HTTP transport.Background
read_contractdoes not go through_make_blockscout_http_request. It calls smart-contract functions viaweb3.pyover the PRO API RPC endpoint throughWEB3_POOL(blockscout_mcp_server/web3_pool.py). As a result:x-credits-remainingheader from the RPC responses is not captured, soread_contractresponses never carry the low-credits note.402on the RPC path would surface as a genericweb3exception, notCreditsExhaustedError.This means the "applies to every tool" intent of #382 is consciously narrowed in parts 1–2; this issue closes that gap for the web3 transport.
Open questions to resolve
x-credits-remaining? (Note:/api/eth-rpcwas rejected indirect_api_callper Reject on/api/eth-rpcin direct_api_call #389 — clarify how RPC requests are routed/priced for the web3 pool.)AsyncHTTPProvider/ request middleware on the pooled provider) so the value can be fed into the sameCreditSink.CreditsExhaustedError.Proposed Changes (to be refined after the open questions)
WEB3_POOLprovider so successful RPC responses feedx-credits-remaininginto the per-invocationCreditSink(reusing the part-2 mechanism), making the low-credits note appear onread_contractresponses.CreditsExhaustedErrorsoread_contractproduces the same distinct error as the HTTP-transport tools.Tests
read_contractpopulates theCreditSinkfrom RPC responses and surfaces the low-credits note viabuild_tool_response.CreditsExhaustedError(and REST →402).Documentation
SPEC.md: remove/replace the part-1/2 scope note that excludes the web3 path; document the unified behavior.