# FirstKey

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/FirstKeyHQ/firstkey-mcp  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/firstkey

## Description
FirstKey MCP: agent wallets, free cycles faucet, and one-command site deploys on ICP.

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "firstkey": {
    "command": "npx",
    "args": ["-y","firstkey"]
  }
}
```

## Documentation & README

# FirstKey MCP Server

An MCP (Model Context Protocol) server running as a canister on the Internet Computer.
One integration point that every MCP-compatible agent framework consumes natively:
LangChain/LangGraph, CrewAI, AutoGen, Vercel AI SDK, OpenAI Agents SDK, Google ADK,
Claude Desktop, Cursor, and more.

**Endpoint:** `POST https://mcp.firstkey.io/mcp` (JSON-RPC 2.0, Streamable HTTP)

Plain JSON responses, stateless (no session ids). CORS enabled (`*`).

## Tools

| Tool | What it does |
|---|---|
| `create_wallet` | Generates a fresh Ed25519 wallet (principal + PKCS#8 PEM private key). The key is returned once and never stored. |
| `claim_faucet_grant` | Claims the one-time free 1T cycles grant from the FirstKey faucet for an agent principal. |
| `deploy_site` | Creates a site canister, installs the static host, uploads files, returns the live `https://<canister>.icp.net` URL. The agent becomes a controller of its own site. One free deploy per agent. |
| `deploy_upload_chunk` | Chunked upload of large files to an already-deployed agent site. |
| `check_cycles` | Reads a principal's cycles balance on the cycles ledger. |
| `get_fuel_link` | Returns the FirstKey Fuel card-payment link to refuel an agent (`https://firstkey.io/fuel?for=<principal>`). |
| `get_swap_quote` | Live read-only ICPSwap quote (on-chain factory→pool): pay token/amount → receive amount + implied price. Symbols or ledger principals; no tokens move. |

## Quick test

```bash
URL=https://mcp.firstkey.io/mcp
# initialize
curl -s $URL -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}' | head -c 600
# list tools
curl -s $URL -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | python3 -c "import json,sys; [print(t['name']) for t in json.load(sys.stdin)['result']['tools']]"
# create a wallet
curl -s $URL -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"create_wallet","arguments":{}}}'
```

## Architecture

- `http_request` (query): serves `initialize`, `tools/list`, `ping`, CORS preflight,
  `/.well-known/ic-domains`, and a landing page.
- `tools/call` upgrades to `http_request_update` (update context) because it makes
  inter-canister calls: `raw_rand` (wallet), the faucet's `claim_for` (grants),
  the cycles ledger (balances), and the management canister
  (`create_canister_with_extra_cycles` / `install_code` / `update_settings` for deploys).
- The static-site host WASM (`firstkey-static-host`) is embedded via `include_bytes!`
  and installed into every deployed site canister.
- Deploy pool: the canister's own cycles balance. One free deploy per agent principal
  (tracked in stable memory); when the pool can't cover a deploy the tool returns
  the Fuel link instead.

## Build & deploy

```bash
export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
cd ~/workspace/firstkey-static-host && cargo build --target wasm32-unknown-unknown --release
cd ~/workspace/firstkey-mcp && cargo build --target wasm32-unknown-unknown --release

# create (needs ~5.5T cycles on the strider identity's cycles ledger)
icp canister create -n ic --detached --cycles "5.5t" \
  --controller fhvid-ondyx-ziq2v-udsry-cfgki-okcur-gcryu-2wwai-b63ku-ptgkk-yqe \
  --controller o5joj-543gr-ibdnq-q6f26-sbevy-iorvz-lqo2i-ocyr7-crp2u-sggj7-cae \
  --identity strider -q
# install
icp canister install <CANISTER> \
  --wasm ~/workspace/firstkey-mcp/target/wasm32-unknown-unknown/release/firstkey_mcp.wasm \
  -n ic --identity ops -y
# authorize on the faucet
icp canister call --network ic 3l667-lyaaa-aaaam-ajkqa-cai set_mcp_canister \
  --candid ~/workspace/firstkey-faucet/faucet.did --identity ops \
  '(principal "<MCP_CANISTER>")'
```

## Custom domain (`mcp.firstkey.io`)

DNS records needed at Porkbun (see `DNS.md`):

1. `CNAME mcp.firstkey.io` → `mcp.firstkey.io.icp1.io`
2. `TXT _canister-id.mcp.firstkey.io` → `<canister-id>`
3. `CNAME _acme-challenge.mcp.firstkey.io` → `_acme-challenge.mcp.firstkey.io.icp2.io`

Then validate + register:

```bash
curl 'https://icp.net/custom-domains/v1/mcp.firstkey.io/validate'
curl -X POST 'https://icp.net/custom-domains/v1/mcp.firstkey.io'
curl 'https://icp.net/custom-domains/v1/mcp.firstkey.io'  # poll until "registered"
```

The canister already serves `/.well-known/ic-domains`.

## Registry publishing

- **Official MCP registry** (`registry.modelcontextprotocol.io`): see `registry/server.json`
  (draft). Publish via GitHub OIDC from the repo's CI.
- **Smithery** (`smithery.ai/new`): submit the public HTTPS URL once `mcp.firstkey.io`
  is live.

## Faucet counterpart

`claim_for(agent)` lives on the faucet canister (`3l667-lyaaa-aaaam-ajkqa-cai`,
source `~/workspace/firstkey-faucet/`). It enforces the once-per-principal rule
against the *agent* principal and performs the standard 1T ledger grant. Only the
principal set via `set_mcp_canister` (controller-only) may call it.

