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):
Then:
- Run
claude mcp list. Attest shows! Needs authentication, which is expected. - Start a session with
claude, type/mcp, select cybo_attest, and choose Authenticate. - 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.
- 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:
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:
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 exampleAttest 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
-pcommand 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,
/loopcan 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 -pmeans 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.