# MCPIP — agent setup

> You are an AI coding agent. A human asked you to set up **MCPIP** for their
> company and to build their skill catalog. Follow this document top to bottom.
> Ask the human for anything you need (gateway URL, their systems, their teams).

**What MCPIP is:** a self-hosted, zero-trust authorization gateway that sits
between an AI agent's tool calls and the systems that execute them. The agent
only ever names an *opaque alias*; MCPIP resolves it to the real target,
authorizes the call deterministically **before** it runs (fail-closed, opaque),
and seals every verdict into a signed write-before-execute audit log. Identity is
a verified JWT; a role authorizes nothing; high-risk actions require a
payload-bound one-time PIN.

There are two parts: **A. Connect an agent** and **B. Build the catalog.**

---

## A. Connect an agent (verify the gateway works)

MCPIP is stood up from its repo (there is no vendor-hosted gateway). If the human
does not have one running, help them start a local sandbox from a checkout:

```bash
python3.12 -m venv .venv
.venv/bin/pip install -r requirements.txt
redis-server --port 63790 --daemonize yes --appendonly yes --appendfsync always
MCPIP_SANDBOX_MODE=true MCPIP_REDIS_URL=redis://localhost:63790/0 \
  .venv/bin/python -m uvicorn app.main:app --port 8080 &
curl -s http://localhost:8080/healthz   # {"status":"live","version":"3.0.0"}
curl -s http://localhost:8080/readyz    # {"redis":"up"}
```

Then connect an agent with the `mcpip` CLI (from the checkout: `pip install ./sdk/python`):

```bash
mcpip login --gateway http://localhost:8080 --sandbox --context sbx
mcpip --context sbx sandbox dev-token --tenant <tenant> --agent <agent-id> --compartment <team-uuid>
mcpip --context sbx whoami
mcpip --context sbx catalog        # shows only the skills this agent may see
mcpip --context sbx authorize <alias> --arg key=value   # ALLOW, or an opaque deny
```

Or drive the raw edge directly — the same pipeline authorizes all of it:

```bash
# REST: any provider dialect in, one decision out
curl -s http://localhost:8080/v1/authorize -H "authorization: Bearer $TOKEN" \
  -H 'content-type: application/json' -d '{
  "source_format":"raw_mcp",
  "tool_call":{"tool":"<alias>","arguments":{}}}'
# → 200 ExecutionReceipt (allow) | 202 StagedChallenge (needs PIN) | 403 {error, correlation_id}
```

A 202 means step-up: re-POST the **identical** tool_call plus `pin` + `challenge_id`.
In sandbox, peek the code at `GET /v1/authenticator/{challenge_id}`.

**Production** swaps the sandbox dev-token for the key ceremony: run
`scripts/provision_gateway_keys.py`, then `scripts/mint_principal.py` against your
own IdP — the gateway never mints identities outside sandbox. Point agents at the
gateway URL with an `Authorization: Bearer <jwt>` your IdP signs.

---

## B. Build this company's skill catalog

Every company's catalog is different. Interview the human (or read the systems
they paste), then emit a catalog tailored to **their** software and teams. Do not
emit a generic list.

### The skill model

A skill maps an **opaque alias** (what the agent sees) to a **hidden target**
(what it must not see). Fields (grounded in `_RegisterSkillBody`):

| field | values | meaning |
|---|---|---|
| `alias` | `skill_{platform}_{tool}`, lower snake_case, ≤256 | agent-facing name. Access is a FIELD, never a `_read`/`_write` suffix. |
| `target` | string ≤512 | the real endpoint/system the agent never sees (e.g. `rest.stripe.refunds.create`). |
| `service` | string ≤64 (optional) | human label for the console (e.g. "Stripe refunds"). Display only. |
| `access` | `read` \| `write` (optional) | the console permission model. Display only. |
| `risk_tier` | `auto` \| `pin_required` | **the enforcement gate.** `auto` runs immediately; `pin_required` demands a human-approved payload-bound PIN before running. |
| `classification` | `unclassified` \| `restricted` | display/annotation. A `restricted` skill MUST be `pin_required`. |

Transport is always `cloud_rest`; registration is **additive-only** (you can add,
never shadow an existing alias).

### The rules

- **Reads → `access: read`, `risk_tier: auto`.** (balances, lookups, list/get)
- **Mutations OR sensitive data-egress → `access: write`, `risk_tier: pin_required`.**
  (payments, refunds, prod teardown, sending email/data, writing records)
- **Least privilege:** one alias per real capability; never a broad passthrough.
- **Opaque aliases:** the `target` is hidden — pick an alias that reveals nothing
  about the real endpoint.
- **Team separation:** put a team's skills in that team's `compartment` (a UUID)
  so only that team's agents can even see them.

### The outputs — produce BOTH

**Output A — register requests** (one per skill; needs a `CAP_DIRECTORY_ADMIN` token):

```bash
curl -s $GATEWAY/v1/admin/skills/register -H "authorization: Bearer $ADMIN_TOKEN" \
  -H 'content-type: application/json' -d '{
  "alias":"skill_stripe_refund",
  "target":"rest.stripe.refunds.create",
  "service":"Stripe refunds",
  "access":"write",
  "risk_tier":"pin_required",
  "classification":"restricted"}'
# → {"registered":"skill_stripe_refund"}
```

**Output B — the catalog as JSON** (for review / apply / version control):

```json
[
  {"alias":"skill_stripe_balance","target":"rest.stripe.balance.get","service":"Stripe balance","access":"read","risk_tier":"auto","team":"finance"},
  {"alias":"skill_stripe_refund","target":"rest.stripe.refunds.create","service":"Stripe refunds","access":"write","risk_tier":"pin_required","team":"finance"},
  {"alias":"skill_github_pr","target":"rest.github.pulls.get","service":"GitHub PRs","access":"read","risk_tier":"auto","team":"engineering"},
  {"alias":"skill_github_merge","target":"rest.github.pulls.merge","service":"GitHub merge","access":"write","risk_tier":"pin_required","team":"engineering"},
  {"alias":"skill_pg_query","target":"rest.pg.readonly.query","service":"Postgres (read)","access":"read","risk_tier":"auto","team":"engineering"},
  {"alias":"skill_aws_s3","target":"rest.aws.s3.get","service":"AWS S3","access":"read","risk_tier":"auto","team":"engineering"}
]
```

*(Worked example above: a company on Stripe + GitHub + Postgres + AWS S3 with a
finance team and an engineering team — reads are `auto`, money-movement and merges
are `pin_required`, and each team's skills sit in its own compartment.)*

### Interview checklist

Ask the human for: their SaaS + internal APIs + cloud services + databases; which
team uses each; and for every tool whether the agent needs to **read** or to
**change** things. Then apply the rules and produce Outputs A and B.

---

## More

- Docs & full connect guide: https://mcpip.ai/docs
- Security model: https://mcpip.ai/security
- Pricing (per governed agent identity): https://mcpip.ai/pricing
- Source, SDKs, licensing: https://mcpip.ai/download
