mrapids 0.1.31

Your OpenAPI, but executable
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# MCP Authentication Architecture

## Overview

This document describes the authentication architecture for the MCP (Model Context Protocol) server implementation in mrapids, following the **Semantic + Guidance** pattern with clean separation of concerns.

---

## Core Principle: Separation of Concerns

```
┌─────────────────────────────────────────────────────────────────────┐
│                        MCP SERVER (Orchestrator)                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  What MCP knows/provides:                                            │
│  ├── operation_id (from spec parsing)                                │
│  ├── parameters (from user/AI conversation)                          │
│  └── environment (from user: "dev", "staging", "prod")               │
│                                                                      │
│  What MCP does NOT do:                                               │
│  ├── Load config files with credentials                              │
│  ├── Resolve ${VAR} placeholders                                     │
│  ├── Cache or store credentials in memory                            │
│  └── Validate credential values                                      │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
                              │ subprocess (process isolation)
┌─────────────────────────────────────────────────────────────────────┐
│                     mrapids run (Executor)                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  Receives: mrapids run <operation> --env <environment> [--params]    │
│                                                                      │
│  Automatically handles:                                              │
│  ├── config/{env}.yaml  → base_url, auth schemes, headers            │
│  ├── env/.env.{env}     → actual secret values                       │
│  ├── ${VAR} resolution  → replaces placeholders with real values     │
│  └── Auth application   → adds headers/tokens to HTTP request        │
│                                                                      │
│  Process exits after request (credentials not persisted)             │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
```

---

## Authentication Sources (Three Layers)

### Layer 1: OpenAPI Spec (What auth the API SUPPORTS)

**Location**: `specs/api.yaml`

**Purpose**: Declares which authentication methods each endpoint requires.

```yaml
# OpenAPI 3.x
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

# Swagger 2.0
securityDefinitions:
  api_key:
    type: apiKey
    name: api_key
    in: header
  petstore_auth:
    type: oauth2
    flow: implicit
```

### Layer 2: Project Config (What auth you HAVE configured)

**Location**: `config/{environment}.yaml`

**Purpose**: Maps your credentials to auth schemes per environment.

```yaml
# config/development.yaml
base_url: http://localhost:3000
auth:
  preferred: bearer
  schemes:
    bearer:
      type: bearer
      token: ${DEV_API_TOKEN}
    apikey:
      type: apiKey
      in: header
      name: X-API-Key
      value: ${DEV_API_KEY}

# config/production.yaml
base_url: https://api.production.com
auth:
  preferred: bearer
  schemes:
    bearer:
      type: bearer
      token: ${PROD_API_TOKEN}
```

### Layer 3: Environment Secrets (Actual credential VALUES)

**Location**: `env/.env.{environment}`

**Purpose**: Stores actual secret values (NEVER committed to git).

```bash
# env/.env.development
DEV_API_TOKEN=dev-token-12345
DEV_API_KEY=dev-key-abcdef

# env/.env.production
PROD_API_TOKEN=prod-live-token-xyz789
```

---

## Semantic + Guidance Pattern for Auth

### What is Semantic?

**Semantic** = Understanding the complete meaning of an operation, including authentication requirements.

```
Without auth info (incomplete semantic):
┌─────────────────────────────────────┐
│ Operation: getPetById               │
│ Method: GET                         │
│ Path: /pet/{petId}                  │
│ Parameters: petId (required)        │
│ Auth: ??? (unknown)                 │
└─────────────────────────────────────┘

With auth info (complete semantic):
┌─────────────────────────────────────┐
│ Operation: getPetById               │
│ Method: GET                         │
│ Path: /pet/{petId}                  │
│ Parameters: petId (required)        │
│ Auth: api_key (header: api_key)     │  ← Complete understanding
└─────────────────────────────────────┘
```

### What is Guidance?

**Guidance** = Telling the AI what actions are possible and what's needed.

```
Without guidance (reactive):
api_show → "auth: required"
api_preview → creates token
api_run → 401 Unauthorized
AI: "Failed. Now what?"

With guidance (proactive):
api_show → "auth: api_key required"
         → "Status: NOT CONFIGURED for this environment"
         → "Next: mrapids auth connect api_key --env production"
AI: "I should tell user to configure auth first"
```

---

## Auth Detection vs Auth Validation

| Aspect | Auth Detection | Auth Validation |
|--------|---------------|-----------------|
| **What it does** | Shows what auth is required | Checks if credentials work |
| **Data source** | OpenAPI spec only | Makes actual API call |
| **Credentials needed** | No | Yes |
| **Safe for MCP** | Yes | No |
| **When to use** | Always (semantic info) | Only at execution time |

### MCP Should Do: Auth Detection

```json
{
  "auth": {
    "required": true,
    "schemes": [
      {
        "name": "api_key",
        "type": "apiKey",
        "location": "header",
        "header_name": "api_key"
      }
    ]
  }
}
```

### MCP Should NOT Do: Auth Validation

```
❌ Load ConfigLoader (credentials in memory)
❌ Check if ${VAR} resolves correctly
❌ Make test API calls to validate tokens
❌ Cache credential values
```

---

## MCP Tool Responsibilities

| Tool | MCP Provides | mrapids Handles |
|------|-------------|-----------------|
| `api_help` | - | - |
| `api_find` | query | Spec parsing |
| `api_show` | operation_id, environment | Auth requirements from spec |
| `api_query` | operation_id | Parameter details |
| `api_preview` | operation_id, params, environment | Preview token generation |
| `api_run` | preview_id, **environment** | Config loading, auth, HTTP |
| `api_auth` | environment | Config file existence check |

---

## Environment Flow

