Skip to main content
Glama
README.md
# advocatehub-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) server for
[Influitive AdvocateHub](https://www.influitive.com/), built entirely on the
public Influitive REST API (`api.influitive.com` / `api.influitives.com` in
staging). This is **Phase 1**: no hub source changes, no internal endpoints —
everything here is something any AdvocateHub customer could build against
their own API token.

## What it does

**55 org-token tools** (members, groups, challenges, events, rewards, approvals,
referrals, references, webhooks, messages, integrations, and more) plus
**25 individual-user SSO / JWT self-service tools** (`sso_login`, `whoami`,
`sso_logout`, and 22 `my_*` tools covering profile, groups, challenges, rewards,
activity, notifications, badges/achievements, and social auth). Org-token writes
are confirm-gated and audit-logged; SSO tools sign a human into their own hub
account via a real browser and call the hub as *them*, separate from the org-wide
API token.

**Tool surface (HTTP-first):** streamable HTTP defaults to the **gateway** surface
(~20 category tools). Set header `X-Advocatehub-Tool-Surface: granular` for the full
**~83** granular catalog (e.g. Cursor). Claude Desktop is auto-detected from MCP
`initialize` clientInfo. Stdio defaults to **granular** unless
`ADVOCATEHUB_TOOL_SURFACE=gateway`. See [docs/tool-reference.md](docs/tool-reference.md)
for gateway actions and [docs/setup-claude.md](docs/setup-claude.md) for setup.

## Status

- **P1a (stdio, for Claude Desktop/Code): done.** See
  [docs/setup-claude.md](docs/setup-claude.md).
- **P1b (streamable HTTP, for ChatGPT / remote clients): done, needs a staging
  smoke pass.** See [docs/setup-chatgpt.md](docs/setup-chatgpt.md).
- **Individual-user SSO/JWT self-service (`sso_login`/`whoami`/`sso_logout` + 22 `my_*` tools,
  see `src/tools/myAccount.ts` and `src/tools/sso.ts`): done for stdio only.** See
  [docs/setup-sso.md](docs/setup-sso.md). Not yet available on the streamable
  HTTP transport.
- Target environment so far: **staging** (`https://api.influitives.com`).
  Production support is a config change (`X-Influitive-Base-Url` header or
  `INFLUITIVE_BASE_URL` env var to `https://api.influitive.com`) — re-run the
  staging smoke checklist against production before trusting it there.

## Optimization roadmap

File-grounded improvement plans by credential model:

- **Org token + org id** (integration / admin bot): [docs/optimization-plan-org-token.md](docs/optimization-plan-org-token.md)
- **Individual JWT / SSO** (self-service, signed-in human): [docs/optimization-plan-jwt-sso.md](docs/optimization-plan-jwt-sso.md)
- **Both credentials** (hybrid stdio deployments): [docs/optimization-plan-hybrid.md](docs/optimization-plan-hybrid.md)

See also [JWT_INDIVIDUAL_USER_AUTH_CAPABILITY_MATRIX.md](JWT_INDIVIDUAL_USER_AUTH_CAPABILITY_MATRIX.md) for what each credential can and cannot do today.

## Quick start (HTTP — recommended)

```bash
npm install
npm run build
npm run start:http            # listens on PORT (default 8787), no credentials needed
```

Point your MCP client at `http://localhost:8787/mcp` with per-connection headers:

```json
{
  "mcpServers": {
    "advocatehub": {
      "type": "http",
      "url": "http://localhost:8787/mcp",
      "headers": {
        "Authorization": "Bearer <INFLUITIVE_API_TOKEN>",
        "X-Influitive-Org-Id": "<ORG_ID>",
        "X-Influitive-Base-Url": "https://api.influitives.com"
      }
    }
  }
}
```

See [docs/setup-claude.md](docs/setup-claude.md) and [docs/setup-chatgpt.md](docs/setup-chatgpt.md)
for Claude Desktop, Claude Code (`claude mcp add --transport http`), and ChatGPT setup.
See [docs/usage-guide.md](docs/usage-guide.md) for credential modes and which tools each auth type exposes.

## Quick start (stdio)

```bash
npm install
npm run build
npm run start      # or point your client's config at dist/src/index.js
```

Supply credentials via client `env` vars (`INFLUITIVE_API_TOKEN`, `INFLUITIVE_ORG_ID`)
or call the `configure_tenant` tool at session start. No `.env` file or setup
wizard required.

### Hybrid mode (org token + SSO on one machine)

Use stdio transport and configure **both** credentials:

```bash
# Org-wide integration bot (required for admin tools)
INFLUITIVE_BASE_URL=https://api.influitives.com
INFLUITIVE_API_TOKEN=<from hub Admin -> Integrations -> Influitive API>
INFLUITIVE_ORG_ID=<numeric org id>

# Individual-user SSO (required for sso_login / whoami / my_* tools)
INFLUITIVE_HUB_URL=https://yourhub.influitives.com
```

Or pass `hub_url` to `configure_tenant` alongside `api_token` and `org_id`.

After configuration, run `sso_login` once interactively to seed the browser profile. SSO tools do not work on streamable HTTP — see [docs/setup-sso.md](docs/setup-sso.md) and [docs/optimization-plan-hybrid.md](docs/optimization-plan-hybrid.md).

## Development

```bash
npm run dev            # tsx watch, stdio
npm run dev:http       # tsx watch, streamable HTTP
npm test               # unit tests (mocked fetch, no network)
npm run test:integration  # opt-in, hits real staging — see .env.example
npm run lint
npm run typecheck
```

## Repo layout

```
src/
  index.ts            stdio entrypoint (P1a)
  http.ts             streamable HTTP entrypoint (P1b)
  server.ts           builds the McpServer and registers all tools
  config/             tenant session, HTTP header resolution, env bootstrap, SSO session cache
  client/             InfluitiveClient: auth headers, retries, cursor pagination, rate limiting
  auth/               HubSsoClient: Playwright-driven individual-user SSO login (see docs/setup-sso.md)
  errors/             typed error classes + HTTP status -> error mapping
  registry/           local per-tenant index of challenges this server has created
  audit/              append-only JSONL write audit log (monthly rotation)
  tools/              ~55 org-token tools + configure_tenant + 25 SSO/JWT self-service tools
test/
  unit/               fast tests, fetch mocked, no network
  integration/        opt-in, mutates a real (disposable) staging tenant
docs/                  setup guides, usage guide, tool reference
```

## Design notes worth knowing before you touch this

- **Plug-and-play credentials:** the server starts unconfigured. HTTP clients
  pass `Authorization`, `X-Influitive-Org-Id`, and optionally
  `X-Influitive-Base-Url` per connection. Stdio clients use env vars or
  `configure_tenant` at runtime.
- **Write safety:** every write tool takes a `confirm` flag. `confirm:false`
  (or omitted) only previews — it never calls the API. `confirm:true` executes
  and always appends exactly one entry to the per-tenant audit log
  (`~/.advocatehub-mcp/audit/<orgId>-YYYY-MM.jsonl`, with legacy
  `<orgId>.jsonl` still read), whether it succeeded or failed.
  See `src/tools/shared/confirmGate.ts`.
- **No raw exceptions cross the MCP boundary.** Every tool handler is wrapped
  so typed errors (`AuthError`, `NotFoundError`, ...) come back as
  `{ isError: true }` text, never an unhandled throw. See
  `src/tools/shared/formatters.ts`.
- **The public API has no "list challenges" endpoint.** `ChallengeRegistry`
  (`src/registry/challengeRegistry.ts`) is a local, best-effort index of
  challenges *this server* created — it does not know about challenges
  created any other way, and is lost if `~/.advocatehub-mcp` is wiped.
- **`contacts_api_search` is a per-tenant Labs flag.** If it's off, `/contacts`
  silently ignores filters instead of erroring. `search_members` refuses
  filtered queries once it knows the flag is off (`config.contactsSearchEnabled
  === false`), and self-heals that cache the first time it sees evidence
  either way. See `src/tools/members.ts`.
- **Locking a member is seat reclaim**, per current product policy: it blocks
  login and excludes the member from advocate counts, targeting, and the
  billable seat count. `deactivate_member`/`reactivate_member` describe this
  explicitly in their tool descriptions so an LLM doesn't undersell what the
  action does.

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation4/5

The tools are mostly distinct: list_advocatehub_tools for discovery, configure_tenant for setup, get_active_identity_context for session context. The only potential confusion is between audit_tail and audit_search, but they are differentiated by recency vs. filtered search, and the descriptions clarify the distinction.

Naming Consistency4/5

All tool names use snake_case and are readable. Most follow a verb_first pattern (list_, configure_, get_), but audit_tail and audit_search place the resource (audit) before the verb, a minor deviation from the otherwise consistent convention.

Tool Count4/5

With five tools, the count falls within the typical 3-15 range and feels reasonable for a utility/admin-focused server. It is slightly on the smaller side given the apparent domain, but not inappropriately sparse.

Completeness1/5

The server name and list_advocatehub_tools description reference domain objects like members, rewards, and challenges, yet none of the actual tools perform any domain operations. The set is limited to configuration, identity, and audit utilities, leaving the core AdvocateHub functionality completely absent. Even within the meta-purpose, there is no way to modify configuration or manage audit logs beyond reading them.

Maintenance

ActivityMaintained
ResponsivenessSyncing