npm package: @monei-js/mcp-appsync-cognito
Description: MCP server for AWS AppSync with Cognito authentication
Author: MONEI
Latest version: 1.0.10

# @monei-js/mcp-appsync-cognito

[![npm version](https://img.shields.io/npm/v/@monei-js/mcp-appsync-cognito.svg)](https://www.npmjs.com/package/@monei-js/mcp-appsync-cognito)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

MCP server for executing GraphQL queries against AWS AppSync with Cognito User Pools authentication. Built with [FastMCP](https://github.com/punkpeye/fastmcp) framework.

## Features

- **Cognito Authentication**: Username/password authentication with automatic token refresh
- **GraphQL Query Execution**: Execute queries and mutations against AppSync API
- **Operation Discovery**: List available queries/mutations with arguments and example queries
- **Enum Values**: Get all possible values for GraphQL enum types
- **Fuzzy Schema Search**: Levenshtein distance-based search for types, queries, mutations, and fields
- **Schema Introspection**: Explore GraphQL schema types and fields
- **Readonly Mode**: Optional environment variable to block mutations
- **FastMCP Framework**: Declarative tool registration with automatic validation

## Installation

```bash
npm install -g @monei-js/mcp-appsync-cognito
```

Or use with npx:

```bash
npx @monei-js/mcp-appsync-cognito
```

## Tools

### appsync_query
Execute GraphQL queries/mutations. Mutations blocked if `READONLY_MODE=true`.

**IMPORTANT:** Always select only necessary fields to avoid large responses. Types can have 50+ fields.

**Parameters:**
- `query` (string): GraphQL query string
- `variables` (object, optional): Query variables

**Example:** `query { subscriptions(size: 100) { items { id accountId status } } }`

### appsync_list_operations
List available GraphQL queries and mutations with arguments and return types.

**Workflow:** Use this to find operations → use `appsync_introspect` to check return type fields → use `appsync_query` with only necessary fields.

**Parameters:**
- `type` (enum, optional): Type of operations - `queries`, `mutations`, or `all` (default: all)
- `search` (string, optional): Filter operations by name
- `limit` (number, optional): Max results (default: 50)

**Returns:** Operation names, arguments (with types and required flags), return types, example queries with variables.

### appsync_enum_values
Get all possible values for a GraphQL enum type (e.g., AccountStatus, PaymentMethods).

**Workflow:** Use `appsync_search` or `appsync_introspect` first to find enum type names.

**Parameters:**
- `enumName` (string): Name of the enum type

**Returns:** Array of valid enum values with descriptions and deprecation info.

### appsync_search
Fuzzy search GraphQL schema using Levenshtein distance matching.

**Use for:** Broad exploration when you don't know exact names. For targeted operation discovery, use `appsync_list_operations` instead.

**Parameters:**
- `query` (string): Search term
- `limit` (number, optional): Max results (default: 20)

**Scoring:** Exact(100) → StartsWith(90) → Contains(70-80) → Levenshtein(>60%)

### appsync_introspect
Query GraphQL schema information for specific types.

**Use for:** Inspecting type fields before querying. Check field names and types to select only what you need. Don't query all 50+ fields.

**Parameters:**
- `typeName` (string, optional): Specific type to introspect (omit for schema overview)

## Quick Start

### Using npx

```bash
npx @monei-js/mcp-appsync-cognito
```

### Configure Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):

**Method 1: Using global install (recommended)**

```bash
npm install -g @monei-js/mcp-appsync-cognito
```

```json
{
  "mcpServers": {
    "appsync": {
      "command": "mcp-appsync-cognito",
      "args": [],
      "env": {
        "APPSYNC_ENDPOINT": "https://your-api-id.appsync-api.region.amazonaws.com/graphql",
        "AWS_REGION": "us-east-1",
        "COGNITO_USER_POOL_ID": "us-east-1_XXXXXXXXX",
        "COGNITO_CLIENT_ID": "your-client-id",
        "COGNITO_USERNAME": "your-username",
        "COGNITO_PASSWORD": "your-password",
        "READONLY_MODE": "true"
      }
    }
  }
}
```

**Method 2: Using npx (may not work in all environments)**

```json
{
  "mcpServers": {
    "appsync": {
      "command": "npx",
      "args": ["-y", "@monei-js/mcp-appsync-cognito"],
      "env": {
        "APPSYNC_ENDPOINT": "https://your-api-id.appsync-api.region.amazonaws.com/graphql",
        "AWS_REGION": "us-east-1",
        "COGNITO_USER_POOL_ID": "us-east-1_XXXXXXXXX",
        "COGNITO_CLIENT_ID": "your-client-id",
        "COGNITO_USERNAME": "your-username",
        "COGNITO_PASSWORD": "your-password",
        "READONLY_MODE": "true"
      }
    }
  }
}
```

## Configuration

### Required Environment Variables

- `APPSYNC_ENDPOINT`: Your AppSync GraphQL endpoint
- `AWS_REGION`: AWS region (e.g., eu-west-1)
- `COGNITO_USER_POOL_ID`: Cognito User Pool ID
- `COGNITO_CLIENT_ID`: Cognito App Client ID
- `COGNITO_USERNAME`: Your username
- `COGNITO_PASSWORD`: Your password
- `READONLY_MODE` (optional): Set to `true` to block mutations (default: false)

### Cognito Setup

**Important**: The App Client must be configured for `USER_PASSWORD_AUTH` flow.

Get your configuration from:
- AWS Console → Cognito → User Pools
- CloudFormation outputs for your stack
- Serverless deployment outputs

## Usage

### Best Practices

**IMPORTANT**: Always select only necessary fields in queries to avoid large responses:

```graphql
# ✅ Good - only select needed fields
query {
  subscriptions(size: 100) {
    items { id accountId status }
  }
}

# ❌ Bad - selecting all fields can return huge responses
query {
  subscriptions(size: 100) {
    items { id accountId status amount currency ... } # 50+ fields
  }
}
```

### Execute GraphQL Query

```typescript
Use the appsync_query tool:
{
  "query": "query { accounts(size: 1) { items { id name } } }",
  "variables": {}
}
```

### Search Schema

```typescript
Use the appsync_search tool:
{
  "query": "account",
  "limit": 5
}
```

### Introspect Schema

```typescript
Use the appsync_introspect tool:
{
  "typeName": "Account"  // Optional
}
```

## Development

### Local Setup

```bash
# Clone repository
git clone https://github.com/MONEI/mcp-appsync-cognito-.git
cd mcp-appsync-cognito

# Install dependencies
npm install

# Build
npm run build

# Run locally
npm start
```

### Scripts

- `npm run build` - Build with tsup
- `npm run dev` - Watch mode
- `npm start` - Run built package

## Architecture

```
src/
├── index.ts              # FastMCP server entry point
├── auth/
│   └── cognito.ts       # Cognito auth + token refresh
├── graphql/
│   └── client.ts        # AppSync client + mutation blocking
└── tools/
    ├── query.ts         # Execute GraphQL queries
    ├── list-operations.ts # List queries/mutations with args
    ├── enum-values.ts   # Get enum type values
    ├── search.ts        # Fuzzy search with Levenshtein
    └── introspect.ts    # Schema introspection
```

**Build Output:**
- ESM-only package (modern Node.js ≥18)
- TypeScript declarations included
- Source maps for debugging

## Security

- Credentials stored in environment variables
- ID tokens cached in memory only (not persisted)
- Readonly mode prevents accidental mutations
- Automatic token refresh (5min buffer before expiry)
- GraphQL parsing for mutation detection

## Troubleshooting

### "Authentication failed"
- Verify username/password are correct
- Check that App Client allows USER_PASSWORD_AUTH flow
- Ensure user exists in the User Pool

### "Not Authorized"
- Verify user has correct Cognito groups
- Check AppSync authorization rules

### "Mutations are disabled"
- You're in readonly mode - set `READONLY_MODE=false` to enable mutations

## Requirements

- Node.js ≥18.0.0
- AWS AppSync API with Cognito User Pool authentication
- Cognito App Client with USER_PASSWORD_AUTH enabled

## License

MIT © MONEI

## Contributing

Issues and pull requests welcome at [GitHub](https://github.com/MONEI/mcp-appsync-cognito-).