How the Arbitrum MCP Server Resolves Chain Names to RPC URLs
The Arbitrum MCP Server resolves chain names to RPC URLs through a four-step resolution algorithm in ArbitrumMCPServer.resolveRpcUrl that checks for direct URLs, queries a cached ChainLookupService for known chains, falls back to treating the input as a custom endpoint, or uses a default RPC URL.
When interacting with the dewanshparashar/arbitrum-mcp repository, tools like arbos_version, node_health, and list_chains accept a chainName parameter that must be converted into a concrete JSON-RPC endpoint. The server handles this translation seamlessly through a centralized resolution mechanism that supports both well-known Arbitrum chains and custom endpoints.
Resolution Algorithm in ArbitrumMCPServer.resolveRpcUrl
The primary resolution logic lives in src/index.ts within the ArbitrumMCPServer.resolveRpcUrl method (lines 54-71). This method implements a priority-based lookup system that processes user input through four distinct stages.
Step 1: Direct URL Detection
If the supplied string starts with http:// or https://, the server returns it unchanged. This shortcut allows users to bypass the lookup system entirely and provide raw RPC endpoints directly.
Step 2: Chain Lookup via ChainLookupService
When the input is not a URL, the server delegates to the singleton ChainLookupService obtained via ChainLookupService.getInstance(). The service method findChainByName(chainNameOrUrl) searches a cached list of chain descriptors for matching name or slug fields.
The underlying data originates from ChainLookupService.fetchChainsData() in src/services/chain-lookup.ts, which merges two sources:
- Core Arbitrum chains: Arbitrum One and Nova, defined in-code via
@arbitrum/sdkthrough thegetCoreArbitrumChainsfunction (lines 79-147) - Orbit chains: Loaded from the public JSON file at
https://raw.githubusercontent.com/OffchainLabs/arbitrum-token-bridge/master/packages/arb-token-bridge-ui/src/util/orbitChainsData.json
The combined array is stored in this.chainsData with a 5-minute cache TTL (CACHE_TTL). If a match is found, the method returns the chain's rpcUrl field.
Step 3: Fallback to Custom URL
If the lookup fails to find a known chain, the server assumes the input string is a custom RPC URL and returns it as-is. This provides flexibility for private or development networks not listed in the official registries.
Step 4: Default RPC URL
When no chainName argument is supplied, the method falls back to this.defaultRpcUrl, ensuring the server always has a valid endpoint for instantiating clients like NitroNodeClient, ArbitrumChainClient, or EthereumAccountClient.
The ChainLookupService Implementation
Located in src/services/chain-lookup.ts, the ChainLookupService acts as the authoritative source for chain metadata across the Arbitrum ecosystem.
Core Arbitrum Chains
The getCoreArbitrumChains function (lines 79-147) constructs descriptors for Arbitrum One and Nova, including their hard-coded RPC URLs. These foundational chains are always available regardless of external network requests.
Orbit Chains from Remote JSON
The service fetches dynamic chain data from the OffchainLabs Arbitrum token bridge repository. This JSON contains names, slugs, RPC URLs, and bridge addresses for all Orbit-deployed chains, enabling immediate support for new chains without code modifications.
Caching Strategy
To minimize external requests, the service caches the merged chain data for five minutes. Subsequent lookups during this window hit the local cache, significantly improving response times for tools like list_chains that enumerate available networks.
Practical Code Examples
Resolving Chain Names Directly
import { ArbitrumMCPServer } from './index.js';
async function demo() {
const server = new ArbitrumMCPServer();
// Resolve a known chain name
const rpc1 = await (server as any).resolveRpcUrl('Arbitrum One');
console.log(rpc1); // → https://arb1.arbitrum.io/rpc
// Resolve a custom URL (passed through unchanged)
const rpc2 = await (server as any).resolveRpcUrl('https://my-custom-node.io/rpc');
console.log(rpc2); // → https://my-custom-node.io/rpc
}
demo();
The resolveRpcUrl method is defined in src/index.ts (lines 54-71).
Using the MCP Tool Interface
When calling tools via an MCP client, the resolution happens automatically:
{
"name": "arbos_version",
"arguments": {
"chainName": "Xai"
}
}
Internally, the server executes:
const rpcUrl = await this.resolveRpcUrl(args.chainName);
const client = new NitroNodeClient(rpcUrl);
const version = await client.getArbOSVersion();
The name "Xai" is matched against cached OrbitChainData, returning the appropriate RPC URL (e.g., https://xai-chain.net/rpc) for the NitroNodeClient instantiation.
Refreshing Chain Data at Runtime
await server.chainLookupService.fetchChainsData(); // forces refresh
// after the fetch you can call findChainByName on the new entry
const custom = await server.chainLookupService.findChainByName('my-chain');
console.log(custom?.rpcUrl);
Because fetchChainsData pulls the latest JSON from the Orbit repository, newly added chains become available immediately without restarting the server.
Key Source Files and Functions
src/index.ts–ArbitrumMCPServer.resolveRpcUrl: Central resolution logic handling URL detection, name lookup, fallback mechanisms, and default handling.src/services/chain-lookup.ts–ChainLookupService: Singleton service managing chain metadata, cache lifecycle, and thefindChainByNamelookup method.src/services/chain-lookup.ts–getCoreArbitrumChains: In-code definitions for Arbitrum One and Nova including hard-coded RPC endpoints.- Orbit chains JSON: External registry at
https://raw.githubusercontent.com/OffchainLabs/arbitrum-token-bridge/master/packages/arb-token-bridge-ui/src/util/orbitChainsData.jsoncontaining Orbit chain configurations.
Summary
ArbitrumMCPServer.resolveRpcUrlinsrc/index.tsimplements a four-stage resolution algorithm prioritizing direct URLs, known chain lookups, custom endpoints, and default fallbacks.ChainLookupServicemaintains a merged registry of core Arbitrum chains and Orbit chains, caching results for five minutes to optimize performance.- The system supports human-readable names (e.g., "Arbitrum One", "Nova"), slugs (e.g., "arbitrum-nova"), raw URLs, and custom endpoints through a unified interface.
- Chain data automatically updates by fetching the latest Orbit chains JSON from the OffchainLabs repository, requiring no code changes to support new networks.
Frequently Asked Questions
What happens if I provide a full HTTP URL as the chainName?
If the input string begins with http:// or https://, ArbitrumMCPServer.resolveRpcUrl returns it immediately without modification. This bypasses the ChainLookupService entirely, allowing direct connection to any compatible JSON-RPC endpoint.
How often does the Arbitrum MCP Server refresh its chain list?
The ChainLookupService caches chain data for 5 minutes (CACHE_TTL). After this period expires, the next lookup triggers fetchChainsData() to reload core chains and refetch the Orbit chains JSON from the remote repository.
Can I use chain slugs instead of full names?
Yes. The findChainByName method in ChainLookupService searches both the name and slug fields of each chain descriptor. You can use identifiers like "arbitrum-nova" or "Xai" interchangeably with their full canonical names.
Where are the core Arbitrum One and Nova RPC URLs defined?
These are hard-coded within the getCoreArbitrumChains function in src/services/chain-lookup.ts (lines 79-147), which uses the @arbitrum/sdk package to construct the chain descriptors with their official RPC endpoints.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →