Skip to content

Commit 8cfd64b

Browse files
authored
Merge pull request #313 from deploystackio/feat/oauth
Add documentation for MCP Server OAuth Token Injection process
2 parents f2c710c + e6f7b0a commit 8cfd64b

File tree

9 files changed

+2348
-4
lines changed

9 files changed

+2348
-4
lines changed

development/backend/mcp-server-oauth.mdx

Lines changed: 1350 additions & 0 deletions
Large diffs are not rendered by default.

development/backend/oauth2-server.mdx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,17 @@ description: Developer guide for the OAuth2 authorization server that enables pr
44
sidebarTitle: OAuth2 Server
55
---
66

7+
<Note>
8+
**OAuth System Clarification**: DeployStack implements three distinct OAuth systems:
79

8-
This document describes the OAuth2 authorization server implementation in the DeployStack backend, which enables CLI tools and applications to access APIs using Bearer tokens. For general authentication, see [Backend Authentication System](/development/backend/auth). For OAuth provider integration (social login), see [Providers OAuth Implementation](/development/backend/oauth-providers).
10+
1. **User → DeployStack OAuth** (Social Login) - See [OAuth Providers](/development/backend/oauth-providers)
11+
2. **MCP Client → DeployStack OAuth** (API Access) - **This document** - How VS Code, Cursor, Claude.ai authenticate to satellite APIs
12+
3. **User → MCP Server OAuth** (External Service Access) - See [MCP Server OAuth](/development/backend/mcp-server-oauth) - How users authorize Notion, Box, Linear
13+
14+
This document covers system #2 - the OAuth2 authorization server for MCP client authentication.
15+
</Note>
16+
17+
This document describes the OAuth2 authorization server implementation in the DeployStack backend, which enables CLI tools and applications to access APIs using Bearer tokens. For general authentication, see [Backend Authentication System](/development/backend/auth).
918

1019
## Overview
1120

development/backend/satellite/events.mdx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,32 @@ Updates `satelliteProcesses` table when server exits unexpectedly.
188188

189189
**Optional Fields**: None (all fields required for proper crash tracking)
190190

191+
#### mcp.server.status_changed
192+
Updates `mcpServerInstallations` table when server status changes during installation, discovery, or health checks.
193+
194+
**Business Logic**: Tracks installation lifecycle from provisioning through discovery to online/error states. Enables frontend progress indicators and error visibility.
195+
196+
**Required Fields** (snake_case): `installation_id`, `team_id`, `status`, `timestamp`
197+
198+
**Optional Fields**: `status_message` (string, human-readable context or error details)
199+
200+
**Status Values**:
201+
- `provisioning` - Installation created, waiting for satellite
202+
- `command_received` - Satellite acknowledged install command
203+
- `connecting` - Satellite connecting to MCP server
204+
- `discovering_tools` - Tool discovery in progress
205+
- `syncing_tools` - Sending discovered tools to backend
206+
- `online` - Server healthy and responding
207+
- `offline` - Server unreachable
208+
- `error` - Connection failed with specific error
209+
- `requires_reauth` - OAuth token expired/revoked
210+
- `permanently_failed` - Process crashed 3+ times in 5 minutes
211+
212+
**Emission Points**:
213+
- Success path: After successful tool discovery → status='online'
214+
- Failure path: On connection errors → status='offline', 'error', or 'requires_reauth'
215+
- Command processor: During installation steps → status='connecting', 'discovering_tools'
216+
191217
### Tool Execution
192218

193219
#### mcp.tool.executed
@@ -311,6 +337,7 @@ Events route to existing business tables based on their purpose:
311337
|-----------|----------------|--------|
312338
| `mcp.server.started` | `satelliteProcesses` | Update status='running', set start time |
313339
| `mcp.server.crashed` | `satelliteProcesses` | Update status='failed', log error details |
340+
| `mcp.server.status_changed` | `mcpServerInstallations` | Update status, status_message, status_updated_at |
314341
| `mcp.tool.executed` | `satelliteUsageLogs` | Insert usage record with metrics |
315342

316343
### Transaction Strategy

