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
5 changes: 5 additions & 0 deletions app/.dev.vars.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ SESSION_SECRET=""
# OIT API store credentials (ActiveDirectory subscription) for alias->netid.
OIT_CONSUMER_KEY=""
OIT_CONSUMER_SECRET=""
# Google Calendar MCP (dev needs its own OAuth client with a
# http://localhost:5173/oauth/google/callback redirect URI).
GOOGLE_OAUTH_CLIENT_ID=""
GOOGLE_OAUTH_CLIENT_SECRET=""
APP_ORIGIN=""
8 changes: 8 additions & 0 deletions app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ browser (React + useAgentChat over WebSocket)
full-page weekly Planner, an Agenda, and My apps. Design system in
`src/client/styles.css`; official TigerApps logos in `public/logos/`.

- **Google Calendar**: connects to Google's hosted Calendar MCP server with
read-only scopes via OAuth (`src/server/gcal.ts`). The client is
pre-registered in Google Cloud; consent runs once from *My apps* against
the user's desk DO, which stores the tokens and shares them with that
user's chats. Requires the `GOOGLE_OAUTH_CLIENT_ID` var, the
`GOOGLE_OAUTH_CLIENT_SECRET` secret, and an authorized redirect URI of
`<origin>/oauth/google/callback` on the OAuth client.

## Develop

```bash
Expand Down
9 changes: 0 additions & 9 deletions app/dev-grid.html

This file was deleted.

7 changes: 7 additions & 0 deletions app/public/logos/googlecalendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 0 additions & 10 deletions app/src/client/dev-grid.tsx

This file was deleted.

1 change: 1 addition & 0 deletions app/src/client/lib/desk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { userInstance } from "./auth";
export type DeskState = {
settings: PiSettings | null;
appErrors: Partial<Record<AppKey, string>>;
authUrls?: Partial<Record<AppKey, string>>;
};

export type McpServersSnapshot = {
Expand Down
1 change: 1 addition & 0 deletions app/src/client/lib/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,4 +485,5 @@ export const APP_INK: Record<AppKey, string> = {
princetoncourses: "var(--hl-orange)",
path: "var(--hl-violet)",
snatch: "var(--hl-pink)",
gcal: "var(--hl-mint)",
};
11 changes: 11 additions & 0 deletions app/src/client/pages/AppsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export function AppsPage({
}

function statusFor(key: AppKey): { text: string; cls: string } {
if (desk.deskState?.authUrls?.[key]) {
return { text: "one step left", cls: "status" };
}
const err = desk.deskState?.appErrors?.[key];
if (err) return { text: `couldn't connect — ${err}`, cls: "status err" };
const server = desk.mcp?.servers?.[key];
Expand Down Expand Up @@ -109,6 +112,14 @@ export function AppsPage({
<p className="adetail">{app.detail}</p>
<div className="foot">
<span className={status.cls}>{status.text}</span>
{on && desk.deskState?.authUrls?.[app.key] && (
<a
className="cta"
href={desk.deskState.authUrls[app.key]}
>
Connect with Google →
</a>
)}
<button
className={on ? "toggle on" : "toggle"}
role="switch"
Expand Down
Loading
Loading