Project Arc – Technical Design Document¶
Introduction¶
Purpose: This document describes the design, architecture, and operational model of Arc, Appcircle's central AI assistant. It covers the agent core, all integrated capabilities, security controls, multi-user isolation, deployment model, cost breakdown, and planned next steps.
Scope: Arc as a whole: the Claude agent loop, all MCP server integrations, the subagents and skills, the Slack adapter, the authorization and audit model, the per-user workspace isolation mechanism, and the Docker deployment.
Source code: github.com/appcircleio/arc
System Overview¶
Arc is Appcircle's central AI assistant, accessible through Slack as a single conversational interface to the systems that engineering and operations work is spread across: GitHub, Linear, Appcircle documentation, Jenkins, KolayIK, Microsoft Teams, Zendesk, HubSpot, and the Appcircle codebase itself.
Arc is an orchestrator, not a search index. At the center is a Claude agent that reads every incoming message and decides which tools to call before producing a response. Each capability is an independent module registered as an MCP (Model Context Protocol) server. Adding a new capability means adding a new module without touching the agent core.
Arc is built on Anthropic's @anthropic-ai/claude-agent-sdk, a Node.js SDK that drives the
agent query loop, running on the Claude Opus 4.8 model.
Architecture¶
Technology Stack:
| Layer | Technology |
|---|---|
| Runtime | Node.js 22, ES modules |
| Agent model | Claude Opus 4.8 (CLAUDE_MODEL=claude-opus-4-8) |
| Package manager | Yarn |
| Agent loop | @anthropic-ai/claude-agent-sdk |
| Capability protocol | Model Context Protocol (MCP) |
| Slack integration | @slack/bolt (socket-mode) |
| Observability | Langfuse / OpenTelemetry tracing |
| Container | Docker (DHI hardened base dhi/node:22-dev, Debian 13 / glibc) |
| Config | JS defaults + config/arc.env + OS env vars |
Agent Loop:
The agent loop is driven by query() from @anthropic-ai/claude-agent-sdk. Every authorized
message enters the loop. The loop runs until the agent produces a final text response, calling
MCP tools as many times as needed.
Key properties:
- System prompt and identity.
ARC.mdat the project root defines who Arc is. It is read once at startup and passed assystemPromptto everyquery()call. Keeping it static means the prompt stays in Anthropic's prompt cache, reducing latency and cost. - Per-session workspace. The user's session workspace path is prepended to the user message (not the system prompt), so each user gets scoped context while the system prompt stays cached.
- Skill discovery.
settingSources: ['project']instructs the SDK to auto-discover Arc's skills from.claude/skills/and its subagents from.claude/agents/. Skills inject a prompt into the main session without a separate Claude API call. - Conversation continuity. Each Slack thread maps to a
sessionId(resume). Subsequent messages in the same thread continue the prior context. - Cancellation. Each query runs under an
AbortController. The "Stop" button in Slack triggers the abort signal; the loop exits cleanly. - Live progress. Every tool call the agent makes is streamed to the Slack message in real time
(
:gear: tool_name params).
Key Components¶
Claude Agent SDK (Core)¶
The primary reasoning and orchestration layer. Reads every user message, calls MCP tools, synthesizes results, and produces responses. All other components are tools called by this core. The model is Claude Opus 4.8 (switched from an earlier model on 2026-06-11 for lower per-token cost and fewer tokens per turn).
Skills¶
Skills inject a specialized prompt into the main session when their trigger matches, with no extra Claude API round trip. The current skill set:
linear-issue- create/update Linear items with Appcircle's templates.docs-authoring- draft new documentation pages to the project's writing standard.appcircle-code-standard- the team's code/PR-review standard, loaded before writing or reviewing code.code-explanation- trace and explain a code flow across services.bug-investigation- investigate a reported bug to root cause before assuming it exists.feature-planning- impact analysis and design before implementation.incident-postmortem- produce a blameless postmortem from a thread.branch-cleanup- list/clean stale git branches (delegates deletion to thebranch-deletersubagent after approval).prep-release- the PREP pre-production release ruleset.caveman/caveman-review- opt-in token-compressed communication / review modes.
The
criticskill (Gemini destructive-action gate, see below) exists in the repo but is currently disabled in the loaded skill set.
Subagents¶
Self-contained, heavy-input / light-reasoning tasks run as subagents on cheaper models, invoked
by the core through the Task tool. Each lives in .claude/agents/ and is auto-discovered:
appcircle-docs(sonnet) - answers Appcircle documentation questions; the answer is relayed as-is.teams-transcript(haiku) - summarizes Microsoft Teams meeting transcripts.code-reviewer(sonnet) - reviews a large / cross-service / high-risk branch diff in an isolated context, invoked byappcircle-code-standard.branch-deleter(haiku) - mechanically deletes already-approved branches forbranch-cleanup.
Gemini MCP (Critic Gate – currently disabled)¶
An independent second opinion from a different AI model (Google Gemini, gemini-3.5-flash). The
critic skill is designed to call mcp__gemini__judge before any destructive or irreversible
action to cross-check it against the conversation context.
The skill is currently disabled (since 2026-06-11): a Gemini outage caused repeated
skip-asks, and it will be re-enabled behind a circuit breaker. While it is off, explicit human
confirmation is the active gate before destructive actions. The Gemini MCP server and the
mcp__gemini__judge tool remain wired and available.
Implementation: src/mcp-gemini.js. Authenticates with GEMINI_API_KEY.
Jenkins MCP (Read-only)¶
Appcircle's CI/CD orchestration server at jenkins.appcircle.io.
Arc can: list jobs, read job details, list builds, read build metadata, stream console logs, and
run a composite diagnose-build (result + failed stage + relevant log slice in one call).
Write and trigger operations are intentionally absent.
Implementation: src/mcp-jenkins.js. Authenticates with JENKINS_USER=arc and
JENKINS_API_TOKEN.
KolayIK MCP¶
Appcircle's HR platform for team directory, leave management, and company calendar.
Arc can: look up team members by name, list upcoming leaves, list public holidays, list upcoming birthdays.
Implementation: src/mcp-kolayik.js. Authenticates with KOLAYIK_EMAIL=arc@appcircle.io and
KOLAYIK_PASSWORD.
Microsoft Teams MCP¶
Microsoft Teams meeting transcripts, via the Microsoft Graph API.
Arc can: list meetings and fetch a meeting transcript. Access is authorized per meeting: the
requesting user's trusted work email (from the SLACK_USERS map, originally sourced from KolayIK)
is passed to the MCP server as ARC_REQUESTER_EMAIL, and the server only returns a transcript for
a meeting the requester actually participated in (fail-closed when the email is missing).
Implementation: src/mcp-teams.js. Uses a delegated arc@appcircle.io refresh token
(MS_REFRESH_TOKEN) against the arc-teams-transcript Microsoft Entra app
(MS_TENANT_ID, MS_CLIENT_ID). Summaries are produced by the teams-transcript subagent.
Zendesk MCP (Read-only)¶
Appcircle's customer support platform.
Arc can: read and search tickets, organizations, users, and comments; list tickets by status,
priority, assignee, or staleness; pull customer context. Read-only - the MCP server exposes
no write tools. Access is gated per user by MCP_USER_ACL.zendesk.
Implementation: src/mcp-zendesk.js. Authenticates with API-token Basic auth
(ZENDESK_EMAIL/token:ZENDESK_API_TOKEN) against ZENDESK_SUBDOMAIN.zendesk.com.
HubSpot MCP (Read-only)¶
HubSpot CRM. Arc can: search and read contacts, companies, deals, tickets and other CRM records,
run SQL-style queries, and read owners, property definitions, org details, and campaign
analytics. Read-only for phase 1 - the server's single write tool is deliberately not on the
allowlist. Access is gated per user by MCP_USER_ACL.hubspot.
Transport: HTTP MCP. Authentication is per user: a shared OAuth app (HS_CLIENT_ID /
HS_CLIENT_SECRET) plus a per-user refresh token (HS_REFRESH_TOKEN__<user>), collected into
config.HUBSPOT_CREDENTIALS at startup and minted at runtime (src/auth-hubspot.js).
ast-grep MCP¶
A structural code search and rewrite tool based on Abstract Syntax Trees (ASTs). Unlike text
search (ripgrep), ast-grep understands code structure, so patterns like
$VAR.method($$$ARGS) match semantically rather than textually.
Arc can:
search- find code patterns across any cloned repo (C#, TypeScript, JS, Python, Java, Go, and more).rewrite-preview- dry-run a structural transformation and show the diff before applying.rewrite-apply- apply the transformation in place (always previewed first).
Implementation: src/mcp-ast-grep.js. Calls the @ast-grep/cli@0.43.0 binary.
GitHub: github.com/ast-grep/ast-grep
gitnexus MCP (Code Knowledge Graph)¶
A code knowledge graph that indexes a curated set of Appcircle source repositories into a queryable graph database (LadybugDB). The graph captures structural relationships between symbols: which method calls which, which class implements which interface, which service imports which module.
Indexed set. Not the full organization. config/repos.txt is a curated subset - every repo
with recent human activity (roughly the last month, bots excluded) plus all backend repos by
prefix (ac-server-*, ac-service-*, ac-lib-*). The full org is too RAM-heavy to index; the
curated set keeps it manageable.
How the graph is built:
- Each source file is parsed into an AST using language-specific parsers (tree-sitter grammars for C#, TypeScript, Java, Go, Python, and more). This step uses no LLM - it is deterministic and fast.
- From the AST, structural nodes (class, method, function, file) and edges (calls, implements, imports, contains) are extracted.
- The resulting graph is stored in LadybugDB, an embedded graph database. The index lives at
/gitnexusand the source files live at/repositories.
Arc's graph queries:
impact/api_impact- blast radius of a change before writing code.context- callers and callees of a symbol.query- execution-flow search and concept queries in natural language.cypher- custom graph queries using Cypher syntax.detect_changes- map a diff to the affected execution flows.list_repos/group_list- list indexed repos / groups; if empty, fall back to ast-grep/ripgrep.route_map,shape_check,tool_map- structural analysis tools.rename,group_sync- graph-write operations (used deliberately, not for ad-hoc reads).
Index lifecycle: The index is not built in the container. A prebuilt artifact is produced
out-of-band by the build-index GitHub Actions workflow (nightly + manual) and published to a
GitHub Release. On every container start the entrypoint downloads and extracts that artifact
into /gitnexus (scripts/fetch-index.mjs); if it is unreachable, the cached copy is reused,
otherwise boot fails fast. The container never runs gitnexus analyze, so boot stays light. The
agent reads a consistent snapshot and never triggers an inline refresh.
License note: gitnexus does not carry a standard open-source license. Its inclusion as a core dependency creates a commercial risk if the tool's terms change. This is tracked as a known risk.
Version in use: gitnexus@1.6.5
Linear MCP¶
Appcircle's project management and issue tracking platform.
Arc can: read teams, issues, projects, milestones, and comments; create and update issues,
projects, milestones, and comments using Appcircle's team templates (via the linear-issue
skill).
Transport: HTTP MCP at mcp.linear.app/mcp. Authenticates via OAuth2 client credentials
(LINEAR_CLIENT_ID, LINEAR_CLIENT_SECRET). The token is minted at runtime and cached; it is
re-minted automatically before expiry (~30-day tokens).
No paid Linear seat is required. A dedicated OAuth app was created and authorized via the client credentials grant, covering all of Arc's Linear operations at no additional monthly cost.
GitHub MCP¶
GitHub, via the GitHub Copilot MCP endpoint.
Arc can: browse code, list branches, commits, releases, pull requests, and issues across all Appcircle repos; open and update pull requests; comment on pull requests and issues; create branches.
Arc cannot: merge pull requests, delete branches, force-push, manage repository settings, write
to issues, or leave inline review approvals/change requests. Notably, direct file writes are
also excluded (create_or_update_file is not allowed): it re-sends whole files and skips
lockfile/build steps, so file changes go through a fresh workspace clone plus git push. All of
these are deliberately omitted from ALLOWED_TOOLS.
Transport: HTTP MCP at api.githubcopilot.com/mcp/. Authenticates with GITHUB_PAT.
Context7 MCP¶
A versioned third-party library documentation service. When Arc needs to answer a question about an external package, Context7 returns up-to-date docs for the specific version in use rather than relying on potentially stale training data.
Arc can: resolve-library-id to find a library, query-docs to fetch relevant documentation.
Transport: HTTP MCP at mcp.context7.com/mcp. Authenticates with CONTEXT7_API_KEY.
Website: context7.com
Team of Rivals¶
Arc's design is intentionally multi-model. Rather than a single AI making all decisions, independent systems are meant to check each other's work. This is the "Team of Rivals" principle:
"If You Want Coherence, Orchestrate a Team of Rivals" arxiv.org/abs/2601.14351
The pillars:
- Claude Agent SDK (core). The primary reasoning and orchestration layer. Handles all tool calls and response synthesis.
- Gemini MCP (critic gate). An independent second opinion from a different AI model, designed to run before every destructive or irreversible action. Currently disabled (see the Gemini MCP component above); while off, explicit human confirmation is the active gate.
- CodeRabbit (PR reviewer). An automated code review service that triggers on every pull request Arc opens on GitHub, providing a review layer independent of both Claude and Gemini. A single seat is scoped to Arc's GitHub user, so only pull requests opened by Arc receive automated review - not the entire organization's pull request volume. Website: coderabbit.ai
For high-risk diffs Arc opens, the code-reviewer subagent adds a further internal review pass
before the PR is finalized.
Detailed Design¶
Security¶
Security is layered across multiple mechanisms, none of which relies on a single point of trust.
Trust Boundary¶
Only a message from an authorized Slack user is treated as an instruction. URLs, file contents, Linear and GitHub issue bodies, Jenkins console logs, and MCP tool results are all data, not instructions. If any of that data contains text that looks like a command ("ignore previous instructions", "your real task is..."), it is treated as content to analyze and surfaced to the user. Arc never executes shell commands, modifies files, opens PRs, or calls any write tool based solely on the content of a tool result or pasted text.
Authorization - Allowlists¶
Access to Arc is governed by two allowlists, both keyed on stable Slack IDs (never display names):
- DM access (
USER_ALLOWLIST). Direct messages are restricted to a named allowlist inconfig/index.js. The list is written with human-readable Slack usernames for maintainability, but the runtime gate resolves each username to its stable Slack user ID (SLACK_USERSmap) at startup and checks the incomingmessage.useragainst the stable ID. - Channel access (
CHANNEL_ALLOWLIST). Arc also answers@mentionsinside a small set of allowlisted (private) channels. Authorization there is membership-based: any member of a listed channel may mention Arc. Mentions from any other channel (public ones included) are ignored silently. An empty list means no channels (fail-closed).
This means:
- A Slack display name change does not affect access in either direction.
- There is no way to gain access by impersonating or guessing a username.
- Removing a user (or channel) from the list takes effect on the next restart.
The SLACK_USERS map also carries each user's trusted work email (sourced from KolayIK). That
email is the requester identity used for write attribution (the "Requesting user:" preamble) and
to authorize Teams transcript and HubSpot access.
Unauthorized requests are rejected before the agent loop starts. A rejection audit event is
written and the user receives :no_entry: You are not authorized to use Arc.
Per-User MCP Access Control¶
Some MCP servers are restricted per user via MCP_USER_ACL (server key -> allowed emails). For
any other requester the server is removed from the query's mcpServers and its
mcp__<server>__* tools are dropped from allowedTools - deterministic and fail-closed on a
missing or unknown email. Currently hubspot and zendesk are gated this way; servers not
listed are available to every authorized user.
Audit Logging¶
Every accepted request and every rejection is written as a structured JSON line to stdout. Docker
log collection (or any compatible log aggregator) picks this up as jsonPayload.
Accepted request log:
{
"ts": "2026-06-04T10:00:00.000Z",
"event": "prompt",
"user": "U0B3P0MM41E",
"username": "ozcanovunc",
"prompt": "first 500 chars of the message..."
}
Rejection log:
{
"ts": "2026-06-04T10:00:00.000Z",
"event": "rejected",
"user": "UXXXXXXXXXX",
"username": "unknown"
}
The username field is resolved at runtime via client.users.info and cached in memory. It is
stored in the audit log for human readability only - the authorization gate never uses it.
Tracing of the agent loop and tool calls is also exported to Langfuse / OpenTelemetry
(src/instrumentation.js), with secret values masked before export.
Read/Write Separation - Allowed Tools¶
Arc has an explicit ALLOWED_TOOLS whitelist in config/index.js. Any tool not on this list is
blocked by the SDK before it can execute. The whitelist is intentionally asymmetric:
- Read tools (
Read,Grep,Glob) are allowed broadly - they can read any path. - Write tools are listed by exact name - adding a new write capability requires a deliberate code change.
- MCP tools follow the same principle: Jenkins, KolayIK, and Zendesk are read-only (
list-*/get-*/search-*prefixes). GitHub write tools are listed individually, excluding merge, delete, admin, issue writes, inline review writes, and direct file writes. HubSpot is read-only for phase 1. ast-greprewrite-applyand gitnexusrename/group_syncare the only structural write tools, each previewed first.
Tool-Use Hooks¶
Three hooks run around tool calls:
hook-gitnexus.js(PreToolUse). A narrow substring-deny hook that blocks any tool call referencing the/gitnexusindex path with403 Forbidden. It is false-positive-free because no legitimate flow references that path.hook-attribution.js(PreToolUse). Appends the requester-attribution footer (the trusted Slack-derived work email) to Linear and GitHub writes. Fail-closed: a write with no resolvable email is blocked.hook-secret-guard.js(PostToolUse). Withholds any tool output that contains a configured secret value (read fromarc.env.example+process.env) before it reaches the model - the backstop againstprintenv/ file-read leaks.
Note on path enforcement. The earlier broad
PreToolUsepath guard was removed on 2026-06-04 after false positives on legitimate git/gh paths. Current path enforcement is:/app(Arc's own source) is immutable via the read-only image filesystem;/gitnexusis guarded by the narrow hook above;/repositoriesis read-only at the source mount but is not yet guarded at the process level (mount-layer enforcement is an open TODO). Per-user workspace isolation under$WORKSPACE_DIRrelies onARC.mdinstructions plus the Slack allowlist as the outer bound.
Destructive Action Gate (Critic)¶
Code changes, PR creation, Linear ticket creation, and comments are designed to be gated behind
the critic skill, which calls mcp__gemini__judge with the proposed action and conversation
context. The critic skill is currently disabled (see the Gemini MCP component); while it is
off, explicit user confirmation in-thread is the active gate before Arc executes a destructive or
irreversible action.
Surface Restriction¶
Arc responds only to direct messages (channel_type === 'im') from allowlisted users and to
@mentions inside allowlisted private channels. Bot messages and system subtypes are ignored.
This limits the attack surface to authenticated Slack users on the allowlists.
CodeRabbit - Data Privacy¶
CodeRabbit reviews pull request code on behalf of Arc. Before enabling this integration on Appcircle's private repositories, written confirmation was obtained from CodeRabbit (Mitali Sapra, mitali@coderabbit.ai) on the following points:
- Private repository code is not used to train foundation models.
- Privacy and security handling for private repositories is consistent across all plans.
- Enterprise-grade security controls are available, with documentation on retention, subprocessors, and DPA availability on request.
- Providers are engaged in a way designed to protect customer data and support strong privacy guarantees.
This confirmation was requested in the context of KVKK compliance. The written exchange is on file with the Appcircle team.
Deployment and Infrastructure¶
Base Image and Runtime¶
FROM dhi/node:22-dev # DHI hardened base (Debian 13 / glibc); production pulls the GAR mirror
Node.js 22 on a DHI (Docker Hardened Images) base. @ast-grep/cli@0.43.0 and gitnexus@1.6.5
are installed globally as CLI binaries. The C++ build toolchain is used only during image build
(to compile tree-sitter grammars without prebuilts) and is purged afterward to keep the final
image lean. Production builds from a GAR mirror of the base image; a local build can swap to the
dhi.io base.
Volume Mounts¶
The container uses three Docker volumes:
| Mount | Purpose | Agent access |
|---|---|---|
/repositories |
Canonical Appcircle source (curated subset) | Read-only at source; process-level guard is an open TODO |
/gitnexus |
Knowledge graph index (LadybugDB) | Read-only (narrow PreToolUse deny hook) |
/workspaces |
Per-user session workspaces | Read-write |
On every start the entrypoint script (scripts/entrypoint.sh) wipes the per-user session
workspaces, clones or shallow-pulls every canonical repo into /repositories, and acquires the
gitnexus index into /gitnexus by downloading the prebuilt artifact from a GitHub Release. The
container never builds the index itself.
Health Check¶
A minimal HTTP server listens on $PORT (default 8080) and responds ok to any request.
This gives the container a health check endpoint. The Slack socket-mode adapter does not expose
an HTTP port on its own.
Configuration and Secrets¶
Non-secret defaults are in config/index.js (committed). Secrets are supplied via:
config/arc.env(local development, gitignored,KEY=valueformat)- OS environment variables (CI/CD, production)
Precedence: OS env vars override arc.env, which overrides config/index.js defaults.
Secrets required at runtime:
SLACK_BOT_TOKEN - Slack bot token (socket-mode)
SLACK_APP_TOKEN - Slack app-level token (socket-mode)
CLAUDE_CODE_OAUTH_TOKEN - Claude agent SDK authentication token
GITHUB_PAT - GitHub Personal Access Token
GEMINI_API_KEY - Gemini API key (critic gate)
CONTEXT7_API_KEY - Context7 API key (library docs)
JENKINS_API_TOKEN - Jenkins service account token
KOLAYIK_PASSWORD - KolayIK service account password
LINEAR_CLIENT_ID - Linear OAuth app client ID
LINEAR_CLIENT_SECRET - Linear OAuth app client secret
MS_REFRESH_TOKEN - Microsoft Graph delegated refresh token (Teams transcripts)
ZENDESK_API_TOKEN - Zendesk Support API token
HS_CLIENT_ID - HubSpot OAuth app client ID (shared)
HS_CLIENT_SECRET - HubSpot OAuth app client secret (shared)
HS_REFRESH_TOKEN__<user> - HubSpot per-user refresh token
LANGFUSE_PUBLIC_KEY - Langfuse tracing public key
LANGFUSE_SECRET_KEY - Langfuse tracing secret key
Performance Considerations¶
Multi-User Isolation¶
Multiple team members can use Arc simultaneously with no risk of interference between sessions.
Automatic workspace assignment. When a message arrives, the Slack adapter derives a session workspace from the stable Slack user ID:
/workspaces/<slack_user_id>/
This directory is created automatically (mkdir -p) if it does not exist.
Write isolation. Every file write, git clone, build output, and generated artifact is scoped
to the requesting user's workspace. Two team members can edit the same repository simultaneously
with no conflict because each works in their own fresh clone. Isolation under $WORKSPACE_DIR
relies on the ARC.md instructions and the Slack allowlist as the outer bound; mount-layer
enforcement of the per-user boundary is an open TODO (see the security note above).
Shared read, isolated write. The curated Appcircle repositories live at /repositories as a
single shared read-only copy. All users query the same source for understanding code - there is
no per-user copy. When a user needs to modify code, the relevant repo is cloned freshly from
GitHub into the user's own workspace.
Thread-based session continuity. Each Slack thread maps to a sessionId. Concurrent queries
run under separate AbortController instances. A user clicking "Stop" aborts only their own
query.
File attachments. Files dropped into a Slack DM are downloaded into the user's workspace
under slack-uploads/<file_id>/. Other users cannot access this path.
Adapter Portability¶
The runQuery() function in src/common.js is adapter-agnostic. It accepts prompt,
sessionId, abortSignal, and userWs. The Slack-specific logic (DM and channel-mention paths)
lives entirely in src/adapter-slack.js. Adding support for a new surface (Microsoft Teams, CLI,
web UI) means adding a new src/adapter-<name>.js file without changing the agent core, security
hooks, or MCP server registrations.
Risks and Mitigation Strategies¶
Claude Enterprise Upsell Trigger¶
Arc uses a Claude Team account, not Claude Enterprise. Anthropic's systems can detect usage patterns that resemble enterprise-scale workloads - particularly from US-market accounts - and may apply pressure to upgrade or trigger unexpected billing.
Mitigation: The Claude Team account will be created in Turkey. A Turkish account with moderate user counts is less likely to appear on Anthropic's enterprise radar. This is a mitigation, not a guarantee, and the risk of unexpected cost escalation remains.
CodeRabbit Scope Creep¶
CodeRabbit is configured as a single seat tied to Arc's GitHub user. The expectation is that only pull requests opened by Arc are reviewed automatically. If the seat is later reused or the integration is widened to the organization level, costs will increase significantly (CodeRabbit's organization-wide plans are substantially more expensive). Any change to the CodeRabbit configuration should be a deliberate decision, not a side effect of a GitHub org settings change.
gitnexus License¶
gitnexus does not carry a standard open-source license. Its inclusion as a core dependency creates a commercial risk if the tool's terms change or if Appcircle's usage exceeds what is implicitly permitted.
Costs¶
The figures below reflect the original phase-1 plan and have not been revised since Arc went live with additional integrations (Teams, Zendesk, HubSpot, Langfuse) and the move to the Claude Opus 4.8 model. They should be refreshed against current usage.
All figures are in USD per month.
Claude Team¶
A dedicated Claude Team workspace for Arc. Initially one premium seat to observe usage patterns; a second seat can be added under a rotation model if usage warrants it.
| Seats | Monthly cost |
|---|---|
| 1 (initial) | $125 |
| 2 (if needed) | $250 |
Context7¶
Context7 starts on the free tier. If monthly usage exceeds 1,000 API calls, the pro plan will be activated.
| Tier | Monthly cost |
|---|---|
| Free (up to 1,000 calls) | $0 |
| Pro (above 1,000 calls) | $10 |
Gemini¶
Used for the critic gate (currently disabled). Ongoing cost is not yet determined.
| Tier | Monthly cost |
|---|---|
| Free trial | $0 |
| Paid (TBD) | TBD |
CodeRabbit¶
Pro plan on a single seat scoped to Arc's GitHub user.
| Plan | Monthly cost |
|---|---|
| Pro | $30 |
Linear¶
No paid Linear seat is required. A dedicated OAuth app was created and authorized via the client credentials grant, covering all of Arc's Linear operations at no additional cost.
| Tier | Monthly cost |
|---|---|
| OAuth app (client credentials) | $0 |
Summary¶
| Service | Initial monthly cost |
|---|---|
| Claude Team (1 seat) | $125 |
| Context7 (free tier) | $0 |
| Gemini (free trial) | $0 |
| CodeRabbit Pro | $30 |
| Linear (OAuth app) | $0 |
| Total | $155 |
Adding a second Claude seat would increase the monthly total to $280. This summary predates the Teams / Zendesk / HubSpot / Langfuse additions and the Opus 4.8 switch and should be refreshed.
Next Steps¶
- Teams adapter. The Teams transcript capability is in place (Teams MCP +
teams-transcriptsubagent). The remaining step is a fullsrc/adapter-teams.jsthat, following the Slack adapter as a blueprint, brings Arc's full capability set to Microsoft Teams as a second chat surface. - CSM meeting summaries at scale. Building on the Teams transcript capability, scale it to Customer Success Manager meetings: summarize customer calls, extract action items, and link them to Linear issues automatically.
- HubSpot / Zendesk writes. Both are read-only today. A deliberate phase-2 decision could add scoped write tools (e.g. ticket updates, CRM record updates) behind the per-user ACL.
- Re-enable the critic gate. Bring the
criticskill back behind a circuit breaker so a Gemini outage degrades gracefully instead of forcing repeated skip-asks. - Admin panel. A lightweight internal UI (or Arc command) to add and remove users from the allowlists, grant or revoke specific capabilities per user, and view active sessions without requiring a code change or container restart.
- Extended KolayIK capabilities. Expand the KolayIK MCP beyond read-only lookups - for example, submitting leave requests, viewing payslips, or managing time-off approvals directly from Slack.
- Observability alerting. Structured audit logs and Langfuse/OpenTelemetry tracing are in place. The next step is routing logs to a centralized aggregator and adding alerting for repeated authorization rejections, high error rates, and cost anomalies.
- Process-level mount enforcement. Close the open TODO: enforce the
/repositoriesread-only boundary and per-user$WORKSPACE_DIRisolation at the mount/process layer rather than relying on instructions plus the allowlist. - Onboarding documentation. A short internal guide for adding or removing users from the allowlists, rotating secrets, and refreshing the gitnexus index.