aws-security-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -0
- package/dashboard/dist/assets/index-DCplBiuM.css +2 -0
- package/dashboard/dist/assets/index-jFq0Af8S.js +46 -0
- package/dashboard/dist/data.json +926 -0
- package/dashboard/dist/favicon.svg +1 -0
- package/dashboard/dist/icons.svg +24 -0
- package/dashboard/dist/index.html +14 -0
- package/dist/bin/aws-security-mcp.d.ts +1 -0
- package/dist/bin/aws-security-mcp.js +16057 -0
- package/dist/bin/aws-security-mcp.js.map +1 -0
- package/dist/src/commands/dashboard.d.ts +3 -0
- package/dist/src/commands/dashboard.js +90 -0
- package/dist/src/commands/dashboard.js.map +1 -0
- package/dist/src/commands/deploy-dashboard.d.ts +3 -0
- package/dist/src/commands/deploy-dashboard.js +117 -0
- package/dist/src/commands/deploy-dashboard.js.map +1 -0
- package/dist/src/index.d.ts +96 -0
- package/dist/src/index.js +15765 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# aws-security-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for automated AWS security scanning — 7 modules, risk scoring, zero write operations.
|
|
4
|
+
|
|
5
|
+
<!-- badges -->
|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **7 Security Scan Modules** — Security Groups, S3, IAM, CloudTrail, RDS, EBS, VPC
|
|
13
|
+
- **Risk Scoring** — every finding scored 0-10 with severity (CRITICAL/HIGH/MEDIUM/LOW) and priority (P0-P3)
|
|
14
|
+
- **100% Read-Only** — uses only Describe/Get/List API calls; never modifies your AWS resources
|
|
15
|
+
- **Parallel Execution** — all 7 modules run concurrently via `Promise.allSettled`
|
|
16
|
+
- **Markdown Report Generation** — structured report with executive summary, findings by severity, and prioritized recommendations
|
|
17
|
+
- **MCP Resources** — embedded security rules and risk scoring model documentation
|
|
18
|
+
- **MCP Prompts** — pre-built workflows for full scans and finding analysis
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### 1. Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install
|
|
26
|
+
npm run build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 2. Configure AWS Credentials
|
|
30
|
+
|
|
31
|
+
The server uses the standard AWS SDK credential chain. Any of the following will work:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Environment variables
|
|
35
|
+
export AWS_ACCESS_KEY_ID=AKIA...
|
|
36
|
+
export AWS_SECRET_ACCESS_KEY=...
|
|
37
|
+
export AWS_REGION=ap-northeast-1
|
|
38
|
+
|
|
39
|
+
# Or use an AWS profile
|
|
40
|
+
export AWS_PROFILE=your-profile
|
|
41
|
+
|
|
42
|
+
# Or run on an EC2 instance / ECS task with an IAM role attached
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
See [Recommended IAM Policy](#recommended-iam-policy) below for the minimum permissions required.
|
|
46
|
+
|
|
47
|
+
### 3. Configure Your AI Tool
|
|
48
|
+
|
|
49
|
+
Add the MCP server to your AI tool's configuration:
|
|
50
|
+
|
|
51
|
+
#### Kiro
|
|
52
|
+
|
|
53
|
+
`.kiro/settings/mcp.json`:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"aws-security": {
|
|
59
|
+
"command": "aws-security-mcp",
|
|
60
|
+
"args": ["--region", "ap-northeast-1"]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Claude Code
|
|
67
|
+
|
|
68
|
+
`.claude/settings.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"aws-security": {
|
|
74
|
+
"command": "aws-security-mcp",
|
|
75
|
+
"args": ["--region", "ap-northeast-1"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Cursor
|
|
82
|
+
|
|
83
|
+
Add in Cursor MCP settings:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"aws-security": {
|
|
89
|
+
"command": "aws-security-mcp",
|
|
90
|
+
"args": ["--region", "ap-northeast-1"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4. Use
|
|
97
|
+
|
|
98
|
+
Ask your AI tool to run a security scan:
|
|
99
|
+
|
|
100
|
+
> "Run a full AWS security scan and generate a report"
|
|
101
|
+
|
|
102
|
+
Or use the built-in `security-scan` prompt for a guided workflow.
|
|
103
|
+
|
|
104
|
+
## Available Tools
|
|
105
|
+
|
|
106
|
+
| Tool | Description |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| `scan_all` | Run all 7 security scanners in parallel |
|
|
109
|
+
| `scan_sg` | Scan EC2 security groups for overly permissive rules |
|
|
110
|
+
| `scan_s3` | Check S3 buckets for public access, encryption, versioning |
|
|
111
|
+
| `scan_iam` | Audit IAM users, root account, access keys, policies |
|
|
112
|
+
| `scan_cloudtrail` | Validate CloudTrail logging configuration |
|
|
113
|
+
| `scan_rds` | Scan RDS instances for public access, encryption, backups |
|
|
114
|
+
| `scan_ebs` | Check EBS volumes and snapshots for encryption and public sharing |
|
|
115
|
+
| `scan_vpc` | Review VPC flow logs, default VPC usage, default security groups |
|
|
116
|
+
| `generate_report` | Generate a Markdown report from scan results |
|
|
117
|
+
| `list_modules` | List available scan modules with descriptions |
|
|
118
|
+
|
|
119
|
+
All tools accept an optional `region` parameter (defaults to the server's configured region).
|
|
120
|
+
|
|
121
|
+
## Recommended IAM Policy
|
|
122
|
+
|
|
123
|
+
Attach this policy to the IAM user or role running the scanner. All actions are read-only.
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"Version": "2012-10-17",
|
|
128
|
+
"Statement": [
|
|
129
|
+
{
|
|
130
|
+
"Sid": "SecurityScannerReadOnly",
|
|
131
|
+
"Effect": "Allow",
|
|
132
|
+
"Action": [
|
|
133
|
+
"ec2:DescribeSecurityGroups",
|
|
134
|
+
"ec2:DescribeInstances",
|
|
135
|
+
"ec2:DescribeVolumes",
|
|
136
|
+
"ec2:DescribeSnapshots",
|
|
137
|
+
"ec2:DescribeSnapshotAttribute",
|
|
138
|
+
"ec2:GetEbsEncryptionByDefault",
|
|
139
|
+
"ec2:DescribeVpcs",
|
|
140
|
+
"ec2:DescribeFlowLogs",
|
|
141
|
+
|
|
142
|
+
"s3:ListAllMyBuckets",
|
|
143
|
+
"s3:GetBucketPublicAccessBlock",
|
|
144
|
+
"s3:GetBucketAcl",
|
|
145
|
+
"s3:GetBucketPolicy",
|
|
146
|
+
"s3:GetBucketPolicyStatus",
|
|
147
|
+
"s3:GetEncryptionConfiguration",
|
|
148
|
+
"s3:GetBucketVersioning",
|
|
149
|
+
|
|
150
|
+
"iam:GetAccountSummary",
|
|
151
|
+
"iam:ListUsers",
|
|
152
|
+
"iam:ListAccessKeys",
|
|
153
|
+
"iam:GetAccessKeyLastUsed",
|
|
154
|
+
"iam:ListAttachedUserPolicies",
|
|
155
|
+
"iam:GenerateCredentialReport",
|
|
156
|
+
"iam:GetCredentialReport",
|
|
157
|
+
|
|
158
|
+
"cloudtrail:DescribeTrails",
|
|
159
|
+
"cloudtrail:GetTrailStatus",
|
|
160
|
+
"cloudtrail:GetEventSelectors",
|
|
161
|
+
|
|
162
|
+
"rds:DescribeDBInstances",
|
|
163
|
+
|
|
164
|
+
"sts:GetCallerIdentity"
|
|
165
|
+
],
|
|
166
|
+
"Resource": "*"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Scan Modules
|
|
173
|
+
|
|
174
|
+
| Module | What It Checks | Risk Score Range |
|
|
175
|
+
|--------|---------------|-----------------|
|
|
176
|
+
| **Security Groups** | Open ports to 0.0.0.0/0 (SSH, RDP, databases), all-ports rules | 7.5 - 9.5 |
|
|
177
|
+
| **S3** | Public ACLs, public bucket policies, Block Public Access, encryption, versioning | 3.0 - 9.5 |
|
|
178
|
+
| **IAM** | Root MFA, root access keys, inactive users, old access keys, over-permissive policies | 5.0 - 10.0 |
|
|
179
|
+
| **CloudTrail** | Trail existence, multi-region logging, log validation, CloudWatch integration, management events | 5.5 - 9.5 |
|
|
180
|
+
| **RDS** | Public accessibility, storage encryption, backup retention, deletion protection | 4.0 - 8.0 |
|
|
181
|
+
| **EBS** | Default encryption, unencrypted volumes, unencrypted snapshots, public snapshots | 5.5 - 9.5 |
|
|
182
|
+
| **VPC** | Default VPC usage, VPC Flow Logs, default security group rules | 5.5 - 7.0 |
|
|
183
|
+
|
|
184
|
+
### Risk Scoring
|
|
185
|
+
|
|
186
|
+
| Score | Severity | Priority |
|
|
187
|
+
|-------|----------|----------|
|
|
188
|
+
| 9.0 - 10.0 | CRITICAL | P0 |
|
|
189
|
+
| 7.0 - 8.9 | HIGH | P1 |
|
|
190
|
+
| 4.0 - 6.9 | MEDIUM | P2 |
|
|
191
|
+
| 0.0 - 3.9 | LOW | P3 |
|
|
192
|
+
|
|
193
|
+
## Output Format
|
|
194
|
+
|
|
195
|
+
### Scan Results (JSON)
|
|
196
|
+
|
|
197
|
+
Each scan tool returns structured JSON:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"module": "security_group",
|
|
202
|
+
"status": "success",
|
|
203
|
+
"resourcesScanned": 12,
|
|
204
|
+
"findingsCount": 3,
|
|
205
|
+
"scanTimeMs": 1250,
|
|
206
|
+
"findings": [
|
|
207
|
+
{
|
|
208
|
+
"severity": "CRITICAL",
|
|
209
|
+
"title": "Security group sg-abc123 allows SSH (22) from 0.0.0.0/0",
|
|
210
|
+
"resourceType": "AWS::EC2::SecurityGroup",
|
|
211
|
+
"resourceId": "sg-abc123",
|
|
212
|
+
"resourceArn": "arn:aws:ec2:ap-northeast-1:123456789012:security-group/sg-abc123",
|
|
213
|
+
"region": "ap-northeast-1",
|
|
214
|
+
"description": "...",
|
|
215
|
+
"impact": "...",
|
|
216
|
+
"riskScore": 9.0,
|
|
217
|
+
"remediationSteps": ["..."],
|
|
218
|
+
"priority": "P0"
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Markdown Report
|
|
225
|
+
|
|
226
|
+
The `generate_report` tool produces a Markdown report with:
|
|
227
|
+
|
|
228
|
+
- **Executive Summary** — account, region, duration, finding counts by severity
|
|
229
|
+
- **Findings by Severity** — grouped and sorted by risk score
|
|
230
|
+
- **Scan Statistics** — per-module resource counts and status
|
|
231
|
+
- **Recommendations** — prioritized action items
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
MIT
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-tight:1.25;--radius-lg:.5rem;--ease-in:cubic-bezier(.4, 0, 1, 1);--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.right-0{right:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.table{display:table}.h-\[300px\]{height:300px}.h-screen{height:100vh}.min-h-screen{min-height:100vh}.w-64{width:calc(var(--spacing) * 64)}.w-full{width:100%}.flex-1{flex:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/30{border-color:color-mix(in oklab, var(--color-blue-500) 30%, transparent)}}.border-current{border-color:currentColor}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab, red, red)){.border-green-500\/30{border-color:color-mix(in oklab, var(--color-green-500) 30%, transparent)}}.border-orange-500\/30{border-color:#fe6e004d}@supports (color:color-mix(in lab, red, red)){.border-orange-500\/30{border-color:color-mix(in oklab, var(--color-orange-500) 30%, transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.border-red-500\/30{border-color:color-mix(in oklab, var(--color-red-500) 30%, transparent)}}.border-slate-700{border-color:var(--color-slate-700)}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/30{border-color:color-mix(in oklab, var(--color-yellow-500) 30%, transparent)}}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.bg-blue-500\/20{background-color:color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}.bg-green-500\/20{background-color:#00c75833}@supports (color:color-mix(in lab, red, red)){.bg-green-500\/20{background-color:color-mix(in oklab, var(--color-green-500) 20%, transparent)}}.bg-orange-500\/20{background-color:#fe6e0033}@supports (color:color-mix(in lab, red, red)){.bg-orange-500\/20{background-color:color-mix(in oklab, var(--color-orange-500) 20%, transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/20{background-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.bg-slate-800{background-color:var(--color-slate-800)}.bg-slate-800\/30{background-color:#1d293d4d}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/30{background-color:color-mix(in oklab, var(--color-slate-800) 30%, transparent)}}.bg-slate-800\/50{background-color:#1d293d80}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/50{background-color:color-mix(in oklab, var(--color-slate-800) 50%, transparent)}}.bg-slate-800\/80{background-color:#1d293dcc}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/80{background-color:color-mix(in oklab, var(--color-slate-800) 80%, transparent)}}.bg-slate-900{background-color:var(--color-slate-900)}.bg-yellow-500\/20{background-color:#edb20033}@supports (color:color-mix(in lab, red, red)){.bg-yellow-500\/20{background-color:color-mix(in oklab, var(--color-yellow-500) 20%, transparent)}}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-blue-400{color:var(--color-blue-400)}.text-green-400{color:var(--color-green-400)}.text-orange-400{color:var(--color-orange-400)}.text-red-400{color:var(--color-red-400)}.text-slate-50{color:var(--color-slate-50)}.text-slate-100{color:var(--color-slate-100)}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-yellow-400{color:var(--color-yellow-400)}.capitalize{text-transform:capitalize}.italic{font-style:italic}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:border-slate-500:hover{border-color:var(--color-slate-500)}.hover\:bg-slate-700\/50:hover{background-color:#31415880}@supports (color:color-mix(in lab, red, red)){.hover\:bg-slate-700\/50:hover{background-color:color-mix(in oklab, var(--color-slate-700) 50%, transparent)}}.hover\:text-slate-200:hover{color:var(--color-slate-200)}}@media (width>=40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=48rem){.md\:col-span-2{grid-column:span 2/span 2}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=64rem){.lg\:mt-0{margin-top:calc(var(--spacing) * 0)}.lg\:ml-64{margin-left:calc(var(--spacing) * 64)}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}}body{color:#f8fafc;background-color:#0f172a;margin:0;font-family:Inter,system-ui,-apple-system,sans-serif}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:#1e293b}::-webkit-scrollbar-thumb{background:#475569;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#64748b}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}
|