Loftlancer Docs
MCP

Using MCP

End-user guide to Collidr MCP — what it does, signing in, scopes, and everyday tasks with AI clients.

Collidr exposes a remote MCP server so AI assistants (Cursor, Claude, VS Code, and others) can work with your organizations, projects, environments, and variables using the same permissions as the studio dashboard.

  • MCP endpoint: https://collidr-mcp.vercel.app/api/mcp
  • OAuth issuer (sign-in & consent): https://auth.loftlancer.com

Technical deployment notes live in MCP setup. This page focuses on using MCP as an end user.

What MCP can do

Tools are registered in @loftlancer/mcp and map one-to-one to canonical actions in @loftlancer/actions. Each call runs requireAction for your user, organization, and project grants.

Typical capabilities (when your role, grants, and token scopes allow):

You want to…MCP tool (example)
List organizationsorganization_list
List or create projectsproject_read, project_create
Manage environmentsenvironment_read, environment_create
Create or update variables (metadata)variable_create, variable_update
Reveal a secret valuevariable_reveal (needs variables:reveal)
Invite a teammatemember_invite
Read audit timelineaudit_timeline_view_org

See the full tool index with inputs and OAuth scopes per tool. Call permissions_snapshot (only needs mcp:tools) to list tools and scopes from a connected client.

User-scoped actions (for example in-app notifications) are not registered as MCP tools even when handlers exist in the API package.

How authorization works (two layers)

  1. OAuth scopes on your access token — coarse gates enforced before a tool runs (insufficient_scope: … if missing).
  2. Org role and project grants — the same rules as the studio (requireAction). A token with projects:write still cannot mutate a project you cannot access.

Always pass organization context on org-scoped tools: organizationId or organizationSlug. MCP bearer tokens do not carry the studio “active organization” cookie.

Most desktop and IDE clients open a browser for OAuth 2.1 against https://auth.loftlancer.com.

Flow

  1. Your MCP client starts authorization and sends you to the auth app.
  2. If you are not signed in, you see Sign in (GitHub OAuth).
  3. On /consent, the Authorize application screen shows:
    • Title: “Authorize application”
    • Application name loaded via oauth2.publicClient for the requesting client_id
    • Requested access — bullet list from describeMcpOAuthScopes (human-readable labels from @loftlancer/actions, plus scope ids in parentheses)
    • Approve / Deny — calls oauth2.consent; on success the browser redirects back to the client
  4. If the consent link is invalid or expired, you see Authorization request invalid with a link back to sign-in.

Deny if you do not recognize the application or the scopes are broader than you need.

Device code flow (CLI and headless)

Better Auth device authorization is enabled with verification URI /device on the auth app.

Steps

  1. Your CLI or headless client displays a user code (often eight characters, with or without a dash).
  2. Open https://auth.loftlancer.com and go to Device sign-in (/device), linked from the sign-in page.
  3. On Device sign-in, enter the code. The form normalizes formatting via formatDeviceUserCode.
  4. If you are not signed in, use Sign in with GitHub first (return URL preserves your code).
  5. After verification, you land on Approve device (/device/approve):
    • Shows the formatted code and asks you to confirm it matches your terminal
    • Shows client id, optional resource URL(s), and requested scopes (same descriptions as consent)
    • Approve calls device.approve — success message: “Device approved. You can return to your terminal or device.”
    • Deny calls device.deny — “Request denied. The device will not be signed in.”
  6. Invalid or expired codes show: “Invalid or expired code…” or “This code is invalid or expired.”

Only approve codes you started on a machine you control.

Choosing scopes (least privilege)

Every tool needs mcp:tools plus a resource scope. Labels shown on consent/device screens come from MCP_OAUTH_SCOPE_DESCRIPTIONS in @loftlancer/actions.

ScopeWhen you need it
organizations:readList/view orgs, members, teams
organizations:writeInvites, team changes, org updates
projects:readProjects and environments (read)
projects:writeCreate/update/delete projects and environments
variables:readVariable keys and metadata (not secret values)
variables:writeCreate/update/delete variables
variables:revealvariable_reveal only — request separately from write
variables:exportBulk export
audit:readTimeline tools

Prefer read scopes until you need mutations. Add variables:reveal only for assistants that must read secret values.

Full matrix: OAuth scopes.

Example prompts and tools

Use natural language in your client; the model should call the right tool with JSON arguments.

Prompt ideaToolNotes
“List my organizations”organization_listNo org ref required
“List projects in acme-corp”project_readorganizationSlug: "acme-corp"
“Create a staging environment on project X”environment_createOrg ref + project id/slug per schema
“Set API_KEY in production”variable_create or variable_updatevariables:write; value encrypted server-side
“What is the DATABASE_URL secret?”variable_revealvariables:reveal; org role + grants
“Invite jane@example.com as member”member_inviteorganizations:write; manager+
“Show recent audit events for this org”audit_timeline_view_orgaudit:read

Inputs must match the Zod schemas on each tool page.

Revealing secrets safely

  • Grant variables:reveal only when necessary; it is listed explicitly on consent/device screens.
  • Reveal is rate-limited more strictly than reads (default 30 requests per 60s window per user/client/tool, configurable via MCP_RATE_LIMIT_MAX_REVEAL).
  • Prefer showing metadata with variable_read when the secret value is not required.
  • Audit entries for MCP reveals record source: "mcp", oauth_client_id, and mcp_tool when ACTIONS_AUDIT_ENABLED is on.

Audit timeline (source = mcp)

runMcpTool wraps execution in runWithMcpAuditContext with source: "mcp". Successful and denied requireAction paths that write audit_event include:

  • source — "mcp" (studio browser traffic uses "trpc")
  • oauth_client_id — from the token (client_id / azp claim)
  • mcp_tool — snake_case tool name

Org owners/managers can inspect timeline via studio or MCP audit_timeline_view_* tools when audit is enabled.

Rate limits

Per user, OAuth client, and tool name, @loftlancer/mcp uses a Postgres-backed fixed window (rate_limit_bucket). Defaults (per 60s unless MCP_RATE_LIMIT_WINDOW_MS is set):

ClassDefault max
Read120 (MCP_RATE_LIMIT_MAX_REQUESTS)
Write verbs60 (MCP_RATE_LIMIT_MAX_WRITE)
Reveal / export30 (MCP_RATE_LIMIT_MAX_REVEAL)

When exceeded, tools throw: rate_limit_exceeded: retry after Ns.

Revoking access

ActionWhat it does
Deny on consent or device approvalClient never receives tokens
Account → Settings → SessionsRevokes Better Auth browser sessions for the account app (revokeAuthSession)
Sign out / revoke other sessionsEnds other studio/account sessions; does not list MCP OAuth clients in the UI today

There is no dedicated “authorized MCP applications” screen in the account app yet. OAuth refresh tokens are stored in oauth_refresh_token (with optional session_id); revoking a session may not invalidate every MCP token. If you approved a client by mistake, deny future consent and contact your org owner; operators can revoke rows in the OAuth tables for incidents.

Next steps

On this page