# mcp-archer

MCP server for the [Archer GRC platform](https://www.archerirm.com). Provides 49 tools for record management, metadata inspection, user administration, workflow automation, and more — all via Archer's REST API.

## Requirements

- Node.js 18+
- An Archer instance (tested against `archerirm.us`)

## Installation

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

## Authentication

Two modes are supported:

### Token-based

```bash
ARCHER_INSTANCE_NAME=your-instance
ARCHER_DOMAIN=us                    # optional, defaults to "us"
ARCHER_TOKEN=your-session-token
```

### Credential-based (recommended)

Enables session auto-refresh on 401/403.

```bash
ARCHER_INSTANCE_NAME=your-instance
ARCHER_DOMAIN=us
ARCHER_USERNAME=your-username
ARCHER_PASSWORD=your-password
```

For custom deployments, set `ARCHER_BASE_URL` directly instead of `ARCHER_INSTANCE_NAME` + `ARCHER_DOMAIN`. The base URL is constructed as `https://{ARCHER_INSTANCE_NAME}.archerirm.{ARCHER_DOMAIN}` when not provided.

## Usage with Claude

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "archer": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-archer/build/index.js"],
      "env": {
        "ARCHER_INSTANCE_NAME": "your-instance",
        "ARCHER_DOMAIN": "us",
        "ARCHER_USERNAME": "your-username",
        "ARCHER_PASSWORD": "your-password"
      }
    }
  }
}
```

## Tools (49)

### Records

| Tool                  | Description                                     |
| --------------------- | ----------------------------------------------- |
| `search_records`      | Get records by content IDs + field IDs          |
| `get_record`          | Get a single record by content ID               |
| `get_records_by_ids`  | Bulk fetch field content for multiple records   |
| `get_related_records` | Get records related via a cross-reference field |
| `get_record_history`  | Get the change history log for a record         |
| `create_record`       | Create a new record                             |
| `update_record`       | Update an existing record                       |
| `delete_record`       | Delete a record                                 |

### Metadata & Schema

| Tool                   | Description                             |
| ---------------------- | --------------------------------------- |
| `get_modules`          | List all applications/modules           |
| `get_application`      | Get detailed metadata for a module      |
| `get_levels`           | Get levels for a module                 |
| `get_level`            | Get details for a specific level        |
| `get_level_layout`     | Get form layout for a level             |
| `get_fields`           | Get field definitions by application ID |
| `get_fields_by_level`  | Get field definitions by level ID       |
| `get_field_definition` | Get a single field definition           |
| `get_value_list`       | Get dropdown options by values list ID  |
| `get_subform`          | Get subform definition                  |

### Attachments

| Tool                | Description                        |
| ------------------- | ---------------------------------- |
| `get_attachment`    | Download an attachment by ID       |
| `upload_attachment` | Upload a base64-encoded attachment |

### Users

| Tool              | Description                     |
| ----------------- | ------------------------------- |
| `get_users`       | List users with OData filtering |
| `get_user`        | Get user details by ID          |
| `create_user`     | Create a new user               |
| `update_user`     | Update an existing user         |
| `activate_user`   | Activate a user account         |
| `deactivate_user` | Deactivate a user account       |

### Groups & Roles

| Tool         | Description           |
| ------------ | --------------------- |
| `get_groups` | List all groups       |
| `get_group`  | Get group details     |
| `get_roles`  | List all access roles |

### Workflow

| Tool                      | Description                                     |
| ------------------------- | ----------------------------------------------- |
| `get_workflow_actions`    | Get available workflow transitions for a record |
| `perform_workflow_action` | Execute a workflow transition                   |

### Data Feeds

| Tool                    | Description                           |
| ----------------------- | ------------------------------------- |
| `execute_data_feed`     | Trigger a data feed by GUID           |
| `get_data_feed_history` | Get execution history for a data feed |

### Questionnaires

| Tool                 | Description               |
| -------------------- | ------------------------- |
| `get_questionnaires` | List all questionnaires   |
| `get_questionnaire`  | Get questionnaire details |

### System

| Tool                      | Description                                               |
| ------------------------- | --------------------------------------------------------- |
| `get_archer_version`      | Get the Archer platform version                           |
| `get_security_parameters` | Get password policies, lockout settings, session timeouts |
| `get_user_tasks`          | Get tasks assigned to the current user                    |

### Smart Composite Tools

Higher-level operations that combine multiple API calls.

| Tool                      | Description                                                   |
| ------------------------- | ------------------------------------------------------------- |
| `lookup_user`             | Search users by name or username — no OData needed            |
| `decode_record`           | Fetch a record with resolved field names and dropdown values  |
| `search_records_filtered` | Get records by content IDs with OData `$filter`/`$orderby`    |
| `get_records_by_module`   | Fetch records by content IDs with auto-discovered field names |
| `batch_resolve_values`    | Resolve up to 50 value lists in parallel                      |
| `lookup_field`            | Search field definitions by name (case-insensitive)           |
| `clone_record`            | Clone a record with optional field overrides                  |
| `bulk_create_records`     | Create up to 50 records with per-record error reporting       |
| `compare_records`         | Compare two records field by field                            |
| `export_module`           | Export records with resolved field names and dropdown values  |

### Generic API Access

| Tool           | Description                            |
| -------------- | -------------------------------------- |
| `raw_api_call` | Call any Archer REST endpoint directly |

## Field Types

| Type | Name            | Value format                     |
| ---- | --------------- | -------------------------------- |
| 1    | Text            | `"string"`                       |
| 2    | Numeric         | `123`                            |
| 3    | Date            | `"2025-01-15T00:00:00"`          |
| 4    | Values List     | `{"ValuesListIds": [id]}`        |
| 6    | Tracking ID     | read-only                        |
| 8    | Users/Groups    | `{"UserList": [{"Id": userId}]}` |
| 9    | Cross-Reference | `{"ContentIds": [contentId]}`    |
| 11   | Attachment      | managed via attachment tools     |
| 21   | First Published | read-only                        |
| 22   | Last Updated    | read-only                        |
| 23   | Related Records | read-only                        |
| 24   | Sub-Form        | nested records                   |
| 25   | History Log     | read-only                        |

## Notes

- All API calls use `/platformapi/core/`. SOAP endpoints are not supported.
- `get_value_list` takes `RelatedValuesListId` from the field definition — not the field ID itself.
- Read-only and calculated fields are rejected on create/update. Use `clone_record` which strips them automatically.
- `decode_record` is the fastest way to inspect a record — it resolves field names and dropdown values in one call.
- `raw_api_call` covers any endpoint not wrapped by a specific tool.

## License

ISC
