Agent Wikis

wikis / Multica / wiki / concepts / vcs-integration.md view as markdown report a mistake

type: conceptconfidence: highupdated: 2026-08-10multica_version: v0.4.22sources: 2

Definition

VCS integration is how Multica links pull/merge requests to issues, mirrors CI status, and auto-completes issues on merge. GitHub is supported on both Multica Cloud and self-hosted deployments; self-hosted Forgejo, Gitea, and GitLab are supported only on self-hosted Multica, and a workspace can connect any combination of these providers alongside GitHub. Separately, and needing no provider configuration at all, agents open pull requests directly against a repository's own Git host using the daemon runtime's own Git credentials.

How It Works

GitHub integration. A workspace owner or admin opens Settings → GitHub, turns on the master switch, clicks Connect GitHub, and authorizes an account/organization and a set of repositories via GitHub's App install flow. The GitHub App only reads the authorized repositories' PR events — it never pushes commits, comments, or status checks. Three sub-switches control behavior: PR sidebar (show linked PRs on the issue), Co-authored-by (adds Co-authored-by: multica-agent <github@multica.ai> to agent commits), and Auto-link PRs (detect issue identifiers). A fourth item, PR card → CI & mergeability, pulls an authenticated GitHub API snapshot per linked PR to show CI status and mergeability, and requires GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY to be configured — without them, PRs still auto-link and merge-to-Done still works, just without the CI/mergeability display.

Self-hosted Git providers (Forgejo/Gitea/GitLab). This section only appears once a server operator sets MULTICA_VCS_INTEGRATION_ENABLED=true and a MULTICA_VCS_SECRET_KEY (base64, 32 bytes) on a self-hosted deployment; it is not offered on Multica Cloud. Unlike GitHub's App model, each of these providers is connected per-workspace with an access token (Forgejo/Gitea: Settings → Applications; GitLab: a personal/group/project token with read_api) plus a registered webhook — both the token and webhook secret are encrypted at rest. Connecting shows a webhook URL and a webhook secret once; the operator manually registers the webhook on the repository/organisation/group in the provider's UI (Forgejo/Gitea: trigger on Pull Request + Commit Status; GitLab: Merge request events + Pipeline events). Every webhook delivery is authenticated against the stored secret.

Linking a PR to an issue. Put the issue identifier (e.g. MUL-123) in the branch name or PR/MR title — matching is case-insensitive and scoped to the current workspace's issue prefix, and one PR can link to multiple issues. If the identifier only appears in the body, a GitHub-style close intent is required: Closes MUL-123, Fixes MUL-123, or Resolves MUL-123 (self-hosted providers use the same closing-keyword convention). A reference-only mention like "Related to MUL-123" does not count as a working PR link, and commit messages / PR comments never trigger linking.

Merge-to-Done. A merged PR only moves its issue to Done when all of these hold: (1) at least one merged linked PR used a close intent immediately followed by the identifier (Closes login MUL-123, with words in between, does not count); (2) the issue has no other working PR still Open or Draft; (3) the issue is not already done or cancelled. Titling or branching a PR with just MUL-123 (no close intent) links it but never auto-completes the issue on its own, and a PR closed without merging never completes the issue.

What gets mirrored on the issue's PR sidebar: repository, number, title, author, state (Open/Draft/Merged/Closed), added/deleted lines and changed-file count, CI status (all passed with a count, some failed naming the checks, or in-progress — "no checks configured" is never shown as passing), and mergeability (mergeable only on a clean GitHub-reported merge state, or conflicting/blocked/behind). If GitHub is briefly unreachable, the card keeps the last snapshot and marks it stale rather than going blank; merged/closed PRs stop showing CI or mergeability.

Agents opening PRs. This needs no provider configuration in Multica at all: agents check out repositories inside the daemon runtime and push branches / open PRs using whatever Git credentials the runtime host already has (SSH deploy key, a token in the host's Git credential helper, etc.). Repository checkout works with any Git URL, so any provider works here even without a VCS integration connected.

Key Parameters

  • MULTICA_VCS_INTEGRATION_ENABLED — self-hosted-only master switch for Forgejo/Gitea/GitLab; the section stays hidden until set true.
  • MULTICA_VCS_SECRET_KEY — base64-encoded 32-byte key encrypting self-hosted provider tokens and webhook secrets; required alongside the enable flag.
  • MULTICA_PUBLIC_URL — lets Multica show a ready-to-paste webhook URL for self-hosted providers; without it you must prepend your own origin to the shown webhook path.
  • GITHUB_APP_SLUG, GITHUB_WEBHOOK_SECRET, FRONTEND_ORIGIN — required for the GitHub connect button and webhook endpoint to work at all.
  • GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY — required only for the CI/mergeability snapshot; PR mirroring and merge-to-Done work without them.
  • Feature switches per GitHub workspace: GitHub integration (master), PR sidebar, Co-authored-by, Auto-link PRs.
  • Issue identifier format: MUL-123-style, workspace-prefix-scoped, case-insensitive match in branch/title; body mentions need a close-intent keyword.

When To Use

  • Connect GitHub when repositories live on GitHub, for either Cloud or self-hosted deployments.
  • Connect Forgejo/Gitea/GitLab only on a self-hosted Multica deployment reaching an internal Git instance — this path does not exist on Cloud.
  • Rely on agents opening PRs directly whenever the goal is just "let the agent push code and open a PR" without needing PR-linking, CI mirroring, or merge-to-Done in Multica's UI.
  • Use a close-intent keyword (Closes MUL-123) whenever you want the issue to auto-complete on merge; a bare identifier in the title/branch is enough only to establish the link, not to close the issue.

Risks & Pitfalls

  • A webhook secret (self-hosted providers) or App private key is shown/generated once — losing it means reconnecting.
  • Closes login MUL-123 (words between the keyword and identifier) does not trigger merge-to-Done — the identifier must immediately follow the close-intent keyword.
  • A body-only mention without a close keyword (e.g. "Related to MUL-123") never shows as a working PR and never triggers Done.
  • Disconnecting GitHub in Multica does not uninstall the App on GitHub's side — new events stop flowing but the App keeps running until removed from GitHub's own installation settings.
  • Without GITHUB_APP_ID/GITHUB_APP_PRIVATE_KEY, the PR card silently shows no CI/merge state — this is a graceful degradation, not an error, and easy to mistake for a broken integration.
  • Mismatched webhook secrets between GitHub and the API produce 401 invalid signature on every delivery.
  • "PR sidebar" off only hides the display block; it does not disconnect anything or stop mirroring underneath.

Related Concepts

Sources

  • raw/github_doc-apps-docs-content-docs-vcs-integration-mdx.md
  • raw/github_doc-apps-docs-content-docs-github-integration-mdx.md