Skip to content
stake.linkInstitutional analytics, home page
The stake.link docs shelf

The docs, but human first.

This is the plain English walkthrough of the stake.link MCP, the strategy planner, and the unsigned builders. If you prefer to read the specs, the three source files are one click away in the shelf below. If you want the shape first, stay here and read the loop before you crack them open.

60 live tools3 MCP resourcesEthereum mainnetSepolia validated
Endpoint

What you get

POSTJSON-RPC 2.0
MCP endpoint
https://www.stakedotlink.money/mcp
Read and planning tools50
Unsigned builders10
Markdown resources over MCP3

No API key, no sign-in, no wallet custody.

Architecture

The loop, in five moves.

  1. Your agent asks for state

    It calls a read tool like sdl_protocol_summary or sdl_get_defi_curve. The MCP hits Ethereum RPC, verified contracts, the subgraph, and protocol APIs, then hands back the real numbers. No vibes, no stale snapshots.

  2. Your agent asks for a plan

    It calls sdl_strategy_plan with the route it wants. The planner returns the exact sequence of steps, ordered, with each step pointing at the builder that owns it. Later steps reference real previous outputs, not fake placeholders.

  3. Your agent asks for calldata

    It calls the relevant builder, say sdl_build_stake_link or sdl_build_curve_swap. The MCP returns any approvals you need plus the unsigned call. It never signs. It never broadcasts. The shape is always the same across builders.

  4. The MCP simulates the tx

    Builders fork mainnet on Tenderly and replay the call before returning. Reverts, bad slippage, and missing approvals get caught server side, so your agent sees the failure before a real wallet touches real gas.

  5. You sign from your own wallet

    The calldata goes to whatever signer you plug in, browser wallet, viem client, Ledger, whatever. The broadcast happens from you. The MCP never holds a key, never holds state about you, and never requires an API key to try.

The shelf

Three docs, each for a different moment.

One real example

Stake 10 LINK, in code.

This is the smallest end to end example that still proves the shape. You ask the MCP to build an unsigned stake of 10 LINK. It returns the approval and the stake call, already simulated on a mainnet fork. You sign each call from your own viem wallet and broadcast.

Everything the MCP touches is public state. Everything that moves value is you signing. That split is the whole point.

  1. Ask the MCP to build an unsigned stake of 10 LINK.
  2. Parse the tool output. It lands as a JSON string inside the first content block.
  3. Sign any approval the builder returned, then sign the main call. LINK uses ERC677, so this one skips the approval.
  4. Broadcast to mainnet from your own wallet and check the receipt for stLINK.
TypeScript with viem
import { createWalletClient, http, parseUnits } from 'viem';
import { mainnet } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

// Your signer. The MCP never sees this.
const account = privateKeyToAccount(process.env.SIGNER_KEY as `0x${string}`);
const wallet = createWalletClient({ account, chain: mainnet, transport: http() });

// Ask stake.link's MCP to build the unsigned stake call.
const res = await fetch('https://www.stakedotlink.money/mcp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'tools/call',
    params: {
      name: 'sdl_build_stake_link',
      arguments: {
        amount_link: parseUnits('10', 18).toString(),
        from: account.address,
      },
    },
  }),
}).then((r) => r.json());

// Tool output is a JSON string inside the first content block.
const tx = JSON.parse(res.result.content[0].text) as {
  to: `0x${string}`;
  data: `0x${string}`;
  value: string;
  chainId: 1;
  approval?: { to: `0x${string}`; data: `0x${string}`; value: string };
  metadata: { action: string; inputAmount: string; notes?: string[] };
};

// If the builder returned an approval, sign it first.
if (tx.approval) {
  await wallet.sendTransaction({
    to: tx.approval.to,
    data: tx.approval.data,
    value: BigInt(tx.approval.value),
  });
}

// Sign the main call. LINK uses ERC677 transferAndCall, so no approval here.
const hash = await wallet.sendTransaction({
  to: tx.to,
  data: tx.data,
  value: BigInt(tx.value),
});

console.log(tx.metadata.action, hash);
Ready to build

Plug it in and try it.

One endpoint, no key, no sign-in. Wire it into Claude, Cursor, or Codex, or hit it with curl and watch the shape. If you want the full reference first, AGENTS.md is right there.

stake.link docs, for humans who build