Files
PaperClipAI/doc/connections/GAUGE.md
T
Devin Foley 53105d5830 feat(apps): add Gauge connection (#15596)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents reach external services through the Apps catalog. Each
catalog entry is a reviewed `AppDefinition` that connects a provider's
hosted MCP server to Paperclip's shared vault, grants, policies,
gateway, and audit trail.
> - Gauge (`withgauge.com`) measures how AI answer engines mention and
cite a brand. Its hosted MCP server also gives SEO, analytics and ads
reports, and runs a content pipeline that can publish to a connected
CMS.
> - Gauge is not in the catalog. Operators must use the generic "Connect
your own MCP server" flow. That flow has no branding, no organization
guidance, and no warning about live CMS publishing.
> - The connector playbook supports this provider with existing
definition fields. The server supports dynamic client registration with
a reviewed `mcp` scope, and it accepts an organization API key as a
bearer header.
> - This pull request adds the Gauge definition, its artwork, the
research and permission-review ledger rows, documentation, and
deterministic tests.
> - The benefit is a branded, governed Gauge connection with browser
sign-in, an API-key option, and a clear publish warning.

## Linked Issues or Issue Description

**Problem or motivation**

Marketing and growth teams use Gauge to track their brand in AI answers
and to run content workflows. They want their Paperclip agents to read
visibility, keyword and traffic data, and to prepare content. Gauge is
not in the Apps catalog. Operators must paste the MCP URL into the
generic remote-MCP flow, which gives no branding, no method guidance,
and no warning that content tools can publish live.

**Proposed solution**

Add a catalog-only Gauge connection built from the connector playbook.
Browser sign-in uses Gauge's dynamic client registration and requests
only the reviewed `mcp` scope. The user selects one Gauge organization
on the consent screen. An optional method sends a customer-created
organization API key as an `Authorization: Bearer` header. Both methods
warn the operator to set publish actions to Ask first. Every discovered
tool stays governed by the normal per-action policies.

**Alternatives considered**

A plugin was not needed because no custom UI, tables, workers, or
webhooks are involved. The identity scopes that Gauge also advertises
(`openid`, `profile`, `email`, `organizations`) are not requested,
because Gauge selects the organization on its consent screen. A
Gauge-specific `classifyRisk` rule was not added, because the tool names
cannot be seen without an account. The generic rule already classifies
`publish`, `create` and `update` tools as writes.

**Roadmap alignment**

This extends the existing self-serve remote-MCP connection catalog and
does not overlap planned core work.

## What Changed

- Added the `gauge` provider to `scripts/ingest-app-definitions.mjs`
(category `analytics`, API-key placement, guidance, warnings,
description) and regenerated
`packages/shared/src/app-definitions/gauge.json` and the generated
registry.
- Added the Gauge row to the self-serve MCP research ledger with
`dcr_or_api_key` auth and risk tier S3.
- Added permission reviews for `gauge/mcp-oauth` (explicit scope `mcp`,
from Gauge's live authorization-server metadata) and `gauge/mcp-api-key`
(provider key), with evidence links.
- Added Gauge's mark (`ui/public/brands/apps/gauge.png`, the avatar of
Gauge's official GitHub organization) and the brand manifest entry.
- Added gallery copy for the Gauge card.
- Added `doc/connections/GAUGE.md` (endpoints, scopes, administrator
setup, capabilities and policy, manifest, brand provenance, validation
hook) and linked it from the connections README and the permission
audit.
- Tests: Gauge definition shape, store visibility and artwork, URL
recognition, reviewed scope, bearer-header placement, the connect form's
sign-in default and API-key gating, and the pinned catalog counts.

## Verification

- `pnpm exec vitest run packages/shared/src/app-definitions.test.ts
packages/shared/src/app-definitions-url.test.ts
ui/src/pages/apps/AppsConnect.test.tsx ui/src/pages/apps/Browse.test.tsx
ui/src/lib/app-brand-assets.test.ts
ui/src/pages/apps/AppLogo.brand-assets.test.tsx
server/src/__tests__/tool-access-service.test.ts` — 738 passed.
- `node scripts/check-app-brand-assets.mjs` and `node --test
scripts/app-brand-validation.test.mjs` — passed.
- `pnpm --filter @paperclipai/shared typecheck`, `pnpm --filter
@paperclipai/server typecheck`, `pnpm --filter @paperclipai/ui
typecheck` — clean.
- `node scripts/ingest-app-definitions.mjs --definitions-only` produces
no Gauge drift.
- Manual: on a local instance, open Apps → Browse and confirm the Gauge
card and icon. Open `/apps/connect?source=gauge` and confirm that
sign-in is the default and that the API-key method is under Advanced.
- Live metadata probe on 2026-10-08: an unauthenticated `initialize` on
`https://app.withgauge.com/mcp` returns 401 with `resource_metadata`.
Both `.well-known` documents return the recorded endpoints and scopes.
Dynamic client registration succeeds. The authorize endpoint accepts
`scope=mcp` and rejects an unknown scope with HTTP 400.

## Risks

- Low risk to existing providers: the change is additive catalog data
plus tests. The generated registry only gains one import.
- Gauge content tools can publish to a connected CMS, including live,
and a bulk keyword update replaces each prompt's keyword list. Both
methods warn the operator, and the API-key helper text tells operators
to set publish actions to Ask first.
- Gauge API keys are not scoped and reach the whole organization.
Paperclip cannot narrow an issued key.
- The permission-review ledger records live proof for both methods as
not run. The lifecycle checklist in `doc/connections/GAUGE.md` still
needs a documented pass with a Gauge organization.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`, 1M context) in Claude Code, with
tool use (shell, file editing, web research).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-10-08 12:37:06 -07:00

190 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gauge
Updated: 2026-10-08. Status: catalog definition reviewed against official
documentation and live provider metadata; live account qualification
outstanding.
Gauge (`withgauge.com`) measures how AI answer engines mention and cite a
brand, combines that with SEO, analytics and ads data, and runs a content
pipeline that can publish to a connected CMS. It appears in Apps and uses
Paperclip's shared remote-MCP connection, vault, catalog, grants, policies,
gateway, and audit trail. It is a resource connection, not Paperclip sign-in.
No plugin, database migration, or provider-specific runtime code is required.
Paperclip connects to Gauge's hosted MCP server at
`https://app.withgauge.com/mcp` (Streamable HTTP) with two methods:
- `mcp-oauth`: browser sign-in through Gauge's dynamic client registration.
The user chooses one Gauge organization on the consent screen.
- `mcp-api-key`: an organization API key stored as a Paperclip secret and
sent as an `Authorization: Bearer <key>` header.
This curated connection is the polished route: it provides branding, method
guidance, and a publish warning. The same URL can also be connected from
**Connect your own MCP server**. See
[Connecting any remote MCP server](./GENERIC-REMOTE-MCP.md).
## Service involvement
Gauge hosts the MCP resource and the authorization server. Paperclip stores
the OAuth tokens or the key as secret references, discovers tools with
`tools/list`, and sends the credential on every governed call. No
Paperclip-operated vendor relay is involved; cloud and self-hosted instances
use the same path.
## Endpoints
| Purpose | URL |
| --- | --- |
| MCP resource | `https://app.withgauge.com/mcp` |
| Protected-resource metadata | `https://app.withgauge.com/.well-known/oauth-protected-resource` |
| Authorization-server metadata | `https://app.withgauge.com/.well-known/oauth-authorization-server` |
| Authorize | `https://app.withgauge.com/mcp/oauth/authorize` |
| Token | `https://app.withgauge.com/mcp/oauth/token` |
| Dynamic client registration | `https://app.withgauge.com/mcp/oauth/register` |
The authorization server supports `authorization_code` and `refresh_token`,
PKCE `S256`, and public clients (`token_endpoint_auth_method: none`). It
advertises the scopes `mcp`, `openid`, `profile`, `email` and
`organizations`, and rejects unknown scopes with HTTP 400.
## Scopes
Paperclip requests only `mcp`, the scope that grants MCP access. The identity
scopes are not needed: Gauge selects the organization on its consent screen,
not through a scope. This is recorded as an explicit review in
[`tool-method-permission-reviews.json`](./tool-method-permission-reviews.json).
## Administrator setup
Browser sign-in:
1. In Paperclip, open **Apps → Browse → Gauge** and click
**Continue to sign in**.
2. Sign in to Gauge, choose the organization, and approve access.
API key:
1. In Gauge, open **Settings → Integrations → API Keys** and click
**Generate API Key**. Use a separate key for Paperclip so it can be deleted
independently.
2. In Paperclip, open **Apps → Browse → Gauge**, open **Advanced**, choose
**Use an API key**, paste the key, and click **Connect**.
After either method, set publish actions to **Ask first** or **Off** on the
connection's **Permissions** screen if agents run unattended.
To disconnect, remove the connection in Paperclip. For an API key, also
delete the key in Gauge under **Settings → Integrations → API Keys**, which
revokes every connection that uses it.
## Capabilities and policy
Gauge documents about 25 tools in these groups:
- AI visibility and citations: mentions, citations, answers, visibility and
performance trends, and the sources and pages behind them.
- Topics and prompts: browse tracked prompts and answers; create, generate,
move and tag prompts; bulk keyword updates, which replace each prompt's
full keyword list.
- SEO and keyword reporting: organic rankings, volume, difficulty, and the
keywords a domain or page ranks for.
- GA4, Search Console and PostHog reports, where those integrations are
connected in Gauge.
- Google Ads and OpenAI Ads reporting.
- Content pipeline: brief, research, outline, write, review, images, and
publish to a connected CMS as a draft, to staging, or live.
- Memory files and saved skills: list, read, create and edit.
- Action Center: list, create, assign, set due dates and update status.
- Ask Gauge: natural-language questions answered from the organization's
data.
Tool names were not captured during this review because it needed a signed-in
account. The generic `classifyRisk` rules apply: `publish`, `create`,
`update`, `set` and similar verbs are writes, and `delete` or `remove` is
destructive. Bulk keyword replacement and live CMS publishing are the
highest-impact actions. The method warnings and the API-key helper tell
operators to put publish actions behind Ask first. If live discovery shows
mutations with read-like names, add a reviewed `gauge` rule to
`classifyRisk`, as Superagent has.
## Transport and auth
- Transport: `mcp_remote`, Streamable HTTP (SSE is also documented).
- OAuth: DCR, public client, PKCE, scope `mcp`. Connects as the approving
user, limited to the chosen organization.
- API key: `Authorization: Bearer <key>`. Keys are bound to one
organization, are not scoped, and carry no user identity. Requests are
attributed to the organization. Paperclip cannot narrow an issued key.
## Resource filters
None. Gauge documents no query or header options that narrow the hosted
server. Each connection is already limited to one organization; narrow further
with per-action policies.
## Manifest
| Field | Value |
| --- | --- |
| Slug | `gauge` |
| Category | `analytics` |
| Methods | `mcp-oauth` (`dcr`, S3, scope `mcp`); `mcp-api-key` (`customer`, S3) |
| Server URL | `https://app.withgauge.com/mcp` |
| Credential | `authorization`, password, required |
| Key placement | header `Authorization`, prefix `Bearer ` |
| Console links | docs `https://docs.withgauge.com/help/mcp` |
The definition is generated from the `gauge` row in
`packages/shared/src/self-serve-mcp-research.json` and the `gauge` branch of
`specialMethodsFor` in `scripts/ingest-app-definitions.mjs`.
## Wizard path
`/apps/connect?source=gauge` defaults to **Sign in with Gauge**. Both methods
share one `write` capability profile, so there is no capability picker, but
the access step shows its description, including the publish warning, before
sign-in. Under
**Advanced**, **Use an API key** shows the key field; **Connect** stays
disabled until a key is entered. A successful sign-in or key check and tool
discovery lead to the connection's Permissions screen.
## Governance defaults
- Default profile and bindings: the standard connection profile; every
discovered action starts Allowed under the current product default.
- Policies: operators narrow publish and bulk-edit tools to Ask first or Off
on the Permissions screen.
- Risk: the generic `classifyRisk` rules.
- Quarantine rules: the shared defaults; no Gauge-specific exceptions.
## Brand provenance
Gauge's site ships only a 32×32 favicon, below the catalog's 128px minimum.
The same orange "G" gauge mark is the avatar of Gauge's official GitHub
organization (`withgauge`, whose profile links `https://withgauge.com/`),
published as a 460×460 transparent PNG. That file is used unchanged in both
themes.
| File | Source | SHA-256 |
| --- | --- | --- |
| `ui/public/brands/apps/gauge.png` (460×460) | `https://avatars.githubusercontent.com/u/213101673?v=4&s=512` | `bf1f63a5d30b7f6af1064b74f5f66bf5ea6454d6036a068bf8b0c926fa3f37a6` |
## Validation hook
- Environment: definition review on 2026-10-08 against `origin/master`; no
Gauge account was used.
- Metadata probe: an unauthenticated `initialize` on `/mcp` returned HTTP 401
with `resource_metadata`; both `.well-known` documents returned the
endpoints and scopes above; dynamic client registration succeeded for a
loopback redirect; the authorize endpoint accepted `scope=mcp` (redirect to
Gauge sign-in) and rejected an unknown scope with HTTP 400.
- Deterministic tests: manifest shape, store visibility, artwork, URL
recognition, reviewed scope, bearer-header placement, and the connect
form's sign-in default, the publish warning before sign-in, and API-key
gating.
- Connect evidence, catalog evidence, allowed read, governed write, denied
case, revoke, audit: not run. Both methods still need the full live
lifecycle with a Gauge organization before this connection is considered
qualified.