Operate

Optional integrations

Configure AI, MCP, OIDC, filesystem or S3-compatible storage without making them core dependencies.

v0.3.0 referenceReviewed

On this page

Core Hopya works with local accounts and filesystem storage—no AI, S3, SSO, telemetry, or vendor account required. Test optional integrations with your selected provider before production use.

AI Assistant

Operator secrets/settings belong only in the API environment.

AI Assistant: reference table
SettingContract
AI_PROVIDEREmpty disables assistant
AI_MODELSelected model
AI_BASE_URL, AI_API_KEYOptional provider configuration
AI_MAX_OUTPUT_TOKENSInteger 256–32,768; default 2,048; raising may increase cost
AI Assistant: reference table
ProviderDefault versioned baseRequest / output budget
openaihttps://api.openai.com/v1/chat/completions, bearer; max_completion_tokens, includes reasoning; store:false
anthropichttps://api.anthropic.com/v1/messages, x-api-key; max_tokens
googlehttps://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent, x-goog-api-key; generationConfig.maxOutputTokens
openai-compatibleOperator-supplied/chat/completions; optional local bearer; max_tokens

Base URLs include API version, not final method path. Local examples: http://model-server:8000/v1, http://ollama:11434/v1; verify the actual server. Groq/Mistral/DeepSeek may use their documented compatible base/model, but no endpoint/model version is guaranteed. Trusted private HTTP is allowed; remote credentials need HTTPS. Redirects are rejected; users/models cannot choose outbound URLs.

AI Assistant: reference table
Agent contractValue
EndpointPOST /api/v1/workspaces/:wid/agent
RequestStrict {message}, 1–8,000 characters
Permissionagent:use + items:read
Sent contextMessage + ≤100 recent task titles/statuses/priorities/dates + ≤100 list names/IDs
Not sentMember emails, descriptions, attachments, keys, other workspaces
Response{reply,proposal?}; proposal title, optional description, nodeId, dueDate, priority
ConversationSingle-turn; displayed history stays in browser memory, not stored/automatically resent
BoundsFour concurrent requests; 45 seconds for headers and body; bounded validated model JSON

The agent never mutates tasks. Review/edit the proposal and choose Confirm and create through ordinary validated REST. It cannot delete tasks, run shell commands, browse arbitrary URLs, or change permissions. Task-content prompt injection and model advice remain untrusted.

AI lifecycle, privacy, and provider compatibility
  • SQL selects bounded lightweight metadata, not whole-workspace data then slicing. List and current credentials/permissions are rechecked after provider wait before answer delivery/audit.
  • Audit records action/outcome only, never prompt/answer. Busy: 429, Retry-After: 1; provider timeout/failure: sanitized 502, no successful-answer audit.
  • Close/switch workspace aborts browser request. Detected client disconnect cancels provider HTTP/body and releases slot; normal POST-body completion is not disconnect. Controlled real-HTTP fixtures exercised these cases, not simulated clocks.
  • Cancellation cannot retract sent context, guarantee remote cancellation/billing cessation, or immediately stop remote work after revocation. Verify proxy disconnect propagation and provider policies.
  • Native OpenAI budgeting follows official SDK parameters, which deprecate max_tokens for reasoning models. store:false is not a zero-retention guarantee. Review privacy, retention, billing, and response/time bounds.

MCP

Hopya uses the official TypeScript MCP SDK v1. Both transports call the same REST permission boundary.

MCP: reference table
Transport / settingConfiguration
StdioHOPYA_API_URL (origin only), HOPYA_API_TOKEN; after npm ci and API build, run node apps/api/build/bin/mcp.js
SSEAdmin Site settings enables /api/v1/mcp/sse; disabled by default; personal bearer header only
Read toolslist_workspaces, get_workspace, list_items, get_item
Optional write toolscreate_item, update_item, delete_item; API/stdio process HOPYA_MCP_ALLOW_WRITES=true
SSE sessionsFour per user / 32 per instance; 30 minutes; disable closes them; message POSTs reauthenticate

Exposing tools does not approve writes. The MCP host must enforce human approval per mutation. Leave writes disabled if it cannot. Tool annotations are hints, not enforcement; REST RBAC/validation/version checks/revocation still apply.

MCP: reference table
Reader / client ruleContract
list_itemsOne {items,nextCursor} page; limit 1–500, default 200; existing filters + cursor
CompletionFollow non-null cursors with same filters; first page is not all tasks
Buffer boundAt most 4 MiB incoming UTF-8; cancel when exceeded; large individual records/metadata may need REST even at limit 1
Bound meaningResponse buffering, not total process memory or model context
IdentityDedicated minimally authorized account; tokens inherit all account permissions, no separate scopes
UpdatesExact expectedUpdatedAt to avoid stale writes
Secrets / stdoutPrivate client environment/secure headers; no token in args/URLs/logs/source; no non-protocol stdout wrappers

