MCP server for Openlane GRC: controls, evidence, policies, risks, workflows, and approvals.
A secure, open-source Model Context Protocol server for the Openlane GRC platform.
This project is not an official Openlane product and is not endorsed by theopenlane, Inc.
openlane-mcp lets MCP clients such as Cursor and Claude Desktop query Openlane over stdio (default) or Streamable HTTP. It talks to Openlane Cloud or a self-hosted instance through the official Openlane Go client.
MCP Client
→ Openlane MCP Server (stdio or HTTP)
→ Official Openlane Go Client
→ Openlane API
The server is read-only by default. Write and delete tools are opt-in and independent. Openlane authorization still applies to every request.
io.github.GregDog/mcp-server-theopenlane)Create an Openlane API token or PAT in console developer settings. Organization tokens start with tola_. Personal access tokens start with tolp_.
export OPENLANE_API_TOKEN="tola_..."
# Optional for multi-org PATs:
export OPENLANE_ORGANIZATION_ID="..."
openlane-mcp serve
Then connect an MCP client. See Client configuration.
go install github.com/GregDog/mcp-server-theopenlane/cmd/openlane-mcp@latest
Requires Go 1.27 or later.
Binary archives will be published on tagged GitHub Releases (linux/darwin amd64+arm64, windows amd64) with SHA256 checksums.
docker run --rm -i \
-e OPENLANE_API_TOKEN \
-e OPENLANE_ORGANIZATION_ID \
ghcr.io/gregdog/mcp-server-theopenlane serve
Images are published with GitHub Releases to ghcr.io/gregdog/mcp-server-theopenlane.
This repository's .cursor/mcp.json uses scripts/mcp-serve.sh, which loads .env and runs the local binary:
{
"mcpServers": {
"openlane": {
"command": "bash",
"args": ["${workspaceFolder}/scripts/mcp-serve.sh"]
}
}
}
Or install globally and pass env vars directly:
{
"mcpServers": {
"openlane": {
"command": "openlane-mcp",
"args": ["serve"],
"env": {
"OPENLANE_API_TOKEN": "${env:OPENLANE_API_TOKEN}",
"OPENLANE_ORGANIZATION_ID": "${env:OPENLANE_ORGANIZATION_ID}"
}
}
}
}
Start the server with bash scripts/mcp-http.sh (see HTTP transport), then use examples/cursor-http.mcp.json as a template.
Add to claude_desktop_config.json:
{
"mcpServers": {
"openlane": {
"command": "openlane-mcp",
"args": ["serve"],
"env": {
"OPENLANE_API_TOKEN": "tola_your_token_here"
}
}
}
}
Prefer environment substitution or a local secrets store over committing tokens. Examples in this repository use fictional values only.
Read tools are always available. Write tools require OPENLANE_ALLOW_WRITE=true or --allow-write. Delete tools require OPENLANE_ALLOW_DELETE=true or --allow-delete.
A successful read still requires:
object:read scope (or equivalent PAT permissions)Writes and deletes additionally require server opt-in (OPENLANE_ALLOW_WRITE / OPENLANE_ALLOW_DELETE) and matching Openlane token permissions. Workflow definition writes, workflow assignment actions, native policy lifecycle actions, and workflow deletes also require confirm: true on the tool call.
Tokens are never logged. See docs/security.md.
| Tool | Description |
|---|---|
openlane_controls_list | List controls |
openlane_controls_search | Search controls by ref code, title, or description |
openlane_control_get | Get a control by ID (with relationship summaries) |
openlane_programs_list | List programs (optional name filter) |
openlane_program_get | Get a program by ID (with relationship summaries) |
openlane_evidence_list | List evidence metadata (optional program/control filters) |
openlane_evidence_get | Get evidence metadata by ID |
openlane_policies_list | List internal policies (optional status filter) |
openlane_policies_awaiting_approval | List policies awaiting approval (native NEEDS_APPROVAL + your pending workflow assignments) |
openlane_policy_get | Get a policy by ID |
openlane_risks_list | List risks (optional program/entity/control/status filters) |
openlane_risk_get | Get a risk by ID (with relationship summaries) |
openlane_findings_list | List findings (optional program/assessment/open/status/severity filters) |
openlane_finding_get | Get a finding by ID |
openlane_assessments_list | List assessments |
openlane_assessment_get | Get an assessment by ID |
openlane_control_implementations_list | List control implementations |
openlane_control_implementation_get | Get a control implementation by ID |
openlane_mapped_controls_list | List cross-framework control mappings (MappedControl) |
openlane_mapped_control_get | Get a control mapping by ID |
openlane_standards_list | List standards / frameworks |
openlane_standard_get | Get a standard by ID |
openlane_tasks_list | List tasks |
openlane_task_get | Get a task by ID |
openlane_entities_list | List entities (vendors; optional risk/tier/review/security filters) |
openlane_entity_get | Get an entity by ID (vendor/security/commercial fields) |
openlane_assets_list | List assets |
openlane_asset_get | Get an asset by ID |
openlane_platforms_list | List platforms (system boundaries; optional name, display id, status, environment, region, criticality filters) |
openlane_platform_get | Get a platform by ID (narrative, owner roles, scope links, diagram metadata) |
openlane_contacts_list | List contacts |
openlane_contact_get | Get a contact by ID |
openlane_reviews_list | List vendor Risk Reviews (optional entity filter) |
openlane_review_get | Get a vendor Risk Review by ID |
openlane_groups_list | List groups (optional name filter) |
openlane_group_get | Get a group by ID |
openlane_users_list | List users (optional name/email filters) |
openlane_user_get | Get a user by ID |
openlane_workflows_list | List workflow definitions (optional schema/kind/active filters) |
openlane_workflows_search | Search workflow definitions by name or description |
openlane_workflow_get | Get a workflow definition by ID (with plain-English summary) |
openlane_workflow_instances_list | List workflow instances (optional definition/state/object filters) |
openlane_workflow_instance_get | Get a workflow instance by ID (assignments, events, proposal preview) |
openlane_workflow_assignments_list | List my workflow approval assignments |
openlane_workflow_assignment_get | Get a workflow assignment by ID (targets, due date, object context) |
openlane_workflow_metadata_get | Get workflow-eligible fields, edges, and resolver keys per object type |
Write tools (require OPENLANE_ALLOW_WRITE=true or --allow-write):
| Tool | Description |
|---|---|
openlane_control_create / openlane_control_update | Create or update a control |
openlane_mapped_control_create / openlane_mapped_control_update | Create or update cross-framework control mappings (MappedControl) |
openlane_evidence_create / openlane_evidence_update | Create or update evidence; optional control_ids / add_control_ids / remove_control_ids (org-owned controls only — not system catalog copies); optional base64 file uploads |
openlane_controls_list / openlane_controls_search | Optional linkable_only returns org-owned controls suitable for evidence linking |
openlane_policy_create / openlane_policy_update | Create or update an internal policy |
openlane_policy_submit_for_approval / openlane_policy_approve / openlane_policy_publish / openlane_policy_return_to_draft | Native InternalPolicy status transitions (confirm required) |
openlane_risk_create / openlane_risk_update | Create or update a risk |
openlane_task_create / openlane_task_update | Create or update a task |
openlane_entity_create / openlane_entity_update | Create or update an entity (vendor); optional base64 logo upload or logo_remote_url |
openlane_platform_create / openlane_platform_update | Create or update a platform (system boundary); owner fields accept user id, email, name, or group id/name; optional scope link ids and base64 diagram uploads |
openlane_contact_create | Create a contact (optional entity_ids) |
openlane_vendor_risk_review_create / openlane_vendor_risk_review_update | Create or update a vendor Risk Review |
openlane_workflow_create / openlane_workflow_update | Create or update a WorkflowDefinition (confirm required) |
openlane_workflow_assignment_approve / openlane_workflow_assignment_reject | Approve or reject a WorkflowAssignment (confirm required) |
openlane_workflow_assignment_request_changes / openlane_workflow_assignment_reassign | Request changes or reassign an assignment (confirm required) |
Delete tools (require OPENLANE_ALLOW_DELETE=true or --allow-delete):
| Tool | Description |
|---|---|
openlane_control_delete | Delete a control by ID |
openlane_mapped_control_delete | Delete a control mapping by ID |
openlane_evidence_delete | Delete evidence by ID |
openlane_policy_delete | Delete a policy by ID |
openlane_risk_delete | Delete a risk by ID |
openlane_task_delete | Delete a task by ID |
openlane_workflow_delete | Delete a workflow definition by ID (confirm required) |
See docs/tools.md for full details. With all modes enabled there are 77 tools (44 read, 27 write, 6 delete).
Enriched get tools return bounded relationship summaries (count + items) so agents can answer program, vendor, control, and finding questions without chaining dozens of shallow calls.
List responses are paginated (items, next_cursor, has_more, total_count). Default page size is 20; maximum is 50.
There is no dedicated control search GraphQL operation in the current Openlane Go client. openlane_controls_search uses official ControlWhereInput contains-filters.
File contents and presigned download URLs are not returned from read tools. Write tools accept optional base64-encoded files[] on evidence create/update (default max 10 MiB decoded per file).
openlane_evidence_create accepts optional control_ids; openlane_evidence_update supports add_control_ids / remove_control_ids. Only org-owned controls (owner_id set) may be linked — system catalog copies are rejected (core#1647). Use openlane_controls_search with linkable_only: true to list linkable controls. Program-imported controls may still show source: FRAMEWORK when owner_id is set.
openlane_control_update accepts owner_id and delegate_id as user id, email, name, or group id; user identifiers resolve to managed personal groups (Openlane controlOwnerID / delegateID). Read responses include control_owner and delegate objects with resolved user_email — do not use openlane_user_get on group ids. See docs/openlane-assignee-ids.md (user vs group vs org; what is fixed globally vs controls-only).
For large files[] base64 uploads, prefer a direct MCP client or automation script that passes the payload machine-to-machine. Agent loops that copy content_base64 between tool calls may truncate or corrupt the data.
By default the server uses stdio. For local HTTP testing:
export OPENLANE_MCP_TRANSPORT=http
export OPENLANE_MCP_HTTP_ADDR=127.0.0.1:8090
openlane-mcp serve
The default bind is loopback only (127.0.0.1:8090). Do not use 0.0.0.0 or bare :port addresses unless you understand the exposure.
HTTP mode has no built-in authentication. Do not expose it directly to the public internet. Anyone who can reach the endpoint can use the server's Openlane token. For remote or shared-network deployment, place a trusted authentication reverse proxy (or equivalent private network controls) in front of the server. See docs/security.md.
Increase OPENLANE_MCP_HTTP_MAX_BODY_BYTES when uploading large evidence files over HTTP.
Published to the MCP Registry as io.github.GregDog/mcp-server-theopenlane on each tagged release. The OCI package is ghcr.io/gregdog/mcp-server-theopenlane.
make test
make build
./bin/openlane-mcp version
See docs/development.md.
See CONTRIBUTING.md. To add or extend an MCP tool, see docs/adding-tools.md.
Issues labeled good first issue or help wanted are a good place to start.
Apache License 2.0. See LICENSE.
Openlane names are used only to describe compatibility. Do not copy Openlane logos or imply official endorsement.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
docker run -i --rm ghcr.io/gregdog/mcp-server-theopenlane:v0.8.0Merge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-gregdog-mcp-server-theopenlane": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/gregdog/mcp-server-theopenlane:v0.8.0"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceghcr.io/gregdog/mcp-server-theopenlane:v0.8.0dockerOpenlane MCP Server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.