aictrl
Hosted MCP server for coding agents to query project context, manage backlog tasks, and run controlled workflows using OAuth.
Hosted MCP Server
npx add-mcp 'https://aictrl.dev/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
Plugin Setup
Connect aictrl to ChatGPT, Claude.ai or your coding agent, sign in with OAuth, and use your authorized project context, backlog and workflow tools.
What is the aictrl Plugin?
The aictrl.dev integration connects your AI agent to the canonical hosted MCP endpoint at https://aictrl.dev/mcp. OAuth identifies the authenticated user. Organization scope is selected explicitly with organization_id when a tool requires it and verified against that user's live membership. For the broader connection model and supported agent surfaces, see Plugins and integrations.
Once installed, your agent gains the OAuth-only get_started account-readiness check, three OAuth-only Task Template controls, list_organizations, query_context, update_backlog, and six tools for listing, starting, monitoring, approving, and cancelling controlled workflows. No local MCP process is needed.
Organization access
Start with list_organizations, then use a returned ID as organization_id when a tool requires scope. The server returns a not-found response when the authenticated account is not a member, without disclosing another organization's resources.
Protect customer data with hush
hush is the local aictrl plugin gateway for teams that need to redact customer data and PII before AI requests reach model providers, then restore those values locally in responses.
Quick Setup
Choose your client below. ChatGPT uses a custom MCP plugin; Claude.ai and Claude Desktop use a custom connector. Coding agents can use the public skills and an optional remote MCP connection. All connected routes use https://aictrl.dev/mcp with OAuth.
ChatGPT
Use ChatGPT on the web with permission to add a custom MCP server. Account and workspace policies apply; see OpenAI's current availability and workspace requirements.
- Open ChatGPT Plugins, select the plus button, then Add custom MCP server.
- Name it aictrl. Under Connection, enter
https://aictrl.dev/mcpas the Server URL and choose OAuth authentication. - Review the server warning and requested access, then choose Create as a plugin. Complete the aictrl sign-in and authorization when prompted.
- Open your personal plugin, install it using the plus button, and finish connecting the aictrl account if prompted.
- Start a new ChatGPT Work chat, select @aictrl, and ask Check my aictrl account readiness.
The read-only get_started check explains your next setup step or reports account readiness. It does not create an organization, connect GitHub or start a workflow. You choose whether to follow the recommended next step.
The current Plugins flow does not require Developer Mode. If your workspace still shows the older Apps interface, follow OpenAI's guide above. For authentication failures, see Common Auth Errors; do not switch to an API key or disable OAuth. This custom connection is separate from acceptance into a public directory.
For the current install and removal controls, see OpenAI's plugin guide.
Claude (claude.ai and Claude Desktop)
Add aictrl as a custom connector once; it is then available in every chat, in Claude Desktop, and in Cowork.
- In Claude, open Customize → Connectors, select Add, then Custom → Web.
- Name it aictrl and set the remote MCP server URL to
https://aictrl.dev/mcp. Continue through the detected OAuth settings; use automatic client registration if asked how to identify the client. - Choose Sign in now or Connect when offered. Sign in with the account you use for aictrl.dev.
- Approve the authorization request. Claude returns to the connector with the aictrl tools listed under their titles.
- In a chat, open the tools menu, enable the aictrl connector, and start with Check my aictrl account readiness. The reply names the single best next step, such as connecting a repository.
Read-only tools such as query_context run without a per-call confirmation. Tools that change state (update_backlog, approve_workflow_step, cancel_workflow_run) always ask before running. When aictrl is listed in the Claude Connectors Directory, the directory entry replaces steps 1–2; authentication and tools are the same.
Claude Code
Run the first two slash commands inside Claude Code, then authenticate from your terminal:
Claude Code
/plugin marketplace add aictrl-dev/skills /plugin install aictrl@aictrl-public
plugin:aictrl:aictrl means plugin:<plugin-name>:<server-name>. The qualified form selects the MCP server registered by the plugin and avoids a collision with a user-defined server.
Codex
OpenCode
Terminal
npx @aictrl/opencode@beta opencode mcp auth aictrl
Cursor
Install the portable skills, then merge the server entry into .cursor/mcp.json or ~/.cursor/mcp.json. In Cursor Settings, open Tools & MCP, select aictrl, and choose Connect to complete OAuth.
Terminal
npx skills add aictrl-dev/skills
.cursor/mcp.json
{ "mcpServers": { "aictrl": { "url": "https://aictrl.dev/mcp" } } }
Gemini CLI
Install portable skills, register the HTTP server, then run the slash command inside Gemini CLI:
Terminal
npx skills add aictrl-dev/skills gemini mcp add --transport http aictrl https://aictrl.dev/mcp
Gemini CLI
/mcp auth aictrl
One hosted MCP server
Every client, including claude.ai and Claude Desktop, connects to https://aictrl.dev/mcp. There is no organization slug in the URL and no API key in the public MCP configuration.
Authentication
The public aictrl MCP setup uses OAuth 2.1. The browser sign-in identifies your aictrl.dev account; it does not select or embed an organization in the MCP connection.
OAuth 2.1
When your agent connects to aictrl.dev, its MCP client handles the OAuth flow. Here is what happens behind the scenes:
- MCP returns 401 -- the server responds with a
WWW-Authenticate: Bearerheader, telling the MCP client that authentication is required. - OAuth discovery -- the client fetches the OAuth endpoints from
/.well-known/oauth-protected-resource/mcp. - Browser authorization -- the client opens your browser to
/oauth/authorizewith a PKCE S256 code challenge for security. - Sign in -- you sign in with your Google account via Firebase Auth.
- Redirect back -- after approval, the browser redirects back to the MCP client with an authorization code.
- Token exchange -- the client exchanges the authorization code for an access token at
/oauth/token. - Authenticated requests -- all subsequent MCP requests include the
Authorization: Bearer <token>header.
| Token | Lifetime | Notes |
|---|---|---|
access_token | 1 hour | Automatically refreshed by the MCP client |
refresh_token | 30 days | Used to obtain new access tokens without re-login |
Optional API keys are separate
The developer settings pages can create organization API keys for optional local skill-usage telemetry and private organization skill sync. Those keys are not required for public plugin installation or MCP OAuth, and must never be placed in an MCP URL.
Common Auth Errors
Expired Token
If you see a 401 error after previously working sessions, your access token may have expired. Run the authentication command for your agent again to restart the browser flow.
Wrong Organization
If a tool returns "Organization or resource not found", verify the organization_id argument and confirm that the signed-in account is a current member in Organization Settings.
Client Not Approved
aictrl completes sign-in only for approved MCP client destinations: the ChatGPT and Claude connectors, Glama's hosted MCP Inspector (select OAuth 2.0 when connecting), and agents that receive the sign-in result on your own machine (a loopback callback on localhost, 127.0.0.1, or [::1]), such as Claude Code, Codex, OpenCode, Gemini CLI, and VS Code. Registration without an approved callback returns invalid_redirect_uri, and an older connection saved by such a client returns unauthorized_client. Reconnect from a supported agent.
Network / Connectivity
If your agent cannot reach the MCP server, check your internet connection and ensure aictrl.dev is accessible. Corporate firewalls may need to allow outbound HTTPS to aictrl.dev.
Tool Reference
The canonical aictrl MCP server exposes these tools: get_started, list_tasks, start_task, get_task_execution, list_organizations, query_context, update_backlog, list_workflows, get_workflow, start_workflow, list_workflow_runs, get_workflow_run, approve_workflow_step, cancel_workflow_run, list_pr_findings, and record_finding_verdict.
list_workflow_runs
Read a page of workflow runs in an authorized organization. Combine issue, current native epic, workflow, status, starter, and inclusive date filters. Use needs_attention: true for failed or approval runs you started or on native issues you own; needs_approval matches a pending manual gate.
The result contains data, nextCursor, and hasMore. Pages default to 50 runs and cap at 100. Pass the returned cursor with the same organization and filters to continue; the page size may change. Each item uses the safe run-detail projection and includes native issue identity when available. This read-only tool never starts or changes a run.
get_started
Use this read-only, OAuth-only tool when the user wants to set up aictrl or when repository prerequisites are unknown. It checks live account, organization, GitHub installation, repository connection, and integration state on every call. It never creates an organization, connects a repository, starts a workflow, or accepts user IDs, credentials, prompts, URLs, or continuations as input.
A ready result exposes at most three live-authorized repository display names, the total ready count, and only an action that is available now. For a model-enabled repository with a runnable PR Explanation template and no qualifying execution yet, it recommends the read-only list_tasks catalog; it never starts the task automatically. Setup and repair results use reviewed aictrl.dev guides for account start, GitHub setup, or troubleshooting; ready results may additionally link to the model access guide. Every recommendation explains what is missing, why the action is needed, what completing it unlocks, and that nothing changes automatically.
list_pr_findings and record_finding_verdict
list_pr_findings is read-only. Given an organization and a pull request, it returns the review findings recorded for that pull request — the claim, the cited file and line, the lifecycle state, and the latest verdict — and, when asked, each finding's append-only judgment history. Findings the obsolescence sweep has resolved are left out unless you ask for them, and a run is never shown a judgement it wrote itself.
record_finding_verdict records a triage verdict on one finding: whether the finding is real, what action was taken, the commit the judgement was formed at, and a three-part reasoning chain describing what was read, why the finding is or is not a defect, and what settles it. Cited evidence files are checked against that commit. Verdicts are append-only; a write adds to the finding's history and never removes another run's judgement. Both tools revalidate live organization membership on every call and post nothing to GitHub.
list_tasks, start_task, and get_task_execution
These OAuth-only controls expose the first-party tasks aictrl provisions -- Code Review and PR Explanation -- without exposing skill, credential, model, connection, or raw execution internals, and never expose a template authored inside your organization. list_tasks revalidates live organization membership and GitHub repository authorization and never starts work; an empty result means no first-party task is currently available for that repository. start_task is a separate explicit action bound to a caller-generated idempotency key and the exact pull-request head SHA the user approved. get_task_execution is creator-only unless the caller is an organization administrator; it returns a bounded PR Explanation result only after that artifact is durably stored, and reports status only for a Code Review, whose findings are delivered as review comments on the pull request.
list_organizations
Discover the organizations available to the authenticated account. Use a returned organization_id with scoped context, backlog, and workflow calls. The server re-checks live membership on every request.
query_context
Read project context across six domains: code, system (architecture, data model, APIs, and roadmap), issues, backlog, agent skills, and stack layers. Most actions use stored context; issues/read reads the live GitHub issue and comments, and code/read can fetch repository content. To discover workflow runs, use list_workflow_runs; for a known run, use get_workflow_run. For an execution ID returned by start_task, use get_task_execution.
Input Schema
{ "organization_id": "your-organization-id", "domain": "code | system | issues | backlog | skills | stack", "action": "string // e.g. search, callers, api, list_epics, load, list_layers", "query": "string // search term, file path, symbol, or ID (optional)", "params": {} // additional filters like depth, limit, type (optional) }
Domain values:
| Domain | Description | Example Actions |
|---|---|---|
code | Search and explore codebase structure | search, callers, deps, read |
system | Query system architecture and APIs | api, roadmap |
issues | Browse GitHub issues synced to aictrl | context, list, overlap |
backlog | Read epics and tasks | list_epics, get_epic, list_tasks, get_task |
skills | Browse and load agent skills | list, load |
stack | Explore technology stack layers | list_layers, list_agents, get_layer |
Example: Search for a code symbol
Request
{ "organization_id": "your-organization-id", "domain": "code", "action": "search", "query": "UserService" }
Response
{ "results": [ { "file": "server/services/user-service.ts", "type": "class", "name": "UserService", "line": 15, "summary": "Handles user CRUD, role management, and org membership" } ], "total": 1 }
Example: List epics
Request
{ "organization_id": "your-organization-id", "domain": "backlog", "action": "list_epics" }
Response
{ "tasks": [ { "id": "TASK-42", "title": "Add rate limiting to /api/auth endpoints", "epic": "Security Hardening", "complexity": "medium", "status": "open" } ], "total": 1 }
Example: Load a skill
Request
{ "organization_id": "your-organization-id", "domain": "skills", "action": "load", "query": "coding-standards" }
Response
{ "skill": { "name": "coding-standards", "title": "Coding Standards", "content": "## Rules\n1. Use TypeScript strict mode\n2. All functions must have JSDoc..." } }
update_backlog
Create or update tasks inside an existing epic. The public surface deliberately limits this tool to task mutations; use controlled workflows for broader lifecycle automation.
Input Schema
{ "organization_id": "your-organization-id", "entity": "task", "action": "create | update", "params": {} // create requires epic_id + title; update requires task_id }
Example: Create a task
Request
{ "organization_id": "your-organization-id", "entity": "task", "action": "create", "params": { "epic_id": "SEC-1", "title": "Add rate limiting to authentication endpoints", "complexity": "medium", "depends_on": [] } }