> ## Documentation Index
> Fetch the complete documentation index at: https://docs.toolshed.philo.ventures/llms.txt
> Use this file to discover all available pages before exploring further.

# Web App

> The Toolshed web dashboard for managing tools, authorizations, and MCP endpoints.

The Toolshed web app is a Vite + React application at `apps/web/` that provides a browser-based interface for managing your Toolshed configuration.

## Running locally

```bash theme={null}
# Start the server (requires .env.local with credentials)
pnpm --filter @toolshed/server dev

# Start the web app
pnpm --filter @toolshed/web dev
```

The web app runs at `http://localhost:5173` and connects to the server at `http://localhost:3000`.

## Authentication

Users sign in via email/password or Google OAuth. Only `@philo.ventures` email addresses are allowed. Authentication is handled by [Better Auth](/server/auth) with session cookies.

The login page features a split layout with the auth form on the left and an animated WebGL gradient on the right.

## Dashboard tabs

### Tools

Three sections for managing tool connections:

* **Personal tools** — each user connects their own account (GitHub, Google, Granola Personal)
* **Team tools** — shared across the org (Slack, Linear, QuickBooks, DocuSign, Carta, **Google Cloud**, Granola Enterprise)
* **Built-in tools** — ready-to-use tools with on/off toggles (Attio, Browserbase, Cloudflare Markdown Fetch, SEC Edgar, Firecrawl, Perplexity)

#### Connector availability filter

On every dashboard mount, the page calls [`GET /api/connectors/availability`](/server/connectors) and **hides any tile whose underlying creds aren't configured on the server**. So if `SLACK_CLIENT_ID` is empty, the Slack tile won't appear at all (rather than showing a broken Connect button). This keeps the UI honest about what's actually wired up.

#### Connect button dispatch

The Connect button branches by tile category:

* `apiKeyAuth: true` tiles (granola personal/enterprise) open the API-key paste dialog and store the secret encrypted in `tool_connections`.
* OAuth tiles dispatch by provider id: `github`/`google`/`slack`/`linear` use `authClient.signIn.social({ provider })` (Better Auth social), and the rest (`quickbooks`/`gcp`/`docusign`/`carta`) use `authClient.signIn.oauth2({ providerId })` (Better Auth `genericOAuth` plugin).

Multi-instance tools (GitHub orgs, Linear workspaces) support multiple connections through the multi-instance dialog and per-row management.

### Authorizations

Per-action permission controls for every tool. Each action can be set to:

* **Allow** — execute without confirmation
* **Ask** — pause and request user approval
* **Deny** — block execution

### MCP URLs

Create and manage MCP endpoints for connecting AI tools (Claude, Cursor, etc.) to Toolshed. Each endpoint gets a unique `ts_mcp_` token with:

* Stdio config (JSON for `claude_desktop_config.json` or `.cursor/mcp.json`)
* HTTP endpoint URL

## Tech stack

* **Vite** + **React** + **TypeScript**
* **shadcn/ui** (`@base-ui/react` primitives, with the `render` prop where shadcn would normally pass `asChild`) and custom Philo brand palette
* **Tailwind CSS v4**
* **GT Sectra Display** (headings) + **IBM Plex Sans** (body) + **IBM Plex Mono** (code)
* **Shiki** for syntax highlighting
* **WebGL** animated mesh gradient on auth pages
