Cloud Security in your IDE (MCP)¶
The LimaCharlie MCP server exposes Cloud Security to any Model Context Protocol client — Claude Code, Cursor, and others — so an AI assistant can read your cloud posture, triage findings, and, for Code Security, scan the working copy on your own machine before anything is pushed.
This page covers the setup and the Code Security tools. Check your client's tool list after connecting. Most of the other Cloud Security tools match a command line interface command.
Setup — Claude Code¶
git clone https://github.com/refractionPOINT/lc-mcp-server
cd lc-mcp-server
go build -o lc-mcp-server ./cmd/server
claude mcp add \
--env LC_OID=YOUR_ORGANIZATION_UUID \
--env LC_API_KEY=YOUR_API_KEY \
--env MCP_MODE=stdio \
--env MCP_PROFILE=cloud_security_readonly \
--transport stdio limacharlie-cloudsec \
-- /absolute/path/to/lc-mcp-server
Build with the Go version required by the server's go.mod (currently 1.27.1).
/mcp in a session lists the server and its tools. The command follows the
Claude Code MCP setup.
Setup — Cursor¶
Add the server to your personal ~/.cursor/mcp.json:
{
"mcpServers": {
"limacharlie-cloudsec": {
"command": "/absolute/path/to/lc-mcp-server",
"args": [],
"env": {
"LC_OID": "<your-organization-id>",
"LC_API_KEY": "<your-api-key>",
"MCP_MODE": "stdio",
"MCP_PROFILE": "cloud_security_readonly",
"LOG_LEVEL": "warn"
}
}
}
}
LOG_LEVEL=warn matters more than it looks: the server logs to stderr, and in stdio mode a chatty
stderr is noise in the client's transport log.
Profiles¶
MCP_PROFILE decides which tools the client is offered. For Cloud Security work:
| Profile | What it exposes |
|---|---|
cloud_security |
Every Cloud Security tool, including the triage writes |
cloud_security_readonly |
CloudSec reads, excluding local scan, ingest, triage and response writes |
all |
The whole platform |
Profiles select callable tools; they do not grant API permissions. Generic
provider, secret and policy setup uses platform_admin tools or the
console/CLI setup. Keep your key's permissions scoped to the
workflow even when changing profiles. The hosted profile endpoint is
https://mcp.limacharlie.io/mcp/cloud_security_readonly when that deployment
supports it; verify the returned tools and any server-wide profile override. An
unrecognized profile endpoint can return 404.
A narrow profile is not just tidiness. An assistant chooses from what it is shown, so a session that
only needs to read posture is both cheaper and safer with cloud_security_readonly.
Entity Pivot tools¶
Six read-only tools resolve an email address, hostname, IP address, sensor ID or
other identifier into User and Host entities, and read their cards, sightings and
activity: cloudsec_entity_pivot, cloudsec_entity_resolve, cloudsec_entity_get,
cloudsec_entity_search, cloudsec_entity_sightings and cloudsec_entity_activity.
Start with cloudsec_entity_pivot; resolve and pivot also take observation_selectors for
leads from adapter events. They are in the cloud_security and
cloud_security_readonly profiles, and also in historical_data,
historical_data_readonly, email_security and email_security_readonly. The
hosted server has all six; a self-hosted server needs v2.5.0 or later. See
Entities for arguments and how to read results.
Permissions¶
Organization-scoped tools require ai_agent.operate by default. Reads need
cloudsec.get. Triage writes and code ingest need
cloudsec.set; dependency AutoFix, remediation run creation and decisions require the separate
cloudsec.respond permission. The whole
surface also requires the organization to be subscribed to the ext-cloud-security extension — a
403 may indicate a missing subscription or permission. Check the error before
changing configuration.
For a first review, ask the assistant to use cloudsec_get_scan_status,
cloudsec_get_overview, then cloudsec_list_findings for high-severity open
findings. Read collection and scanner coverage before interpreting an empty list.
The Code Security tools¶
| Tool | What it does |
|---|---|
cloudsec_code_repos |
The repositories the code lane sees, with scan state and the open-finding rollup |
cloudsec_code_findings |
Findings for one or more repositories, or the cross-filtered facet counts |
cloudsec_code_fixes |
The dependency upgrades that close the most findings, each with a finding id to pass to cloudsec_code_autofix |
cloudsec_code_capabilities |
Per-connection scanning and write capabilities; GitLab/Bitbucket workflow support depends on rollout |
cloudsec_code_scan_local |
Scans a working copy on your machine with the same scanner the hosted lane runs |
cloudsec_code_autofix |
Opens the dependency fix pull request for an SCA finding |
Additional tools read build provenance (cloudsec_code_provenance), finding
evidence (cloudsec_get_finding_evidence_chain), scanner coverage
(cloudsec_get_code_coverage) and change impact (cloudsec_get_code_impact).
Their availability depends on the backend capability; missing or stale evidence
does not prove safety. Provenance pushes require cloudsec.set and contain
metadata, not source code. Remediation run tools require cloudsec.respond.
See the server's product guide
and the actual tool schema for selectors and confirmation requirements.
Before they can return anything¶
Code scanning is opt-in, and two things must be true:
- A source-control provider is connected (a
cloudsec_providerrecord). - A
code_scanningrecord exists in thecloudsec_policyhive, naming the repositories in scope and the engines that run.
Both are hive records — see Get started and Scan policy. An empty answer from a code tool usually means one of those two is missing, not that your code is clean, and the tools say so rather than implying an all-clear.
Reading findings¶
cloudsec_code_findings will not list without at least one repo. That is deliberate: the findings
backend has no "any repository" selector, so dropping the constraint would return your whole
findings worklist — cloud findings included — under a tool named for the code lane. Filtering by
class does not scope it either, because vulnerability, misconfig and malware are shared with
the cloud lane.
The unscoped mode is facets: true, which is honest because the repo facet counts only findings
that have a repository. So the natural order is:
cloudsec_code_findings { "facets": true } → which repositories carry what
cloudsec_code_repos { "has_findings": true } → the same per repository, with scan state
cloudsec_code_findings { "repo": ["owner/name"], "severity": ["CRITICAL", "HIGH"] }
source narrows the same read by producer — hosted for the scan LimaCharlie ran, ingest for a
document your pipeline pushed, other for the source control's own detectors, none for a finding
with no code provenance, or both. It is applied inside the query, so the facet counts describe the
estate rather than the page you happen to be holding.
repo is matched exactly against a key whose owner and name segments are both ASCII
lower-cased, while a finding's code.repo_name is the source-control platform's display casing.
The filter folds what you pass, so a key read straight off a finding now scopes the read rather
than silently matching nothing. A key that is genuinely wrong still returns an empty page, and an
empty page under a single repo filter carries a note saying which case you are in: the key is
right and nothing matched, the key is wrong and here is the real one, or no such repository is in
the inventory.
Scanning your working copy¶
This runs on the machine hosting your local server: the default container path
needs Docker and the limacharlie CLI
on PATH, and it takes minutes rather than seconds. Install or upgrade with
python -m pip install --upgrade limacharlie. The default scanner image requires
registry access. The operator can set LC_CODE_SCANNER_IMAGE or
LC_CODE_SCANNER_BINARY for a compatible authorized image or local executable.
These map to the CLI's --image / --binary; an MCP caller cannot select the
executable. Inspect the server's
local scan guide.
Without ingest, the findings report is not uploaded to LimaCharlie. Image pulls,
scanner dependency/intelligence lookups and optional rule downloads may still use
the network. A local scan is not visible in the hosted estate until ingested.
Because it runs a container locally, it is available only when the server is running in stdio mode. A hosted MCP deployment refuses it.
scanners defaults to sca,iac,licenses; sast and images also run locally.
By default SAST uses scanner-local rules and does not automatically load
organization rules; the delegated local-only CLI has no organization credentials.
The operator can set LC_CODE_SCANNER_RULES_FILE to a compatible
exported code-rule JSON file, forwarding the CLI's --rules-file. An MCP caller
cannot choose the rules file. A scanner with no usable rules reports sast_no_rules (see
Scan locally or in CI). Secret scanning
does not, and asking for it is an error rather than a silent omission: a credential's identity in
this pipeline is a digest keyed by a value only the hosted lane holds, so locally-found secrets
would neither deduplicate against a hosted scan's nor be accepted by the ingest. Use the hosted lane
for secrets.
With ingest: true and a repo, the report is pushed to your organization, where it deduplicates
against the hosted scan by identity — the report format is loss-free, so it lands on exactly the
rows a hosted scan of the same repository would write, and re-pushing an identical report writes
nothing. A pushed report can only close findings it previously reported, never one the hosted
scanner found.
Pass output_path alongside ingest. The report otherwise exists only for the duration of the
scan, so a push that fails — not subscribed, no enabled code_scanning policy selecting the
repository, a quota, a transient error — costs the whole scan again.
cloudsec_code_autofix¶
Opens the pull request that raises a vulnerable dependency to its fixed version, for one finding:
finding_id is required and is the only input that decides anything: the
backend resolves it against the dependency rows its own scan produced and raises
that package to that advisory's fixed version, so there is no way to name a
package or a version. repo and provider are optional search hints.
For GitHub it needs Contents: Read and write and Pull requests: Read and write
App permissions. GitLab.com/Bitbucket use separately configured write credentials
when their workflow is available. cloudsec_code_capabilities reports configured
capabilities; a tenant policy cannot enable an unavailable workflow.
The tool creates a governed open_fix_pr remediation run and returns its
run_id and state. It requires cloudsec.respond; the caller is recorded as
requester and approver. Follow the run with cloudsec_get_remediation before
reporting an outcome. The clone, edit and PR happen asynchronously; accepted
does not mean a PR exists or the vulnerability is fixed. Repeating a request
before the PR opens can return the same run with replayed: true.
A disabled workflow is refused immediately. Later failures, such as missing
write permissions, policy scope, unsupported edits, an existing PR or exhausted
budgets, appear in the run's failure_reason and operational events. change
records the PR; verified means the fix was observed in every in-scope
deployment. Missing deployment evidence cannot establish a verified fix.
See AutoFix pull requests for the setup and the lockfile behavior that decides whether the pull request is complete on its own.
Local IaC attribution¶
The server provides cloudsec_code_iac_map_extract in the full CloudSec profile
for local STDIO sessions. The operator must explicitly set LC_IAC_MAP_EXTRACTOR
to an installed extractor's path; there is no implicit executable selection.
The tool reads a local Terraform/OpenTofu show-JSON file and returns sanitized
identity/allowlisted desired metadata. Raw plans, state, source and credentials
are not uploaded. Review the sanitized document before a separate
cloudsec_code_iac_map_push call.
Push and receipt status both require cloudsec.set, so
cloudsec_code_iac_map_status is excluded from the read-only profile despite
being a read. A processing receipt is not published evidence; check status
until published, or resubmit the same document only for a retryable receipt.
Publication is not proof of deployment or remediation. See
IaC source mapping
and the tool schema for exact receipt fields and capability prerequisites.
See also¶
- Code Security — the product these tools read
- Command Line Interface — the same surface, without an assistant
- Entities — resolving identifiers to Users and Hosts