Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,350 changes: 1,350 additions & 0 deletions development/backend/mcp-server-oauth.mdx

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion development/backend/oauth2-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ description: Developer guide for the OAuth2 authorization server that enables pr
sidebarTitle: OAuth2 Server
---

<Note>
**OAuth System Clarification**: DeployStack implements three distinct OAuth systems:

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).
1. **User → DeployStack OAuth** (Social Login) - See [OAuth Providers](/development/backend/oauth-providers)
2. **MCP Client → DeployStack OAuth** (API Access) - **This document** - How VS Code, Cursor, Claude.ai authenticate to satellite APIs
3. **User → MCP Server OAuth** (External Service Access) - See [MCP Server OAuth](/development/backend/mcp-server-oauth) - How users authorize Notion, Box, Linear

This document covers system #2 - the OAuth2 authorization server for MCP client authentication.
</Note>

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).

## Overview

Expand Down
27 changes: 27 additions & 0 deletions development/backend/satellite/events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,32 @@ Updates `satelliteProcesses` table when server exits unexpectedly.

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

#### mcp.server.status_changed
Updates `mcpServerInstallations` table when server status changes during installation, discovery, or health checks.

**Business Logic**: Tracks installation lifecycle from provisioning through discovery to online/error states. Enables frontend progress indicators and error visibility.

**Required Fields** (snake_case): `installation_id`, `team_id`, `status`, `timestamp`

**Optional Fields**: `status_message` (string, human-readable context or error details)

**Status Values**:
- `provisioning` - Installation created, waiting for satellite
- `command_received` - Satellite acknowledged install command
- `connecting` - Satellite connecting to MCP server
- `discovering_tools` - Tool discovery in progress
- `syncing_tools` - Sending discovered tools to backend
- `online` - Server healthy and responding
- `offline` - Server unreachable
- `error` - Connection failed with specific error
- `requires_reauth` - OAuth token expired/revoked
- `permanently_failed` - Process crashed 3+ times in 5 minutes

**Emission Points**:
- Success path: After successful tool discovery → status='online'
- Failure path: On connection errors → status='offline', 'error', or 'requires_reauth'
- Command processor: During installation steps → status='connecting', 'discovering_tools'

### Tool Execution

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

### Transaction Strategy
Expand Down
34 changes: 34 additions & 0 deletions development/frontend/architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ Create a new feature component directory when:
2. **Props Down, Events Up**: Maintain unidirectional data flow
3. **Composition Pattern**: Break complex components into smaller parts
4. **Self-Contained**: Components should work in isolation
5. **Empty States**: Always use the shadcn-vue Empty component for no-data states. Never create custom empty state markup with manual styling.

#### Exceptions to the Structure

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

### Backend API Environment Variables

Always use `VITE_DEPLOYSTACK_BACKEND_URL` for all backend API calls and SSE connections.

```bash
# .env.local
VITE_DEPLOYSTACK_BACKEND_URL=http://localhost:3000
```

**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.

```typescript
import { getEnv } from '@/utils/env'

// Service Layer
export class McpServerService {
private static baseUrl = getEnv('VITE_DEPLOYSTACK_BACKEND_URL')

static async getAllServers(): Promise<McpServer[]> {
const response = await fetch(`${this.baseUrl}/api/mcp-servers`)
if (!response.ok) {
throw new Error('Failed to fetch MCP servers')
}
return response.json()
}
}

// SSE Connections in Composables
const baseUrl = getEnv('VITE_DEPLOYSTACK_BACKEND_URL')
const url = `${baseUrl}/api/teams/${teamId}/status/stream`
const eventSource = new EventSource(url, { withCredentials: true })
```

### Using Services in Components

```vue
Expand Down
64 changes: 64 additions & 0 deletions development/frontend/ui/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,70 @@ Use Spinner for:
| Perceived speed | Feels faster | Can feel slower |
| Use case | Content loading | Action processing |

## Empty State Patterns

**MANDATORY**: Always use the shadcn-vue `Empty` component for no-data states. Never create custom empty state markup with manual styling.

### Basic Empty State

```vue
<script setup lang="ts">
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty'
import { Package } from 'lucide-vue-next'
</script>

<template>
<Empty v-if="!hasData">
<EmptyHeader>
<EmptyMedia variant="icon">
<Package />
</EmptyMedia>
<EmptyTitle>No data found</EmptyTitle>
<EmptyDescription>
There is currently no data to display.
</EmptyDescription>
</EmptyHeader>
</Empty>
</template>
```

### Empty State with Actions

```vue
<script setup lang="ts">
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent } from '@/components/ui/empty'
import { Button } from '@/components/ui/button'
import { Package, Plus } from 'lucide-vue-next'
</script>

<template>
<Empty v-if="!hasData">
<EmptyHeader>
<EmptyMedia variant="icon">
<Package />
</EmptyMedia>
<EmptyTitle>No items found</EmptyTitle>
<EmptyDescription>
Get started by creating your first item.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button @click="handleCreate">
<Plus class="h-4 w-4 mr-2" />
Create Item
</Button>
</EmptyContent>
</Empty>
</template>
```

Use Empty component for:
- No search results
- Empty data tables
- No tools/resources discovered
- Missing configuration items
- Any state where data is expected but not present

## Button Patterns

### Loading States
Expand Down
Loading
Loading