Skip to main content
Glama
IntentGuardLabs

IntentGuard MCP Server

Official
README.md
# IntentGuard MCP Server

> Includes a full end-to-end agent simulation test runnable locally in dry-run mode (no chain required).

A [Model Context Protocol](https://modelcontextprotocol.io) server that gives AI agents the ability to submit Ethereum transactions with on-chain outcome protection.

IntentGuard wraps any DeFi transaction with two enforcement transactions. If the declared balance constraints are violated at execution time, the transaction is dropped before inclusion — and no gas is consumed.

---

## Architecture

The MCP server has a single, well-defined role: **it builds the two protective transactions and validates the signed bundle before submission**. It does not build or inspect the underlying DeFi transaction.

```
Protocol skill / wallet  →  builds the action transaction
IntentGuard agent skill  →  extracts and confirms protection constraints
IntentGuard MCP          →  compiles protection package, validates and submits
On-chain enforcer        →  allows or rejects execution
```

The MCP exposes exactly two tools:

| Tool | Role |
|------|------|
| `prepare_protected_transaction` | Compiler — produces two unsigned enforcement transactions and a nonce layout |
| `submit_protected_bundle` | Submitter — validates the signed bundle (pre + action + post) and submits to the relay |

---

## Prerequisites

- Node.js >= 22
- Access to the IntentGuard relay (default: `https://sepolia.rpc.intentguard.xyz`)

---

## Install & Build

```bash
npm install
npm run build
```

The compiled entrypoint is `dist/index.js`. It includes a `#!/usr/bin/env node` shebang and is executable.

---

## Configuration

The server is configured entirely via environment variables.

| Variable | Required | Default | Description |
|---|---|---|---|
| `INTENTGUARD_CHAIN_ID` | **yes** | — | EVM chain ID (e.g. `11155111` for Sepolia, `1` for mainnet) |
| `INTENTGUARD_RPC_URL` | no | `https://sepolia.rpc.intentguard.xyz` | IntentGuard relay endpoint |
| `INTENTGUARD_ENFORCER_TYPE` | no | `balance` | Enforcer contract type |

The enforcer contract address is resolved automatically from the relay — no contract address configuration is required.

---

## Connecting to an Agent

Add the server to your agent's MCP configuration. Example for Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "intentguard": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server/dist/index.js"],
      "env": {
        "INTENTGUARD_CHAIN_ID": "11155111"
      }
    }
  }
}
```

The agent spawns the server as a subprocess over stdio. No port or hosting is required.

---

## Tools

### `prepare_protected_transaction`

Produces two unsigned enforcement transactions that wrap a given action transaction.

**Does not receive or build the action transaction.** The action transaction is constructed upstream by the wallet or protocol skill.

**Input:**
- `userAddress` — wallet address that will sign all three transactions
- `protectionIntent` — structured protections:
  - `max_spend` — cap outflow of a token
  - `min_receive` — guarantee minimum inflow of a token
  - `no_balance_decrease` — ensure balance does not decrease
- `validUntilBlock` *(optional)* — protection expiry block; defaults to current block + 10

**Output:**
- `preTx` — unsigned pre-enforcement transaction (`nonce N`)
- `postTx` — unsigned post-enforcement transaction (`nonce N+2`)
- `nonceLayout` — `{ pre: N, action: N+1, post: N+2 }`
- `summary` — human-readable protection list and signing instructions

The caller assigns `nonceLayout.action` to the action transaction and signs all three.

---

### `submit_protected_bundle`

Validates and submits a fully signed bundle of three transactions.

**Input:**
- `signedPreTx` — signed pre-enforcement transaction (`nonce N`)
- `signedUserTx` — signed action transaction (`nonce N+1`, built externally)
- `signedPostTx` — signed post-enforcement transaction (`nonce N+2`)
- `retryUntilBlock` *(optional)* — retry deadline; defaults to current block + 25

**Pre-submission validation** (failures returned immediately, no submission attempt):
1. All three transactions are EIP-1559 (type 2)
2. All three are signed by the same address
3. Nonces are strictly sequential: N, N+1, N+2
4. All three target the same chain ID

**Return:**
- Constraints satisfied → transaction hash, signer, confirmed nonce layout
- Constraints violated → bundle dropped, no gas paid

Returns the final bundle outcome directly. No separate receipt polling is required.

---

## Testing

```bash
npm test
```

The test suite covers:
- Nonce layout assignment and boundary cases
- Output shape — action transaction is never returned by the MCP
- Default block window behaviour
- All protection types (max_spend, min_receive, no_balance_decrease)
- Input schema validation
- Bundle validation (nonce ordering, signer consistency, chain ID consistency)
- Error paths (network failures, SDK errors, malformed inputs)
- Full end-to-end flow: prepare → sign → submit

---

## End-to-end test (agent simulation)

This repository includes a full end-to-end test that simulates an AI agent using IntentGuard over the MCP protocol.

The script:
- launches the MCP server as a subprocess (stdio transport, exactly as Claude / Cursor do)
- connects as an MCP client
- calls `prepare_protected_transaction`
- assigns nonce `N+1` to the action transaction (built externally, never passed to MCP)
- signs all three transactions (`preTx`, `actionTx`, `postTx`)
- optionally submits the bundle

### Run locally — no chain required

```bash
INTENTGUARD_CHAIN_ID=11155111 npm run agent-e2e:dry
```

Verifies: MCP connectivity over stdio, nonce assignment (`N`, `N+1`, `N+2`), bundle construction, and transaction signing. The relay is contacted for nonce and block number but no transaction is submitted.

### Full execution (Sepolia)

```bash
INTENTGUARD_CHAIN_ID=11155111 TEST_PRIVATE_KEY=0x... npm run agent-e2e
```

Requires a funded Sepolia wallet. Submits the signed bundle to the relay.

### What this test simulates

| Role | Responsibility |
|------|----------------|
| Upstream builder | constructs the action transaction and assigns nonce N+1 |
| IntentGuard agent | calls `prepare_protected_transaction` |
| Signing agent | signs all three transactions |
| Orchestrator | assembles and submits the bundle |
| MCP server | validates and submits |

This is a full protocol-level test of the IntentGuard execution flow.

---

## Scripts

| Script | Description |
|--------|-------------|
| `npm run build` | Compile to `dist/` |
| `npm run dev` | Run directly from source with `tsx` |
| `npm test` | Run the test suite |
| `npm run typecheck` | TypeScript type check without emit |
| `npm run agent-e2e:dry` | Full agent simulation, dry-run (no submission) |
| `npm run agent-e2e` | Full agent simulation with bundle submission (Sepolia) |

---

## License

MIT