The **only** credential-related input from the Agent is the environment name:

```
┌─────────────────────────┐
│  Agent Decision:        │
│  "User wants production"│
│           │             │
│           ▼             │
│  environment = "prod"   │ ← This is ALL MCP passes
└─────────────────────────┘
┌─────────────────────────────────────────────────────┐
│  mrapids run getPetById --param petId=123 --env prod │
│                                                      │
│  Internally (subprocess):                            │
│  1. ConfigLoader::load("prod")                       │
│  2. Reads config/prod.yaml                           │
│  3. Reads env/.env.prod                              │
│  4. Resolves ${PROD_API_KEY} → "actual-secret"       │
│  5. Applies auth to request                          │
│  6. Sends HTTP request                               │
│  7. Returns response                                 │
│  8. Process exits (credentials gone from memory)     │
└─────────────────────────────────────────────────────┘
```

---

## api_show Response with Auth (Recommended)

```json
{
  "data": {
    "operation_id": "getPetById",
    "method": "GET",
    "path": "/pet/{petId}",
    "summary": "Find pet by ID",
    "parameters": [
      {
        "name": "petId",
        "location": "path",
        "type": "integer",
        "required": true
      }
    ],
    "auth": {
      "required": true,
      "schemes": [
        {
          "name": "api_key",
          "type": "apiKey",
          "location": "header",
          "header_name": "api_key",
          "description": "API key for authentication"
        }
      ]
    }
  },
  "guidance": {
    "ready": true,
    "blockers": [],
    "next_action": {
      "tool": "api_query",
      "params": {"operation_id": "getPetById"},
      "reason_code": "get_parameter_details"
    },
    "auth_hint": "Ensure config/{env}.yaml has 'api_key' scheme configured"
  }
}
```

---

## api_auth Response (Recommended)

```json
{
  "data": {
    "environment": "production",
    "config_exists": true,
    "available_schemes": ["bearer", "apikey"],
    "preferred_scheme": "bearer"
  },
  "guidance": {
    "ready": true,
    "message": "Auth is configured for 'production' environment",
    "next_action": {
      "tool": "api_find",
      "params": {"query": "your search term"},
      "reason_code": "start_discovery"
    }
  }
}
```

**Note**: `api_auth` checks file existence and YAML structure, NOT credential values.

---

## Security Architecture

### Why Subprocess Isolation?

```
┌─────────────────────────────────────────────────────────────────────┐
│                     MCP Server Process                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐              │
│  │ Spec Parser │  │ Preview     │  │ Guidance Engine │              │
│  │ (read-only) │  │ Tokens      │  │ (flow control)  │              │
│  └─────────────┘  └─────────────┘  └─────────────────┘              │
│                                                                      │
│  ❌ NO ConfigLoader                                                  │
│  ❌ NO credential resolution                                         │
│  ❌ NO secrets in memory                                             │
│  ✅ Spec parsing only                                                │
│  ✅ File existence checks only                                       │
└─────────────────────────────────────────────────────────────────────┘
                              │ subprocess (isolated process)
┌─────────────────────────────────────────────────────────────────────┐
│                   mrapids run (Short-lived)                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐              │
│  │ConfigLoader │→ │ Auth Apply  │→ │ HTTP Request    │              │
│  │(loads creds)│  │ (real vals) │  │ (sends request) │              │
│  └─────────────┘  └─────────────┘  └─────────────────┘              │
│                                                                      │
│  ✅ Loads credentials (short-lived in memory)                        │
│  ✅ Process exits after request                                      │
│  ✅ Credentials not persisted                                        │
└─────────────────────────────────────────────────────────────────────┘
```

### Benefits

| Aspect | Benefit |
|--------|---------|
| **Memory safety** | Credentials only in subprocess memory |
| **Process isolation** | MCP compromise doesn't expose secrets |
| **Short-lived** | Subprocess exits, credentials gone |
| **No caching** | Fresh credential load each time |
| **Rotation friendly** | Credential changes picked up immediately |

---

## Existing Commands for Auth

| Command | Description | Use Case |
|---------|-------------|----------|
| `mrapids auth detect` | Analyze spec auth requirements | Semantic info |
| `mrapids auth detect --operations` | Per-operation requirements | Detailed semantic |
| `mrapids auth detect --format json` | JSON output | MCP integration |
| `mrapids auth connect` | Configure credentials | User setup |
| `mrapids auth validate` | Test credentials | User verification |
| `mrapids auth list` | Show configured profiles | User info |

---

## Implementation Notes

### Current State

| Component | Status | Issue |
|-----------|--------|-------|
| `src/core/spec.rs` | ✅ Works | Used by `auth detect` |
| `src/core/parser.rs` | ❌ Incomplete | TODO for Swagger 2.0 security |
| `mcp.rs api_show` | ⚠️ Partial | Shows "See api_query" placeholder |
| `mcp.rs api_auth` | ⚠️ Subprocess | Could check file structure directly |

### Recommended Fix

MCP `api_show` should either:

1. **Option A**: Call `mrapids auth detect --format json` subprocess
2. **Option B**: Use `AuthDetector` from `src/core/auth/detection.rs` directly

Both options provide auth info without loading credentials.

---

## Summary

| Responsibility | Owner |
|---------------|-------|
| Environment selection | User → Agent → MCP |
| Auth requirements (semantic) | MCP (from spec) |
| Config file structure check | MCP (file existence only) |
| Config file location | mrapids (knows `.mrapids/` structure) |
| Secret resolution | mrapids (ConfigLoader in subprocess) |
| Auth application | mrapids (run command) |
| API execution | mrapids |

**Key Principle**: MCP provides `--env {environment}`. mrapids handles everything else.