Skip to main content
Glama
MSPbotsAI

bizratings-mcp

by MSPbotsAI
README.md
# bizratings-mcp

BizRatings MCP server — exposes the BizRatings CSAT/NPS customer-survey API (for ConnectWise partners) as MCP tools.

## Overview

This server implements the [Model Context Protocol](https://modelcontextprotocol.io/) (Streamable HTTP/SSE transport) and wraps the [BizRatings API](https://api.bizratings.com/swagger/index.html), which manages CSAT/NPS satisfaction surveys tied to ConnectWise tickets and projects. It follows the MSPbots **Vendor MCP Service SOP**: stateless, no stored credentials, per-request header authentication.

The server itself holds no credentials — the caller obtains a BizRatings OAuth2 access token and passes it per-request through a header.

## Quick Start

### Docker (recommended)

```bash
docker compose up --build
```

The server starts on `http://localhost:8080`.

### Local (uv)

```bash
uv sync
python -m bizratings_mcp
```

## Health Check

```bash
curl http://localhost:8080/health
# {"status": "ok"}
```

No token is required for the health endpoint.

## 授权参数说明 (Authentication)

Every request to `/mcp` must include the following HTTP header:

| Header | 类型 | 是否必填 | 默认值 | 枚举值 | 字段描述 | Example |
|---|---|---|---|---|---|---|
| `X-Bizratings-Token` | string | 必填 | 无 | 无(自由文本) | BizRatings OAuth2 access token(`grant_type=client_credentials`)。由调用方(Agent Platform / 上游网关)预先换好后传入,本服务从不接触 `client_id`/`client_secret`,只透传该 Bearer token 给 BizRatings API。 | `X-Bizratings-Token: <access_token>` |

The token itself must be obtained by the caller via:

```bash
curl -X POST https://bizratingsidp.azurewebsites.net/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>&scope=BRApi"
```

Missing or invalid tokens return `401 Unauthorized`.

## Environment Variables

| Variable | Default | Description |
|---|---|---|
| `MCP_HTTP_PORT` | `8080` | Listening port |
| `MCP_HTTP_HOST` | `0.0.0.0` | Listening host |
| `BIZRATINGS_BASE_URL` | `https://api.bizratings.com` | Override if your tenant is routed through a different host |

## MCP Endpoint

```
POST http://localhost:8080/mcp
```

Connect your MCP client with:
- Transport: `http` (Streamable HTTP / SSE)
- Header: `X-Bizratings-Token: <access_token>`

## Tool List

All dates use the `DD-Mon-YYYY` format (e.g. `15-Mar-2026`) unless noted otherwise.

### Tickets

| Tool | 功能 | 参数 |
|---|---|---|
| `bizratings_get_ticket_responses` | 查询工单满意度调查结果(分页) | `member_name?`, `filter_by="CompanyName"`, `keyword?`, `review_type=0`, `score=0`, `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_ticket` | 按工单号查单条调查结果 | `ticket_no` (必填, int) |
| `bizratings_create_ticket` | 推送已关闭工单触发满意度调查邮件(写操作,有副作用) | `ticket_id`, `ticket_title`, `company_rec_id`, `company_name`, `contact_rec_id`, `contact_name`, `contact_email`, `ticket_created_on`, `ticket_closed_on`, `ticket_updated_on` (均必填,均为 ISO 8601), `board_name?`, `resource?` |
| `bizratings_get_ticket_summary` | 工单调查汇总统计 | `member_name?`, `filter_by="CompanyName"`, `keyword?`, `review_type=0`, `start_date`, `end_date` |

### Surveys(项目 / 多站点 / 专项问卷)

| Tool | 功能 | 参数 |
|---|---|---|
| `bizratings_get_project_responses` | 项目类调查结果 | `filter_by="CompanyName"`, `keyword?`, `review_type=0`, `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_multisite_responses` | 跨站点合并工单调查结果 | `member_name?`, `filter_by="CompanyName"`, `keyword?`, `review_type=0`, `score=0`, `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_multisite_employee_rating` | 跨站点员工评分 | `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_five_question_survey_detail` | 5问卷详情 | `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_employee_survey_detail` | 员工调查详情 | `start_date`, `end_date`, `current_page=1`, `page_size=20` |

### Stats

| Tool | 功能 | 参数 |
|---|---|---|
| `bizratings_get_response_summary` | 按 view_type 统计 CSAT/NPS 响应数 | `start_date`, `end_date`, `view_type="Monthly"`, `source="CSAT"` |
| `bizratings_get_client_responses` | 按客户维度统计 | `filter_by="CompanyName"`, `keyword?`, `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_employee_responses` | 按员工维度统计 | `company_name?`, `start_date`, `end_date`, `current_page=1`, `page_size=20` |
| `bizratings_get_quarterly_responses` | 季度盈利明细统计 | 无参数 |
| `bizratings_get_quarterly_summary` | 季度盈利汇总统计 | 无参数 |

## 测试示例 (Test Example)

Call `bizratings_get_ticket_responses` for the last quarter's high scores only:

```json
{
  "method": "tools/call",
  "params": {
    "name": "bizratings_get_ticket_responses",
    "arguments": {
      "start_date": "01-Jan-2026",
      "end_date": "31-Mar-2026",
      "current_page": 1,
      "page_size": 10
    }
  }
}
```

Equivalent `curl` against the running server (streamable HTTP MCP endpoint):

```bash
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "X-Bizratings-Token: <access_token>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "bizratings_get_ticket_responses",
      "arguments": { "start_date": "01-Jan-2026", "end_date": "31-Mar-2026", "page_size": 10 }
    }
  }'
```

Expected shape of a successful result (fields abbreviated):

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\n  \"tickets\": [ { \"ticketID\": 12345, \"companyName\": \"Acme Corp\", \"score\": 9, ... } ],\n  \"totalCount\": 42\n}"
    }
  ]
}
```

## API Reference

- [BizRatings Swagger UI](https://api.bizratings.com/swagger/index.html?url=/swagger/v1/swagger.json)