development/frontend/architecture.mdx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ Create a new feature component directory when:
175175
2. **Props Down, Events Up**: Maintain unidirectional data flow
176176
3. **Composition Pattern**: Break complex components into smaller parts
177177
4. **Self-Contained**: Components should work in isolation
178+
5. **Empty States**: Always use the shadcn-vue Empty component for no-data states. Never create custom empty state markup with manual styling.
178179

179180
#### Exceptions to the Structure
180181

@@ -391,6 +392,39 @@ const data = await apiClient.get('/api/servers')
391392
5. **Consistent Naming**: Use descriptive method names (e.g., `getAllServers`, `createCategory`)
392393
6. **Base URL**: Always use environment variables for API endpoints
393394

395+
### Backend API Environment Variables
396+
397+
Always use `VITE_DEPLOYSTACK_BACKEND_URL` for all backend API calls and SSE connections.
398+
399+
```bash
400+
# .env.local
401+
VITE_DEPLOYSTACK_BACKEND_URL=http://localhost:3000
402+
```
403+
404+
**Usage**: DeployStack has a single backend API endpoint. Use `getEnv('VITE_DEPLOYSTACK_BACKEND_URL')` for all API calls, SSE connections, and WebSocket connections to the backend.
405+
406+
```typescript
407+
import { getEnv } from '@/utils/env'
408+
409+
// Service Layer
410+
export class McpServerService {
411+
private static baseUrl = getEnv('VITE_DEPLOYSTACK_BACKEND_URL')
412+
413+
static async getAllServers(): Promise<McpServer[]> {
414+
const response = await fetch(`${this.baseUrl}/api/mcp-servers`)
415+
if (!response.ok) {
416+
throw new Error('Failed to fetch MCP servers')
417+
}
418+
return response.json()
419+
}
420+
}
421+
422+
// SSE Connections in Composables
423+
const baseUrl = getEnv('VITE_DEPLOYSTACK_BACKEND_URL')
424+
const url = `${baseUrl}/api/teams/${teamId}/status/stream`
425+
const eventSource = new EventSource(url, { withCredentials: true })
426+
```
427+
394428
### Using Services in Components
395429

396430
```vue

development/frontend/ui/index.mdx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,70 @@ Use Spinner for:
360360
| Perceived speed | Feels faster | Can feel slower |
361361
| Use case | Content loading | Action processing |
362362

363+
## Empty State Patterns
364+
365+
**MANDATORY**: Always use the shadcn-vue `Empty` component for no-data states. Never create custom empty state markup with manual styling.
366+
367+
### Basic Empty State
368+
369+
```vue
370+
<script setup lang="ts">
371+
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty'
372+
import { Package } from 'lucide-vue-next'
373+
</script>
374+
375+
<template>
376+
<Empty v-if="!hasData">
377+
<EmptyHeader>
378+
<EmptyMedia variant="icon">
379+
<Package />
380+
</EmptyMedia>
381+
<EmptyTitle>No data found</EmptyTitle>
382+
<EmptyDescription>
383+
There is currently no data to display.
384+
</EmptyDescription>
385+
</EmptyHeader>
386+
</Empty>
387+
</template>
388+
```
389+
390+
### Empty State with Actions
391+
392+
```vue
393+
<script setup lang="ts">
394+
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent } from '@/components/ui/empty'
395+
import { Button } from '@/components/ui/button'
396+
import { Package, Plus } from 'lucide-vue-next'
397+
</script>
398+
399+
<template>
400+
<Empty v-if="!hasData">
401+
<EmptyHeader>
402+
<EmptyMedia variant="icon">
403+
<Package />
404+
</EmptyMedia>
405+
<EmptyTitle>No items found</EmptyTitle>
406+
<EmptyDescription>
407+
Get started by creating your first item.
408+
</EmptyDescription>
409+
</EmptyHeader>
410+
<EmptyContent>
411+
<Button @click="handleCreate">
412+
<Plus class="h-4 w-4 mr-2" />
413+
Create Item
414+
</Button>
415+
</EmptyContent>
416+
</Empty>
417+
</template>
418+
```
419+
420+
Use Empty component for:
421+
- No search results
422+
- Empty data tables
423+
- No tools/resources discovered
424+
- Missing configuration items
425+
- Any state where data is expected but not present
426+
363427
## Button Patterns
364428

365429
### Loading States

0 commit comments

Comments
 (0)