Skip to main content
Glama
khoadong07

kompa-mcp-server

by khoadong07
README.md
# kompa-mcp-server

MCP (Model Context Protocol) server that exposes Kompa social-listening data
— buzzes, sentiment breakdown, trendline, hot topics, unique authors — as
tools any MCP client can call. Built so you can chat about Kompa data
directly inside **Claude** (Desktop or Code) instead of a standalone chat UI.

This package is independent from the `kompa-chat` Next.js app — it only
reuses the same Kompa GraphQL API and login flow, ported into a plain MCP
server. It ships two entrypoints:

- `build/index.js` — stdio transport, for local MCP clients that spawn a
  child process (Claude Desktop/Code via local config).
- `build/http.js` — Streamable HTTP transport, multi-tenant: one hosted
  connector URL can serve many customers. See [`DEPLOY.md`](./DEPLOY.md)
  for the full VPS deploy guide (systemd + Caddy + onboarding a customer).

## Account & topic config

There's no separate API-key system. Each customer already has a Kompa
username/password — that's what they use here too, via a tool call:

```
configure_account({ username, password, topicIds: ["topic-id-1", ...] })
```

Call it once at the start of a conversation (Claude will do this
automatically once you mention your credentials/topics, or you can ask it
to explicitly). Every other tool then reuses that account and topic_ids
until you call `configure_account` again — no need to repeat them on
every call, though you can still pass `topicIds` per-call to override.

This exists instead of header-based auth because Claude's custom request
headers for connectors are currently a gated beta rollout — see the
"Auth model" note in `DEPLOY.md`.

For the stdio entrypoint, you can skip the tool call entirely by setting
`KOMPA_USERNAME`/`KOMPA_PASSWORD`/`KOMPA_DEFAULT_INDEXES` env vars — the
account is pre-configured at startup in that case.

## Tools

| Tool | Description |
|---|---|
| `configure_account` | Set username/password/topicIds for the rest of the conversation |
| `list_content_types` | Enum values accepted by `types`/`sentiments` params |
| `search_buzzes` | Paginated raw buzz search with filters |
| `get_sentiment_trend` | Time-bucketed volume by sentiment (trendline) |
| `get_sentiment_breakdown` | Total count grouped by sentiment |
| `get_channel_breakdown` | Volume grouped by channel, nested by sentiment |
| `get_hot_topics` | Top discussion threads ranked by volume |
| `get_unique_authors` | Distinct author/profile count |

All data tools accept `fromDate`/`toDate` (`"YYYY-MM-DD HH:mm:ss"`),
optional `types`, `query`, `sentiments`, and optional `topicIds` (falls
back to the `topicIds` set via `configure_account`).

## Setup

```bash
npm install
npm run build
```

Copy `.env.example` for reference (only relevant to the stdio entrypoint
— see above).

## Using it standalone (before publishing)

Point any MCP client at the built entry file directly:

```json
{
  "mcpServers": {
    "kompa": {
      "command": "node",
      "args": ["/absolute/path/to/kompa-mcp-server/build/index.js"]
    }
  }
}
```

- **Claude Desktop**: put this block in `claude_desktop_config.json`
  (Settings → Developer → Edit Config).
- **Claude Code**: put the same `mcpServers` block in a `.mcp.json` at your
  project root, or run:

  ```bash
  claude mcp add kompa -- node /absolute/path/to/kompa-mcp-server/build/index.js
  ```

Restart the client after editing config, then in chat say something like
*"My Kompa account is X/Y, topic ID Z — what's the sentiment breakdown
for query 'foo' between 2026-08-01 and 2026-08-21?"* — Claude calls
`configure_account` then the data tool.

## Publishing to npm

So users can install via `npx kompa-mcp-server` instead of a local path:

```bash
npm login
npm publish --access public
```

Then the MCP config becomes:

```json
{
  "mcpServers": {
    "kompa": {
      "command": "npx",
      "args": ["-y", "kompa-mcp-server"]
    }
  }
}
```

## Publishing to a Claude Code plugin marketplace

Both Claude Code and, for Team/Enterprise orgs, claude.ai itself can add a
plugin marketplace directly from a git repo — no npm publish needed here,
since `marketplace-example/plugins/kompa-mcp/.claude-plugin/plugin.json`
points at your hosted HTTP connector (see `DEPLOY.md`), not a local
package. Layout:

```
marketplace-example/
├── .claude-plugin/
│   └── marketplace.json
└── plugins/
    └── kompa-mcp/
        └── .claude-plugin/
            └── plugin.json      # edit the connector URL in here first
```

**As maintainer:**
1. Edit the `url` in `marketplace-example/plugins/kompa-mcp/.claude-plugin/plugin.json`
   to your real deployed domain (`https://mcp.yourdomain.com/mcp`).
2. Push a repo containing the `marketplace-example/` layout (rename the
   folder to whatever you want the repo root to be) to GitHub — public,
   or private if only your org needs it (private requires everyone
   installing to have repo access via their GitHub/git credentials).
3. Share the repo URL.

**As a Claude Code user installing it:**

```bash
/plugin marketplace add https://github.com/<you>/<marketplace-repo>
/plugin install kompa-mcp-plugin@<marketplace-name>
```

**As a claude.ai Team/Enterprise org (no CLI, GUI only):**
1. Org owner: **Organization settings → Connectors/Plugins → Add plugin
   marketplace → "Add from a repository"** → paste the same GitHub URL.
2. Members: **Customize → Plugins**, find `kompa-mcp-plugin` listed from
   your marketplace, click install/connect.

For individual Free/Pro/Max accounts with no org, this repo-based
marketplace path isn't available — use the zip-upload flow in
`PLUGIN.md` instead.

## Notes / limitations

- Login uses the same username+password flow as `kompa-chat`'s `auth.ts`
  — no OAuth, no browser automation.
- The access token is cached in-process per username and refreshed 5
  minutes before expiry.
- `topicIds` must be valid Kompa project index IDs the account has access
  to — this server does not discover or list them for you.
- In HTTP mode, account/topic config lives only in that MCP session's
  memory — closing the conversation/session drops it, and the next
  session must call `configure_account` again.