OIDC

See OIDC setup for a compatible provider. Operator owns provider deployment, recovery, MFA, and lifecycle policy.

OIDC: reference table
Configuration / routeContract
ProviderExact OIDC_ISSUER, client ID, provider-required secret; client_secret_post; HTTPS everywhere
Callback${APP_URL}/api/v1/auth/sso/callback
Flow routesGET /api/v1/auth/sso, then callback
ValidationPKCE S256, random state/nonce, hashed browser-bound cookie/state, ten-minute one-use expiry; SDK signature/issuer/audience checks
PersistenceNo tokens/claims persisted or logged; no request-selected redirect host
Provisioning defaultOIDC_AUTO_PROVISION=false; local admin setup first
JIT enabledValid verified non-colliding email → non-admin account, no existing membership; local registration separately controlled
Existing identityExact issuer/subject, not email; suspension blocks it; local logout is not IdP-wide logout

Matching email never links accounts automatically. Admin OIDC identities explicitly links independently verified issuer/subject. API: GET/POST /api/v1/admin/oidc-identities, DELETE /:id.

  • Unlink revokes all target sessions/tokens and blocks matching in-flight exchanges; protects last passwordless method.
  • A fresh verified-email JIT enrollment may still create a different non-admin account; unlink is not an upstream ban.
  • OIDC_ALLOW_INSECURE_HTTP=true is loopback-test-only and rejected in production, not an HTTPS workaround.

Attachments

Attachments: reference table
BackendConfiguration / obligations
FilesystemSTORAGE_DRIVER=filesystem; opaque private objects under DATA_DIR/objects
S3AWS default credential chain; S3_BUCKET, S3_REGION, optional S3_ENDPOINT, S3_FORCE_PATH_STYLE; bucket must exist and be private
S3 accessDedicated bucket, object get/put/delete only; no public ACL; trusted local HTTP allowed, remote TLS required
CompatibilityConditional writes and other SDK behavior vary; verify the actual service

Prefix: /api/v1/workspaces/:wid/items/:id/attachments.

Attachments: reference table
MethodPathContract
GETCollection{id,name,size,contentType,createdAt} metadata
POSTCollection{name,contentType,data} canonical base64; task read/write; decoded ≤10 MiB; JSON ≤15 MiB, proxy ≤20 MiB
GET/:attachmentIdAuthorized private bytes; forced attachment and nosniff, not inline HTML
DELETE/:attachmentIdTransactional metadata revocation; physical failure tracked with cleanupPending:true

Authorization is rechecked after storage waits. Filenames never become paths/keys. Failed uploads are compensated; uncertain writes/deleted-task objects use a durable ledger. Hourly bounded cleanup handles unreferenced objects older than 24 hours, ≤100 per run. Admin status exposes backlog; failed objects retry later.

Changing driver/bucket/endpoint is not migration. Objects record a backend fingerprint with no silent fallback. Preserve old settings, transfer/verify bytes before metadata changes, and back up S3 versions separately. Workspace export has metadata, not bytes/keys; follow full backup.

Body And Comment Images

Body And Comment Images: reference table
OperationContract (paths after /api/v1)
POST /workspaces/:wid/imagesBase64 file fields + kind (task-body, task-comment, document-comment) + resource ID; only new task body may omit resource
Upload resultPrivate url, downloadUrl, expiresAt; uploader-only pending preview; 24-hour expiry
Content saveValidate/claim references transactionally; body images become attachments
DELETE /workspaces/:wid/images/:imageIdCaller’s uncommitted draft only
Inline readsImage /:imageId/inline or attachment /inline; current owning-resource read; comment tombstones revoke images
Raster limitsPNG/JPEG/GIF/WebP, ≤10 MiB / 40 megapixels; MIME from bytes; nosniff, sandbox, private/no-store
RenderingOnly private image paths; remote tracking, arbitrary URLs, data URLs, SVG inert
Export v8Committed image ownership/attachment metadata, no bytes/drafts/keys; ordinary downloads forced attachments

See image and draft behavior for recovery and cleanup.

Verification Boundaries

Verification Boundaries: reference table
IntegrationApplication boundaryOperator verification
FilesystemPrivate keys, access checks, bounded uploads, deletion ledger/cleanupDisk monitoring, restore, sustained workload
S3Signed private requests, bounds, rechecks, tracked cleanupProvider/policy/versions/lifecycle/remote restore
OIDCPKCE/state/nonce, issuer-subject, local revocationAccess policy, MFA, recovery/logout/deprovisioning
AIBounded context/output, deadlines, rechecks, proposals onlyModel behavior, retention/cost/region, cancellation
MCPAuthenticated REST, read defaults, optional mutationsHost security, human approval of every write