Skip to main content
Glama
Darshika0712

MCP Server Suite

by Darshika0712
README.md
# MCP Server Suite

A production-ready suite of **Model Context Protocol (MCP)** servers in TypeScript. Gives AI agents (Kiro, Claude Desktop, Cursor) programmatic access to AWS resources, local databases, and web scraping capabilities.

## Zero Cost Guarantee

This project costs **$0** to build, test, and run. No paid APIs, no cloud hosting, no subscriptions. See [Cost Breakdown](#cost) below.

## Documentation

| Document | Purpose |
|----------|---------|
| [Manual Testing Guide](docs/MANUAL-TESTING-GUIDE.md) | Step-by-step: install, build, test, run manually |
| [Interview Guide](docs/INTERVIEW-GUIDE.md) | How to explain this project, demo script, talking points |
| [API Reference](docs/API.md) | Full tool input/output schemas |
| [Architecture Deep Dive](docs/ARCHITECTURE.md) | Data flow, patterns, security |

## Architecture

```mermaid
graph TB
    subgraph "AI Clients"
        K[Kiro IDE]
        CD[Claude Desktop]
        CU[Cursor]
    end

    subgraph "MCP Transport Layer"
        STDIO[stdio / JSON-RPC 2.0]
    end

    subgraph "MCP Server Suite"
        subgraph "aws-explorer"
            S3[list-s3-buckets<br/>list-s3-objects]
            EC2[list-ec2-instances<br/>describe-ec2-instance]
            LAMBDA[list-lambda-functions<br/>describe-lambda-function]
            DYNAMO[list-dynamodb-tables<br/>describe-dynamodb-table]
        end

        subgraph "database"
            QUERY[query]
            INSERT[insert]
            UPDATE[update]
            DELETE[delete]
            SCHEMA[list-tables / describe-table<br/>create-table]
        end

        subgraph "web-scraper"
            FETCH[fetch-page]
            LINKS[extract-links]
            TEXT[extract-text]
            SEARCH[search-in-page]
        end

        subgraph "shared"
            LOGGER[Logger]
            ERRORS[Error Handling]
            TYPES[Response Types]
            MW[Middleware<br/>Retry / Circuit Breaker]
        end
    end

    subgraph "External Services"
        AWS[AWS SDK v3]
        SQLITE[SQLite via sql.js]
        WEB[Web / HTTP]
    end

    K & CD & CU --> STDIO
    STDIO --> S3 & EC2 & LAMBDA & DYNAMO
    STDIO --> QUERY & INSERT & UPDATE & DELETE & SCHEMA
    STDIO --> FETCH & LINKS & TEXT & SEARCH

    S3 & EC2 & LAMBDA & DYNAMO --> AWS
    QUERY & INSERT & UPDATE & DELETE & SCHEMA --> SQLITE
    FETCH & LINKS & TEXT & SEARCH --> WEB

    aws-explorer & database & web-scraper -.-> shared
```

## Package Structure

```mermaid
graph LR
    ROOT[mcp-server-suite<br/>Turborepo Monorepo]
    ROOT --> SHARED["@mcp-suite/shared<br/>Logger, Errors, Types, Middleware"]
    ROOT --> AWS["@mcp-suite/aws-explorer<br/>8 tools, 2 resources"]
    ROOT --> DB["@mcp-suite/database<br/>7 tools, 3 resources"]
    ROOT --> WS["@mcp-suite/web-scraper<br/>4 tools, 1 resource"]

    AWS --> SHARED
    DB --> SHARED
    WS --> SHARED
```

## Quick Start

### Prerequisites

- Node.js >= 18.0.0
- npm >= 10.0.0
- AWS credentials configured (for aws-explorer)

### Installation

```bash
git clone <repository-url>
cd mcp-server-suite
npm install
npm run build
```

### Running Tests

```bash
npm run test          # Run all tests (184 tests across 4 packages)
npm run test:coverage # Run with coverage reports
```

### Configure with Kiro

Add to your `.kiro/settings/mcp.json`:

```json
{
  "mcpServers": {
    "aws-explorer": {
      "command": "node",
      "args": ["./packages/aws-explorer/dist/index.js"]
    },
    "database": {
      "command": "node",
      "args": ["./packages/database/dist/index.js"],
      "env": {
        "MCP_DB_PATH": "./data/my-database.db"
      }
    },
    "web-scraper": {
      "command": "node",
      "args": ["./packages/web-scraper/dist/index.js"]
    }
  }
}
```

### Configure with Claude Desktop

```json
{
  "mcpServers": {
    "aws-explorer": {
      "command": "node",
      "args": ["/absolute/path/to/packages/aws-explorer/dist/index.js"]
    },
    "database": {
      "command": "node",
      "args": ["/absolute/path/to/packages/database/dist/index.js"]
    },
    "web-scraper": {
      "command": "node",
      "args": ["/absolute/path/to/packages/web-scraper/dist/index.js"]
    }
  }
}
```

## Packages

### @mcp-suite/aws-explorer

Provides read-only access to AWS resources. Requires AWS credentials via environment variables, CLI profile, or IAM role.

| Tool | Description |
|------|-------------|
| `list-s3-buckets` | List all S3 buckets, optionally filter by prefix |
| `list-s3-objects` | List objects in a bucket with prefix filtering |
| `list-lambda-functions` | List Lambda functions with runtime/memory info |
| `describe-lambda-function` | Get detailed Lambda config including env vars |
| `list-dynamodb-tables` | List DynamoDB tables with optional details |
| `describe-dynamodb-table` | Get table schema, indexes, throughput |
| `list-ec2-instances` | List EC2 instances, filter by state |
| `describe-ec2-instance` | Full instance details including networking |

**Resources:**
- `aws://config/region` — Current AWS region
- `aws://config/account` — Account configuration summary

### @mcp-suite/database

SQLite database operations via sql.js (pure JavaScript, no native deps). Supports full CRUD with safety guardrails.

| Tool | Description |
|------|-------------|
| `query` | Execute read-only SQL (SELECT/WITH/EXPLAIN/PRAGMA) |
| `insert` | Insert single or batch rows |
| `update` | Update rows (WHERE clause required) |
| `delete` | Delete rows (WHERE clause required) |
| `list-tables` | List all tables with optional row counts |
| `describe-table` | Get column info, types, constraints, indexes |
| `create-table` | Create new tables with schema definition |

**Resources:**
- `db://schema/tables` — All table names
- `db://schema/full` — Complete schema for all tables
- `db://info` — Database path, size, config

**Environment Variables:**
- `MCP_DB_PATH` — Path to SQLite file (default: `./mcp-data.db`)

### @mcp-suite/web-scraper

Fetch and parse web pages using cheerio. No browser required.

| Tool | Description |
|------|-------------|
| `fetch-page` | Fetch page as text/html/markdown/metadata |
| `extract-links` | Extract links with internal/external filtering |
| `extract-text` | Extract text via CSS selectors |
| `search-in-page` | Search for text patterns with context |

**Resources:**
- `scraper://config` — Scraper configuration and limits

### @mcp-suite/shared

Shared utilities used by all servers.

| Module | Exports |
|--------|---------|
| `logger.ts` | `Logger`, `createLogger`, `LogLevel` — Structured JSON logging to stderr |
| `errors.ts` | `McpServerError`, `NotFoundError`, `ValidationError`, `AuthError`, `RateLimitError`, `ExternalServiceError`, `formatErrorResponse`, `withErrorHandling` |
| `types.ts` | `createTextResponse`, `createJsonResponse`, `createErrorResponse`, type definitions |
| `middleware.ts` | `withRetry`, `CircuitBreaker`, `createRequestContext`, `generateCorrelationId` |

## Design Patterns

### Repository Pattern (Database)

```mermaid
classDiagram
    class IDatabaseRepository {
        <<interface>>
        +listTables(includeRowCounts?) TableListResult
        +describeTable(tableName) TableSchema
        +createTable(tableName, columns, ifNotExists?) WriteResult
        +query(sql, params?, limit?) QueryResult
        +insert(table, data) BatchInsertResult
        +update(table, set, where, params?) WriteResult
        +delete(table, where, params?) WriteResult
    }

    class DatabaseRepository {
        -isReadOnlyQuery(sql) boolean
        -validateTableExists(table) void
        -validateWhereClause(where, operation) void
    }

    class queryTool
    class insertTool
    class updateTool
    class deleteTool

    IDatabaseRepository <|.. DatabaseRepository
    queryTool --> DatabaseRepository
    insertTool --> DatabaseRepository
    updateTool --> DatabaseRepository
    deleteTool --> DatabaseRepository
```

### Circuit Breaker (Shared Middleware)

```mermaid
stateDiagram-v2
    [*] --> CLOSED
    CLOSED --> OPEN : failure threshold reached
    OPEN --> HALF_OPEN : recovery time elapsed
    HALF_OPEN --> CLOSED : success
    HALF_OPEN --> OPEN : failure
    CLOSED --> CLOSED : success / below threshold
```

### Error Handling Flow

```mermaid
flowchart TD
    A[Tool Called] --> B{Execute}
    B -->|Success| C[createJsonResponse]
    B -->|Error| D{Error Type?}
    D -->|ValidationError| E[createErrorResponse<br/>400]
    D -->|NotFoundError| F[createErrorResponse<br/>404]
    D -->|RateLimitError| G[Retry with backoff]
    D -->|ExternalServiceError| H[Circuit Breaker check]
    D -->|Unknown Error| I[formatErrorResponse<br/>500]
    G -->|Max retries| I
    H -->|Circuit OPEN| J[Service unavailable]
    H -->|Circuit CLOSED| B
```

## Tech Stack

| Layer | Technology |
|-------|-----------|
| Language | TypeScript 5.x (strict mode) |
| MCP SDK | @modelcontextprotocol/sdk |
| Validation | Zod v3 |
| Transport | stdio (JSON-RPC 2.0) |
| AWS | AWS SDK v3 (modular clients) |
| Database | sql.js (pure JS SQLite) |
| Web Parsing | cheerio |
| Build | Turborepo monorepo |
| Test | Vitest |
| Module | ES2022 / Node16 resolution |

## Development

```bash
# Build all packages
npm run build

# Type check without emitting
npm run typecheck

# Run tests
npm run test

# Clean build artifacts
npm run clean
```

## Environment Variables

| Variable | Package | Description |
|----------|---------|-------------|
| `AWS_REGION` | aws-explorer | AWS region (default: us-east-1) |
| `AWS_PROFILE` | aws-explorer | AWS CLI profile name |
| `AWS_ACCESS_KEY_ID` | aws-explorer | AWS access key |
| `AWS_SECRET_ACCESS_KEY` | aws-explorer | AWS secret key |
| `MCP_DB_PATH` | database | SQLite file path |
| `MCP_LOG_LEVEL` | all | DEBUG, INFO, WARN, ERROR, SILENT |

## Cost

| Item | Cost |
|------|------|
| AWS SDK | $0 — read-only operations on existing resources |
| npm packages | All free/open-source |
| MCP SDK | Free & open-source |
| sql.js | Free (public domain SQLite) |
| Deployment | $0 — runs locally |

## License

MIT