Skip to content

CYBO Attest with Claude Code

Quick start

One command, one sign in, and Attest is available in every Claude Code session. You need an Attest account first; create one at attest.ulapcybo.app if you do not have one.

Already added Attest in Claude.ai? Skip the add step. Connectors you add under Customize > Connectors in Claude.ai load automatically in Claude Code when you sign in with the same account. Run claude mcp list and you should see it.

Otherwise, from your terminal (not inside a claude session):

claude mcp add --scope user --transport http cybo_attest https://attest.ulapcybo.app/mcp

Then:

  1. Run claude mcp list. Attest shows ! Needs authentication, which is expected.
  2. Start a session with claude, type /mcp, select cybo_attest, and choose Authenticate.
  3. Your browser opens to the Attest sign in page. Log in, approve the consent screen, and return to the terminal. The status changes to connected.
  4. Ask: List my Attest applications

Claude Code asks you to approve the first tool call from Attest. Approve it, and the tool call in the output is labeled with the server name so you can see the answer came from Attest.

Scopes and sharing

Where you register Attest decides who sees it and where. The scope is fixed when you add the server; to change it, remove and re add.

Scope Command flag Saved in Who gets it
user --scope user ~/.claude.json, top level mcpServers You, in every project (recommended for individuals)
project --scope project .mcp.json in the repo root Everyone who clones the repo
local default, no flag ~/.claude.json, under this project You, this project only

Share Attest with your whole team through the repo. Add it at project scope once:

claude mcp add --scope project --transport http cybo_attest https://attest.ulapcybo.app/mcp

That writes .mcp.json at the repo root. Commit it. Each teammate who clones the repo sees a one time prompt to approve the server, then signs in with their own Attest account through /mcp. Nobody shares credentials; the file only carries the URL.

If you prefer to write it by hand, .mcp.json looks like this:

{
  "mcpServers": {
    "cybo_attest": {
      "type": "http",
      "url": "https://attest.ulapcybo.app/mcp"
    }
  }
}

Claude Code reads .mcp.json at session start, so restart the session after editing it.

Cloud sessions. Claude Code on the web and in cloud sessions loads .mcp.json from the repository, so a committed project scope entry makes Attest available there too. The sign in happens once per environment.

Working in a repo

This is where Claude Code beats the chat clients: it can read Attest findings and edit the code in the same turn. A few prompts that work well from inside a project directory:

Close the loop on findings

  • Pull the open critical findings for this app from Attest and fix the ones in this repo. Show me the diff before committing.
  • Attest flagged finding [id]. Explain it, find where it applies in this codebase, and patch it.
  • Get the Attest fix plan for this app and work through it top to bottom, one commit per fix.

Dockerfiles and base images

  • Ask Attest for a fixed Dockerfile for this app, compare it with ours, apply the changes here, and apply it in Attest too.
  • Which approved base image tags does Attest list for node? Update our Dockerfile to the newest one.

Scan, verify, repeat

  • After your fixes, run the tests, commit, and push. Then have Attest scan the latest code, follow the build and the scans, and confirm the findings you fixed are gone.
  • Re run the scans on the current build of this app and tell me when they finish.

The first is the rescan: Attest pulls the newest commits into its copy, rebuilds the container, and runs the scans, and the new build is what the reviewer sees. The second re runs the scans on the build Attest already has, for when a justification or configuration changed and the code did not.

Justifications from the code

  • Finding [id] is in a dev only dependency. Confirm that from package.json, then draft and submit an Attest justification that cites the file.

Posture and gates

  • What gates is this app failing in Attest, and which of them can be fixed in code? Fix those.

Two habits that help:

  • Put the Attest application name in the project's CLAUDE.md (for example Attest application: payments-api) so you never have to repeat it.
  • Say "use Attest" the first time in a session if Claude reaches for another tool; after that it keeps using the server.

Write actions (starting a scan, applying a Dockerfile, submitting a justification, requesting authorization) prompt for approval each time unless you pre approve them, covered under Automation.

Automation

Claude Code runs non interactively with -p, which lets you script Attest checks, run them in CI, or schedule them.

Pre approve the tools you want to run unattended. Permission rules name MCP tools as mcp__<server>__<tool>; mcp__cybo_attest alone allows every Attest tool. A read only posture check:

claude -p "Give me the security posture and open critical findings for the payments-api application in Attest, as a short report" \
  --allowedTools "mcp__cybo_attest__get_security_posture,mcp__cybo_attest__list_findings,mcp__cybo_attest__explain_finding" \
  --output-format json | jq -r '.result'

A scan and report step:

