# Connect Claude Code to Trust Infrastructure

These steps are for a Claude Code agent. The person you work with has a Trust Infrastructure API key. Follow
the steps in order to connect Claude Code to Trust Infrastructure's MCP server on **dev**
(`https://api.dev.trustinfrastructure.com`).

**Treat the key as a secret.** Never print it, repeat it back, paste it into a chat, or write it into a file
that gets committed. Read it from the `TIP_API_KEY` environment variable.

## 1. Check that the key belongs to this environment

A key works only on the environment that issued it. Its first characters say which one:

| Key starts with | Environment | MCP server |
|---|---|---|
| `tip_dev_` | dev | `https://api.dev.trustinfrastructure.com/api/mcp/<ecosystem>` |
| `tip_stg_` | staging | `https://api.staging.trustinfrastructure.com/api/mcp/<ecosystem>` |
| `tip_`, then the hex directly | production | `https://api.trustinfrastructure.com/api/mcp/<ecosystem>` |

This page is for keys that start with `tip_dev_`. If the person's key starts differently, use the MCP
server from its row; every other step is the same. Dev and staging are for testing. Production serves live
applications.

`<ecosystem>` is the slug of the ecosystem the key belongs to, for example `real-estate`. The person
receives it with the key; ask them if you don't have it.

## 2. Add the MCP server

Run this where `TIP_API_KEY` is set:

```bash
claude mcp add --transport http trust-infrastructure \
  https://api.dev.trustinfrastructure.com/api/mcp/<ecosystem> \
  --header "Authorization: Bearer $TIP_API_KEY"
```

If `TIP_API_KEY` is not set in your environment, do not ask for the key. Ask the person to run the command in
their own terminal instead.

- **Scope.** The default scope is this project, for this person only. Add `--scope user` to make the server
  available in every project.
- **Never commit the key.** `--scope project` writes `.mcp.json`, which is usually committed. For a shared
  `.mcp.json`, write the header as `"Authorization": "Bearer ${TIP_API_KEY}"`, which Claude Code expands from
  the environment, and have each person set `TIP_API_KEY` themselves.
- **Restart.** Start a new Claude Code session so the server loads.

## 3. Check the connection

1. Run `claude mcp list`, or `/mcp` inside a session. `trust-infrastructure` should show as connected.
2. Call the `tip-key-introspect` tool. It describes the key making the call: its family (consumer, author or
   admin), its ecosystem and its roles. It calls no data source, and it returns no secret.

To check without Claude Code:

```bash
curl -sS -X POST https://api.dev.trustinfrastructure.com/api/mcp/<ecosystem> \
  -H "Authorization: Bearer $TIP_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
```

The answer arrives as a server-sent event (`event: message`, then `data: {...}`), not as plain JSON.

## 4. Find skills, and check the price before calling one

- **`portal-browse-skills`** lists the skills this key can see. **`discover-skills`** filters them by category,
  domain or query. **`find-skills-for-concept`** finds them by data dictionary concept. Each skill is also a
  tool of its own in the tool list.
- **A priced skill bills the moment it runs, and there is no preview.** Before you call one, get its price
  with **`portal-quote-skill-price`** and ask the person to confirm. A quote is free: it calls nothing and
  bills nothing.
- **Pricing is one of `priced`, `free` or `unpriced`.** Every skill record carries this value. A missing amount
  does not mean the skill is free.
- **Report a wrong or empty answer** with **`submit-invocation-feedback`**, giving the call's
  `invocation_id`.

## 5. Optional arguments on every skill tool

Every skill tool accepts these optional run-control arguments beside the skill's own inputs. Tool schemas list
them with type and bounds only; this is what they mean. Send each as the type listed. On `tip-invoke-skill`, pass
them inside `arguments`.

- **`version`** (string). Pins the version of the skill to run, for example `1.0.0`. Omit it to run the latest
  published version. A version that does not resolve is refused as `skill_not_found` before anything runs.
- **`environment`** (string). Selects a named environment of the data source the skill calls, for example
  `production` or `testing`. Omit it to use the source's default; most calls never pass it. A name the source does
  not have fails the call. Only a skill that calls one data source directly uses it; other skills ignore it.
- **`correlationId`** (string, at most 200 characters). Your own id for this run, 1 to 200 characters with no
  control characters. It is echoed as `_meta.correlationId` exactly as stored: an id outside that rule is stored as
  null, never truncated. Read the run back with `tip-run-get` by this id. It never changes the answer or the price.
- **`maxPrice`** (number, at least 0). The most this call may bill, in US dollars: send the price your quote was
  built on. If the price in effect is higher, the call is refused before anything runs, at $0, with
  `max_price_exceeded` and the current price, so ask the person again. A value that is not a number of 0 or more is
  refused as `input_invalid`. A retry under the `idempotencyKey` of a call that billed gets that answer again at $0
  and is not checked again.
- **`idempotencyKey`** (string, at most 200 characters). Send the same key, 1 to 200 characters with no control
  characters, when you retry a call to the same skill, for example after a timeout. If the first call billed, you
  get its answer again at $0, marked `replayed: true`, and `replayOf` gives the first run's `invocationId` and the
  `invocationCost` it billed. If it failed or billed nothing, the retry runs as a new call. If it is still running,
  you get `still_running`; retry with the same key after its `retryAfterSeconds`. The same key with a different
  request to that skill is refused as `idempotency_key_reused`; a new `correlationId` alone is not a different
  request. An answer is kept for 15 minutes; after that the key runs a new call at the current price. Use a new key
  for each new request.

## If it fails

| What you see | What it means | What to do |
|---|---|---|
| HTTP 401, "API key does not match this environment" | The key comes from another environment | Use the MCP server from the key's row in step 1 |
| HTTP 401, "missing, invalid, or revoked API key" | The key is mistyped or revoked, or the header is missing | Check that the header reads `Authorization: Bearer <key>` with no extra quotes or spaces; if it does, ask the person for a new key |
| HTTP 406, "Not Acceptable" | The `Accept` header is missing | Send `Accept: application/json, text/event-stream`; Claude Code sends it by itself |
| Connected, but an expected skill is missing | The key's role does not see it, or it is not published | Run `tip-key-introspect` and give the result to the person's ecosystem operator |

## Browse in a web page

The person can log in at https://developer.dev.trustinfrastructure.com with the same key to browse skills and the data dictionary and to try
requests. A key logs in only on its own environment's portal.
