@srfgg/sdk
v1.2.0
Published
srf.gg platform SDK — user identity, OAuth tokens, storage, email, and background jobs for managed apps
Maintainers
Readme
@srfgg/sdk
Platform SDK for apps managed by srf.gg. Provides user identity and OAuth token access that works identically in local development and remote deployment.
Install
npm install @srfgg/sdkUser Identity
import { getUser } from '@srfgg/sdk';
app.get('/dashboard', (req, res) => {
const user = getUser(req);
if (!user) return res.status(401).json({ error: 'Not authenticated' });
// user.id — srf.gg user UUID
// user.email — user's email
// user.name — user's display name
});getUser() works with any Node.js HTTP framework — Express, Fastify, Next.js API routes, raw http.createServer.
How it works:
- Deployed on srf.gg: The platform proxy injects
X-SRF-User-Id/Email/Nameheaders on every request - Local dev (srf start / desktop app): The same values are injected as
SRF_USER_ID/EMAIL/NAMEenvironment variables - The SDK reads headers first, falls back to env vars — same code, both environments
OAuth Tokens
Get fresh access tokens for third-party providers (Google, Microsoft, etc.). The platform handles the entire OAuth flow, token storage, encryption, and automatic refresh.
import { getUser, getTokens } from '@srfgg/sdk';
app.get('/calendars', async (req, res) => {
const tokens = await getTokens(req, 'google');
// tokens = [{ access_token, email, label, connection_id, ... }]
// One entry per connected Google account (work, personal, etc.)
const allEvents = [];
for (const t of tokens) {
const calRes = await fetch(
'https://www.googleapis.com/calendar/v3/calendars/primary/events',
{ headers: { Authorization: `Bearer ${t.access_token}` } }
);
allEvents.push({ account: t.email, events: (await calRes.json()).items });
}
res.json(allEvents);
});Setup
- Enable auth: call
srf_auth_enable(MCP tool) or enable in Project Settings - Declare provider requirements: call
srf_oauth_requirewith provider, scopes, and reason - An org admin must configure the OAuth provider in Admin > OAuth Providers
- Users connect their accounts in Settings > Connected Accounts
Token Object
{
access_token: string; // Fresh OAuth access token
email: string | null; // Provider account email
label: string | null; // User-assigned label ("Work", "Personal")
connection_id: string; // Unique connection identifier
provider: string; // Provider slug ("google")
provider_account_id: string;// Provider's unique account ID
expires_at: string; // ISO timestamp
scopes: string | null; // Granted OAuth scopes
}Caching
Tokens are cached in memory for 5 minutes per user+provider. To bypass:
const tokens = await getTokens(req, 'google', { cache: false });To clear the cache (e.g., after a user connects a new account):
import { clearTokenCache } from '@srfgg/sdk';
clearTokenCache();Scripts, workers, and cron jobs
getTokens(req, …) reads the user from an HTTP request. For contexts
without a req — startup scripts, background workers, cron jobs, CLI
tools — use getTokensForUser:
import { getTokensForUser } from '@srfgg/sdk';
// In a worker process
const uid = process.env.SRF_USER_ID; // injected by srf start / platform
const [google] = await getTokensForUser(uid, 'google');
await fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
headers: { Authorization: `Bearer ${google.access_token}` },
});Omitting the first argument is equivalent to process.env.SRF_USER_ID:
const tokens = await getTokensForUser(undefined, 'slack');Local dev — desktop broker
When running via srf start with the srf desktop app open, the SDK
automatically routes token fetches through a loopback server the desktop
runs on 127.0.0.1. Benefits:
- Your project's client secret never needs to leave the desktop process.
- The desktop can surface UI prompts if a token fetch requires consent.
Detection is automatic — no config, no env var. If the desktop isn't running, the SDK falls back to the direct platform call without any behavior change for the caller.
Check Provider Availability
import { hasProvider } from '@srfgg/sdk';
// Returns true if the user has an active Google connection
// (reads X-SRF-Has-Google header, only available when deployed)
if (hasProvider(req, 'google')) {
// show calendar features
}Error Handling
The SDK throws descriptive errors:
| Error | Cause |
|-------|-------|
| No authenticated user | Auth not enabled, or not running via srf start |
| Missing SRF_AUTH_URL... | Auth credentials not configured |
| Rate limited | >60 requests/min per user+provider |
| Token fetch failed (403) | Provider not declared, or user hasn't consented |
| Token fetch failed (404) | User hasn't connected this provider |
Environment Variables
These are injected automatically — you never set them manually.
| Variable | Set by | Purpose |
|----------|--------|---------|
| SRF_AUTH_URL | Platform | Base URL for token API |
| SRF_AUTH_CLIENT_ID | Platform | Project OAuth client ID |
| SRF_AUTH_CLIENT_SECRET | Platform | Project OAuth client secret |
| SRF_USER_ID | srf start / desktop | Local dev user identity |
| SRF_USER_EMAIL | srf start / desktop | Local dev user email |
| SRF_USER_NAME | srf start / desktop | Local dev user name |
License
MIT
