# Claude Code MCP server setup and continuity test

Connect Claude Code to Handover's remote HTTP MCP server, verify the
authenticated boundary, and prove a fresh Claude Code agent can retrieve and
continue exact source context.

Canonical guide:
https://handover.sh/guides/claude-code-mcp-server-setup

Handover endpoint:
https://handover.sh/api/mcp?profile=core

## What a passing setup proves

1. Claude Code reaches the remote Streamable HTTP server.
2. A protected call resolves the expected named service identity.
3. Search and reads stay inside that identity's authorized boundary.
4. An approved private handoff can be created and read back exactly.
5. A separately authenticated successor can retrieve and continue it.
6. Missing, denied, read-only, stale, and revoked paths remain constrained.

`Added`, `Connected`, a visible server, or a tool list proves only an earlier
checkpoint.

## 1. Create two named service identities

Create two Handover service agents with the minimum workspace grants and
scopes required for the test:

```text
Claude publisher: claude-code-publisher
Claude successor: claude-code-successor
```

Use separate credentials. Never paste them into a prompt, repository,
handoff, screenshot, or this file.

## 2. Add Handover at user scope

This command shape was validated with
`@anthropic-ai/claude-code@2.1.221`.

```bash
read -s HANDOVER_TOKEN
export HANDOVER_TOKEN

claude mcp add --transport http --scope user \
  handover "https://handover.sh/api/mcp?profile=core" \
  --header "Authorization: Bearer ${HANDOVER_TOKEN}"

unset HANDOVER_TOKEN
chmod 600 ~/.claude.json
claude mcp list
```

Keep the server name and URL before `--header`. In the current CLI, placing
the variadic header option first can consume the server name and fail with:

```text
error: missing required argument 'name'
```

The resulting user configuration contains:

```json
{
  "mcpServers": {
    "handover": {
      "type": "http",
      "url": "https://handover.sh/api/mcp?profile=core",
      "headers": {
        "Authorization": "Bearer <SERVICE_AGENT_TOKEN>"
      }
    }
  }
}
```

The expanded header value is stored in `~/.claude.json`. Keep that file
private. In the tested CLI version, `claude mcp get handover` prints the saved
header value. Do not paste that output into chat, issues, logs, screenshots,
or a handoff.

## 3. Inspect connection state without exposing the header

From the shell:

```bash
claude mcp list
```

Inside Claude Code:

```text
/mcp
```

`claude mcp add` reporting `Added` means the configuration was written.
`claude mcp list` performs a health check. Do not treat either as proof of the
authenticated identity or Handover boundary.

## 4. Understand service credentials and OAuth

Claude Code supports OAuth discovery, browser authorization, refresh,
`claude mcp login`, and `claude mcp logout` for compatible HTTP servers.

Handover now exposes first-party protected-resource and authorization-server
discovery, dynamic client registration, and PKCE. Interactive Claude Code
connections can therefore use browser sign-in and preserve the approving
person's identity.

When `headers.Authorization` is configured and rejected, Claude Code does not
fall back to OAuth. Rotate or replace the Handover service credential instead.

## 5. Verify identity before reading

Ask Claude Code:

```text
Call Handover's identity tool. Show the server-resolved principal, company,
workspace, role, and scopes. Stop if any value differs from the expected
claude-code-publisher identity.
```

Expected operation:

```text
handover.whoami
```

Never accept identity or workspace values supplied only in prompt text.

## 6. Verify protected reads

Expected operations:

```text
handover.search
handover.get
handover.read_artifact
```

Search for a known private record, open its canonical revision, and read one
exact source artifact. Pass only when the record is in the expected workspace,
the artifact matches the canonical source, and a denied record remains hidden.

## 7. Create and read back one private handover

Ask before the first write. Create a disposable private handoff with a unique
marker:

```text
CLAUDE-CODE-MCP-SETUP-2026-08-04-01
```

Attach:

```markdown
# Claude Code MCP verification

- Marker: CLAUDE-CODE-MCP-SETUP-2026-08-04-01
- Objective: prove authenticated publish and read-back
- Constraint: private to the test workspace
- Next action: retrieve from claude-code-successor
```

Expected operations:

```text
handover.create
handover.get
handover.read_artifact
```

Pass only when the server attributes the revision to
`claude-code-publisher`, visibility remains private, and the exact artifact is
retrievable from the canonical revision.

## 8. Prove successor continuity

Use a fresh Claude Code profile or installation with the
`claude-code-successor` credential. Give it only the stable link or marker,
not the publisher's conversation.

Ask:

```text
Verify your identity, find this handoff, read the current source artifact,
state the exact marker, and continue the bounded next action using the current
expected revision. Read the result back.
```

Expected operations:

```text
handover.whoami
handover.search
handover.get
handover.read_artifact
handover.annotations
handover.continue
handover.get
```

Pass only when the server reports the successor identity, the exact artifact
is retrieved, the marker comes from that artifact, the write uses
`expectedRevisionId`, and the new revision records the successor as author.

## 9. Run negative tests

### Missing credential

Remove the Authorization header temporarily. A protected call must return
`401`; the server must not guess or reuse another actor.

### Rejected static header

Use a dedicated invalid test credential. Claude Code must report a failed
connection and must not fall back to browser OAuth while
`headers.Authorization` remains configured.

### Pending project approval

For a disposable project-scoped `.mcp.json`, confirm Claude Code reports
`Pending approval` until a user reviews the repository configuration.

### Denied workspace

An identity without the test workspace grant must not discover titles,
summaries, artifacts, annotations, or counts.

### Read-only scope

A read-only identity may inspect granted context but must not create, continue,
annotate, assign, archive, or delete.

### Stale revision

Continue with an obsolete `expectedRevisionId`. The server must reject the
write until the agent reads and reconciles the current revision.

### Revoked credential

Revoke a dedicated test agent and call `handover.whoami` again. The old
credential must fail even if Claude Code still has a local server entry.

## 10. Diagnose explicit states

```text
Added, then Failed to connect
  Verify the full URL and named service credential.

HTTP 401 with Authorization
  Rotate the service credential. Static-header rejection disables OAuth fallback.

Pending approval
  Review the project .mcp.json interactively before enabling it.

Server silently missing
  Inspect managed-mcp.json, allowedMcpServers, and deniedMcpServers.

Connected but tools unavailable
  Inspect /mcp, the current identity, workspace grants, scopes, and tool search.

Search returns nothing
  Verify whoami and search a known unique marker.

Write conflict
  Read the current revision, reconcile, and retry only with approval.
```

## 11. Remove local and remote access

Remove the local user-scoped entry:

```bash
claude mcp remove handover --scope user
```

Then revoke the named service agent in Handover and require the old credential
to fail against `handover.whoami`.

Removing only the local entry leaves the remote credential valid. Revoking
only the credential leaves stale local configuration. Complete offboarding
requires both.

## 12. Record the result

```markdown
# Claude Code MCP setup result

- Claude Code version:
- Configuration scope: user | project
- Handover endpoint:
- Publisher identity:
- Successor identity:
- Workspace:
- Publisher revision:
- Successor revision:
- Exact artifact read-back passed:
- Missing credential passed:
- Rejected static header passed:
- Pending project approval passed:
- Denied workspace passed:
- Read-only scope passed:
- Stale revision passed:
- Revocation passed:
- Local removal passed:
- Overall result: PASS | FAIL
- First failing checkpoint:
- Evidence:
```

Mark the workflow `PASS` only after the second authenticated identity retrieves
the exact source artifact and creates a verified successor revision.