claude -p "Scan the latest code of payments-api in Attest, wait for the build and scans to complete, then list the critical findings on the new scan" \
  --allowedTools "mcp__cybo_attest__sync_application,mcp__cybo_attest__get_application_progress,mcp__cybo_attest__get_scan,mcp__cybo_attest__list_scans,mcp__cybo_attest__list_findings" \
  --permission-prompts none \
  --output-format json

--permission-prompts none tells Claude Code nobody will answer prompts, so any tool you did not allow is denied cleanly instead of hanging the run. Add --json-schema if you want the result in a fixed shape for a pipeline to consume.

Sign in happens before automation, not during it. Attest uses OAuth, which needs a browser the first time. On a machine or runner that will run unattended jobs, run claude, /mcp, Authenticate once; the token is cached in that user's Claude Code config and refreshed automatically. For an ephemeral CI runner that cannot do a browser sign in, ask the Attest team whether a service token is available for your organization and pass it with --mcp-config:

claude --bare -p "..." --mcp-config '{"mcpServers":{"cybo_attest":{"type":"http","url":"https://attest.ulapcybo.app/mcp","headers":{"Authorization":"Bearer $ATTEST_TOKEN"}}}}'

Where to run it

  • GitHub Actions or GitLab CI: add the -p command as a job step after your build. Use the read only form on pull requests and the scan form on merges to main.
  • Scheduled: inside a session, /loop can rerun a prompt on an interval (for example a daily posture summary), and the Claude Code web app can run it as a routine on a schedule with no machine of yours left on.
  • Scripts: pipe the JSON into whatever you already use for alerts; a non zero exit code from claude -p means the run itself failed, not that findings were present.

Keep write tools (sync_application, start_scan, use_fixed_dockerfile, propose_justification, apply_justifications, request_authorization, add_github_repository, remove_application) out of --allowedTools unless the job is specifically meant to perform that action.

Managing the connection

Task From your shell Inside a session
See status of every server claude mcp list /mcp
Inspect Attest (scope, URL, tools) claude mcp get cybo_attest /mcp, select cybo_attest
Sign in again, or reconnect /mcp, select cybo_attest, Authenticate or Reconnect
Sign out of Attest /mcp, select cybo_attest, Clear authentication
Turn it off without removing it /mcp, select cybo_attest, Disable
Remove it claude mcp remove cybo_attest (add --scope if it exists in more than one)
Approve a project scope server you skipped claude mcp reset-project-choices, then start a session /mcp

Tool permissions. Claude Code asks before the first call to each Attest tool in a session. To stop being asked for the read tools, add a permission rule to .claude/settings.json in the project (shared) or ~/.claude/settings.json (just you):

{
  "permissions": {
    "allow": [
      "mcp__cybo_attest__list_applications",
      "mcp__cybo_attest__get_security_posture",
      "mcp__cybo_attest__list_findings",
      "mcp__cybo_attest__get_finding",
      "mcp__cybo_attest__explain_finding",
      "mcp__cybo_attest__plan_fixes"
    ]
  }
}

Leave the write tools out so they still prompt. /permissions inside a session edits the same rules interactively.

Context cost. Every connected server loads its tool list into the session context. Attest has a sizeable tool set, so if you only use it occasionally, disable it with /mcp in sessions where you do not need it rather than removing it.

Troubleshooting

Start with claude mcp list (or /mcp in a session) and match the status.

Status or symptom Cause Fix
/mcp says No MCP servers configured You added Attest at local scope in a different project, or edited the wrong file Re add with --scope user, or add it from the project you are in. Claude Code only reads ~/.claude.json and <project>/.mcp.json
! Needs authentication Normal before first sign in /mcp, select cybo_attest, Authenticate
Browser shows invalid scopes or unknown client at sign in The Attest authorization server rejected the client Claude Code registered Report it to the Attest team with the exact text; it is a server side setting, not your config
Sign in page opens but the terminal never updates Callback blocked, or you closed the tab early /mcp, Authenticate again; keep the tab open until the terminal shows connected. If the browser does not open, copy the URL from the terminal
✘ Failed to connect URL typo or network block claude mcp get cybo_attest and compare the URL to https://attest.ulapcybo.app/mcp; curl -I https://attest.ulapcybo.app/mcp should return 401 or 405, which means the server is up
MCP endpoint not found The URL path is wrong Remove and re add with the exact URL including /mcp
Connected, but Claude never uses Attest It picked another tool Say "use Attest" or name the server in the prompt
Tool calls return 401 or 403 Token expired or your Attest role lacks access /mcp, Clear authentication, then Authenticate; check your role in Attest
⏸ Pending approval A project scope .mcp.json you have not approved yet Start claude in the project and approve, or claude mcp reset-project-choices if you declined earlier
Server already exists Same name at the same scope claude mcp remove cybo_attest --scope <scope> then re add

If none of these match, run claude mcp get cybo_attest and send its output plus the error text to Ulap support.