From 00da67c7c5c036de6e897963b1324c54c824a90f Mon Sep 17 00:00:00 2001
From: "Griffin (AI)"
Date: Sun, 20 Sep 2026 06:18:09 -0700
Subject: [PATCH 1/6] plugin update
---
AGENTS.md | 21 +++
README.md | 17 +-
documents/expert-system-mcp-oauth-plan.md | 198 ++++++++++++++++++++++
documents/expert-system-plugin-plan.md | 116 +++++++++++++
public/marketplace.json | 20 ++-
public/privacy.html | 145 ++++++++++++++++
public/terms.html | 127 ++++++++++++++
src/routes/api/v1.docs.ts | 2 +-
src/routes/index.tsx | 49 ++++--
9 files changed, 673 insertions(+), 22 deletions(-)
create mode 100644 documents/expert-system-mcp-oauth-plan.md
create mode 100644 documents/expert-system-plugin-plan.md
create mode 100644 public/privacy.html
create mode 100644 public/terms.html
diff --git a/AGENTS.md b/AGENTS.md
index af5934a..0e6e9cb 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -24,3 +24,24 @@ The route tree (`src/routeTree.gen.ts`) is auto-generated by the TanStack Router
## Database schema changes
During development, apply schema changes using `bun run db:push` (`drizzle-kit push`) instead of generating migrations. Do **not** run `drizzle-kit generate` or `drizzle-kit migrate` while iterating on schema changes. Migrations should only be generated once, right before submitting the PR.
+
+## Server–plugin synchronization
+
+Expert System is maintained in two repositories, normally checked out as siblings:
+
+- `expert-system` owns the MCP server, OAuth, tool schemas and response semantics, website, and public privacy/terms pages.
+- `expert-system-plugin` owns the plugin manifests, shared skills, installation documentation, packaging tests, and plugin releases. Do not duplicate the plugin package in the server repository.
+
+When changing MCP tool names, arguments, responses, errors, limits, pagination, units, fiscal-period semantics, endpoint URLs, or OAuth requirements, inspect the corresponding code and instructions in **both** repositories. Update affected plugin skills, `agents/openai.yaml` dependencies, manifests, tests, and documentation together with server changes. The server contract is defined by `src/server/mcp/tools.ts` and its referenced schemas/operations; do not infer it from stale skill text.
+
+The plugin's `.claude-plugin/marketplace.json` is canonical. Keep the server's `public/marketplace.json` identical whenever plugin versions, descriptions, or source references change. Keep identity and version metadata synchronized across the plugin's portable, Claude, and Codex manifests; transport declarations must point to the same MCP endpoint. Policy URLs in plugin metadata must correspond to pages hosted by the server.
+
+For changes affecting this shared contract or a plugin release, run this command **from the plugin repository**, in addition to each repository's relevant checks:
+
+```bash
+EXPERT_SYSTEM_SERVER_ROOT=../expert-system bun run plugin:check
+```
+
+Use the actual server checkout path if the repositories are not siblings. The cross-repository test is skipped when `EXPERT_SYSTEM_SERVER_ROOT` is unset; a standalone green run is not synchronization validation. The check verifies tool names, marketplace parity, and policy files, but does not validate argument/response semantics or live OAuth behavior. Review affected schemas and workflows and run relevant server tests; perform client smoke tests when connection or packaging behavior changes. Update contract assertions only for intentional changes, never merely to make drift checks pass.
+
+Preserve compatibility with already-installed plugin versions where possible. For breaking changes, document the required plugin version and rollout order in `documents/plugin-release.md` in the plugin repository. If work spans both repositories, link the companion PRs and report checks for each. If a companion checkout is unavailable, report the synchronization work and checks still needed; do not claim the change is release-ready.
diff --git a/README.md b/README.md
index 2f9df1b..7cb6635 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,19 @@
-# STΛR MODΞ 🦨
+# Expert System
-Production deployment: https://sworks.starmode.app/
+Backend and website for Expert System research, macroeconomic data, and company financials.
+
+Production: [expert-system.starmode.dev](https://expert-system.starmode.dev).
+
+## Agent plugin
+
+The Claude Code and Codex plugin is maintained and released in
+[expert-system-plugin](https://github.com/starmode-base/expert-system-plugin).
+See that repository for installation, shared skills, manifests, and release checks.
+This repository owns the MCP server, OAuth, website, and public privacy/terms pages.
+
+The hosted `public/marketplace.json` is a compatibility copy of the plugin repo's
+`.claude-plugin/marketplace.json`. When releasing the plugin, update this copy and
+run its cross-repository check with `EXPERT_SYSTEM_SERVER_ROOT` pointing here.
## Contributing
diff --git a/documents/expert-system-mcp-oauth-plan.md b/documents/expert-system-mcp-oauth-plan.md
new file mode 100644
index 0000000..691b7d4
--- /dev/null
+++ b/documents/expert-system-mcp-oauth-plan.md
@@ -0,0 +1,198 @@
+# Auth0 OAuth 2.1 for the Expert System MCP
+
+## Summary
+
+Replace Clerk with Auth0 across the application, then expose `/api/mcp` as an
+OAuth-only MCP resource server. REST API keys remain supported, but MCP clients
+authenticate through Auth0 using Authorization Code + PKCE.
+
+Auth0 is preferred because its MCP support, CIMD registration, and RFC 8707
+resource handling are generally available, while the repository's Clerk
+integration is outdated and Clerk CIMD remains beta. This follows the
+[OpenAI OAuth guidance](https://developers.openai.com/plugins/build/auth),
+[current MCP authorization specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization),
+[Claude Code OAuth behavior](https://code.claude.com/docs/en/mcp), and
+[Auth0 Auth for MCP](https://auth0.com/ai/docs/mcp/overview).
+
+OAuth interoperability is the release gate for the plugin plan in
+[`expert-system-plugin-plan.md`](./expert-system-plugin-plan.md).
+
+## Implementation Changes
+
+### 1. Replace Clerk application authentication
+
+- Remove `@clerk/tanstack-start`, `ClerkProvider`, Clerk UI components,
+ `createClerkHandler`, and Clerk-specific middleware.
+- Configure one Auth0 tenant per stable environment and create:
+ - A first-party Regular Web Application for the Expert System website.
+ - An Auth0 API whose identifier is the canonical MCP URL, such as
+ `https://expert-system.starmode.dev/api/mcp`.
+- Use `openid-client` for the server-side web authorization-code flow instead
+ of turning the application into a browser-only SPA:
+ - `/api/auth/login` generates `state`, `nonce`, and an S256 PKCE verifier.
+ - `/api/auth/callback` validates the transaction, exchanges the code,
+ validates the ID token, upserts the user, rotates the local session, and
+ redirects to the original safe same-origin path.
+ - `/api/auth/logout` revokes the local session, clears the cookie, and
+ redirects through Auth0 logout.
+- Store opaque web-session tokens in an HttpOnly, Secure, SameSite=Lax cookie.
+ Store only a SHA-256 token hash in a new `auth_sessions` table, with user,
+ Auth0 `sid`, expiry, and revocation timestamps.
+- Add an Auth0 back-channel logout endpoint that validates signature, issuer,
+ audience, events, `sid`/`sub`, and absence of `nonce`, then revokes matching
+ local sessions.
+- Replace Clerk UI helpers with root-loader authentication state and local
+ sign-in/sign-out links. Preserve the existing protected-page behavior.
+- Replace the hard-coded Clerk developer identity with a `DEV_AUTH0_SUBJECT`
+ environment variable.
+- Replace reuse of `CLERK_SECRET_KEY` for X OAuth cookie encryption with a
+ dedicated `APP_COOKIE_SECRET`.
+
+### 2. Reset and normalize application identities
+
+- Replace `users.clerkUserId` with a unique `users.auth0Subject`.
+- Add nullable `displayName`; allow `email` to be initially nullable because an
+ MCP access token is only required to supply a stable `sub`.
+- Web login requires and synchronizes a verified email before creating a web
+ session. MCP-only users can be provisioned from `sub` and enriched when they
+ later use the website.
+- Keep the existing internal `users.id` as the stable identity for quota,
+ Stripe, API keys, organizations, and the MCP profile tool.
+- Update the shared auth middleware to resolve an active local session, load the
+ internal user, and expose the same `viewer` contract expected by existing
+ server functions.
+- Reset user-linked development data during the schema transition, as
+ authorized. Use `bun run db:push` while iterating and generate the final
+ migration only immediately before the PR.
+
+### 3. Configure Auth0 for MCP
+
+- Enable Auth0's Resource Parameter Compatibility Profile so the MCP `resource`
+ parameter maps to the registered MCP API audience.
+- Define one API permission: `expert-system:read`.
+- Require RS256, Authorization Code + S256 PKCE, explicit consent, short-lived
+ access tokens, and rotating refresh tokens.
+- Prefer CIMD:
+ - Pre-register the published OpenAI and Claude client metadata documents after
+ validating their redirect URIs and metadata.
+ - Advertise CIMD support through Auth0.
+- Enable DCR only as a compatibility fallback for older clients. Treat it as a
+ public registration endpoint: apply Auth0 third-party application controls,
+ require consent, monitor registrations, and periodically remove abandoned
+ clients.
+- Use stable development/staging domains and separate Auth0 tenants or
+ applications. Do not use ephemeral Vercel preview URLs as production OAuth
+ resource identifiers.
+
+Required server configuration will include:
+
+- `AUTH0_ISSUER`
+- `AUTH0_WEB_CLIENT_ID`
+- `AUTH0_WEB_CLIENT_SECRET`
+- `AUTH0_MCP_RESOURCE`
+- `APP_COOKIE_SECRET`
+- `SITE_ORIGIN`
+- `DEV_AUTH0_SUBJECT`
+
+No Auth0 client secret or access token belongs in plugin manifests or repository
+files.
+
+### 4. Protect the MCP resource
+
+- Wrap the existing `mcp-handler` endpoint with `withMcpAuth`, with
+ authentication required and `expert-system:read` as the required scope.
+- Verify Auth0 access tokens locally with `jose` and Auth0 JWKS:
+ - Allow only the configured asymmetric algorithm.
+ - Validate signature, exact issuer, `exp`, `nbf`, and canonical MCP
+ audience/resource.
+ - Require `sub` and `expert-system:read`.
+ - Reject ID tokens, web-session tokens, REST API keys, and tokens issued for
+ any other API.
+- Attach the resolved internal `userId`, Auth0 subject, client ID, scopes,
+ expiry, and resource to request-local MCP `AuthInfo`.
+- Return protocol-level authentication responses:
+ - `401` with `WWW-Authenticate` for missing, invalid, expired, revoked, or
+ wrong-audience tokens.
+ - `403` with `error="insufficient_scope"` and the required scope for valid
+ tokens lacking permission.
+- Serve public, CORS-enabled metadata at:
+ - `/.well-known/oauth-protected-resource/api/mcp`
+ - `/.well-known/oauth-protected-resource` as a compatibility alias
+- Both documents identify the exact `/api/mcp` resource, Auth0 issuer,
+ `expert-system:read`, and MCP documentation URL. The `WWW-Authenticate`
+ challenge points to the path-specific document.
+- Keep `/api/mcp` OAuth-only. Continue accepting `esak_...` API keys on REST
+ `/api/v1` routes.
+
+### 5. Add the authenticated profile tool
+
+Add `get_profile` as the twelfth MCP tool:
+
+- Empty input object.
+- Returns exactly one profile for the authenticated token:
+ - `id`: stable internal `users.id`.
+ - Optional `email`, `name`, and `nickname` when available.
+- Mark it read-only and set `_meta["openai/profile"] = true`.
+- Publish the exact OpenAI-compatible output schema.
+- Do not accept a user ID or account selector from the caller.
+- Do not charge quota for this identity-only tool.
+
+Update the plugin plan and MCP documentation to describe OAuth sign-in, remove
+MCP API-key/header instructions, and retain API-key documentation only for REST
+users.
+
+## Public Interfaces
+
+- New browser routes: `/api/auth/login`, `/api/auth/callback`,
+ `/api/auth/logout`, and `/api/auth/backchannel`.
+- New public OAuth discovery routes under `/.well-known/`.
+- MCP gains `get_profile`; the existing eleven data tools retain their schemas
+ and responses.
+- `users.clerkUserId` becomes `users.auth0Subject`.
+- MCP authentication changes from `Bearer esak_...` to an Auth0 OAuth access
+ token with audience equal to the canonical MCP URL and scope
+ `expert-system:read`.
+- REST authentication and quota behavior remain unchanged.
+
+## Test Plan
+
+- Unit-test JWT verification for valid tokens and failures involving issuer,
+ audience/resource, signature, expiry, not-before time, token type, missing
+ subject, and missing scope.
+- Verify metadata JSON, path-specific discovery, CORS preflight, and exact
+ `WWW-Authenticate` challenges.
+- Test `401` versus `403` behavior and confirm authentication failures consume
+ no quota.
+- Test MCP provisioning, stable internal identity, profile output, and isolation
+ between concurrent users.
+- Re-run all existing MCP parity and billing tests after replacing API-key MCP
+ fixtures with authenticated principals.
+- Test web login for state, nonce, PKCE, callback replay, unsafe return paths,
+ session fixation, cookie flags, expiry, logout, and Auth0 back-channel
+ revocation.
+- Verify Stripe, usage, API-key management, developer authorization, and X OAuth
+ still resolve the correct Auth0-backed user.
+- Run end-to-end staging flows with MCP Inspector, Codex/OpenAI, and Claude Code:
+ - Initial discovery and consent.
+ - CIMD and DCR fallback.
+ - Tool discovery and execution.
+ - Access-token refresh.
+ - Revocation and reauthentication.
+ - Denied/cancelled consent.
+ - Wrong resource and insufficient scope.
+ - Logout and reconnection.
+- Complete the repository checks:
+ `npx tsc --noEmit && bun run lint && bun run format`, followed by the full
+ Vitest suite and a production-equivalent Vinxi build.
+
+## Assumptions
+
+- Existing development users and user-linked data may be cleared; no production
+ identity migration is required.
+- Auth0 becomes the single identity provider for both website sessions and MCP
+ OAuth.
+- CIMD is preferred; DCR exists only for backward compatibility.
+- The current MCP endpoint, tool behavior, quota accounting, and REST API remain
+ otherwise unchanged.
+- Plugin packaging and marketplace work resumes only after OAuth passes real
+ Codex/OpenAI and Claude interoperability tests.
diff --git a/documents/expert-system-plugin-plan.md b/documents/expert-system-plugin-plan.md
new file mode 100644
index 0000000..7339364
--- /dev/null
+++ b/documents/expert-system-plugin-plan.md
@@ -0,0 +1,116 @@
+
+
+# Expert System Plugin for Claude Code and Codex
+
+## Summary
+
+Convert the repository into one portable plugin that works in Claude Code and Codex, with shared skills and a single remote MCP server. The three skill summaries—research, macro, and financials—will be visible in initial agent context; individual MCP tool schemas will remain discoverable on demand to control context size.
+
+OAuth availability is the release gate. Plugin integration begins only after
+the MCP endpoint supports OAuth. The authoritative implementation specification
+is the sibling [Auth0 OAuth 2.1 plan](./expert-system-mcp-oauth-plan.md).
+
+## Order of Operations
+
+1. **Freeze the cross-client contract**
+
+ - Retain the plugin ID and MCP server name `expert-system`.
+ - Keep the existing endpoint: `https://expert-system.starmode.dev/api/mcp`.
+ - Define the 11 current MCP tools as the initial supported surface.
+ - Set the release target to `2.0.0` because installation, authentication, and execution change materially.
+
+2. **Complete the OAuth server milestone**
+
+ - Implement and validate the sibling
+ [Auth0 OAuth 2.1 plan](./expert-system-mcp-oauth-plan.md).
+ - Make OAuth available on the production MCP endpoint.
+ - Confirm that both Codex and Claude Code can discover authentication, sign in, reconnect, refresh an expired session, and sign out.
+ - Keep API keys only for REST `/api/v1`; MCP is OAuth-only.
+ - Do not begin plugin integration or end-to-end testing until this gate passes.
+
+3. **Create the dual-client plugin package**
+
+ - Add canonical portable `plugin.json` and `mcp.json` files following the [Agent Plugins format](https://developers.openai.com/plugins/build/plugins).
+ - Keep `.claude-plugin/plugin.json` for Claude Code and `.codex-plugin/plugin.json` as a Codex compatibility overlay.
+ - Add `.mcp.json` for Claude Code, pointing at the same remote HTTP MCP endpoint.
+ - Remove `userConfig.api_key` and all hardcoded authorization headers.
+ - Do not use Claude’s `alwaysLoad`; capability routing through skills is the intended initial-context behavior.
+ - Move the Claude marketplace manifest from root `marketplace.json` to `.claude-plugin/marketplace.json` and use the documented GitHub source form.
+
+4. **Convert the existing skills from REST to MCP**
+
+ - Preserve the shared `skills/research`, `skills/macro`, and `skills/financials` paths so both clients use the same instructions.
+ - Rewrite each skill around MCP tool sequences rather than direct `/api/v1` requests.
+ - Give each skill a concise, trigger-rich description so its capability is visible and routable from initial context.
+ - Add `agents/openai.yaml` to all three skills, declaring the `expert-system` MCP dependency and user-facing metadata as described in the [Codex skill guidance](https://developers.openai.com/plugins/build/skills).
+ - Preserve the existing Claude command names where possible: `/expert-system:research`, `/expert-system:macro`, and `/expert-system:financials`.
+
+5. **Map workflows to tools**
+
+ - Research: `search_takeaways` → `get_takeaways` → optional `get_document_content`; use `get_recent_takeaways` for recent-feed requests.
+ - Macro: `list_macro_series` when resolution is needed, followed by `get_macro_observations`.
+ - Financials: discover supported metrics as needed, then use single- or multi-metric company-financial tools and return source provenance.
+ - Define consistent responses for empty results, ambiguity, pagination, partial batch failures, and unavailable tools.
+ - Preserve source links and document provenance in user-facing answers.
+
+6. **Validate through GitHub before directory submission**
+
+ - Run both manifest validators and repository-level static checks.
+ - Install Claude Code directly from the GitHub marketplace and install the Codex package from a clean checkout through a temporary personal marketplace.
+ - Test clean profiles so previously cached MCP or skill registrations cannot mask packaging failures.
+ - Publish a GitHub prerelease, run a short interoperability soak, then tag the stable `2.0.0` release.
+ - After the GitHub release is stable, submit it to the Claude plugin marketplace and the OpenAI universal plugin directory.
+
+7. **Update documentation and release operations**
+ - Replace the Claude-only/API-key README with separate Claude Code and Codex installation sections.
+ - Describe OAuth sign-in only from the user’s perspective.
+ - Document the three capabilities, expected permission prompts, update/uninstall steps, and `/mcp` troubleshooting.
+ - Add the privacy, terms, support, and repository metadata required by the public directories.
+ - Monitor MCP connection/authentication failures, skill-routing misses, tool errors, and regressions after release; retain the previous Git tag as the rollback point.
+
+## Public Interfaces and Repository Shape
+
+```text
+plugin.json
+mcp.json
+.mcp.json
+.claude-plugin/
+ plugin.json
+ marketplace.json
+.codex-plugin/
+ plugin.json
+skills/
+ research/
+ SKILL.md
+ agents/openai.yaml
+ macro/
+ SKILL.md
+ agents/openai.yaml
+ financials/
+ SKILL.md
+ agents/openai.yaml
+README.md
+```
+
+The portable MCP declaration will identify `expert-system` as a remote `streamable-http` server. Claude’s `.mcp.json` will declare the equivalent HTTP connection. Neither configuration will contain tokens, client secrets, or user-specific headers.
+
+## Test Plan
+
+- Validate every JSON/YAML manifest and ensure names, versions, URLs, and descriptions remain synchronized.
+- Run `claude plugin validate .` plus the Codex plugin validator.
+- Verify clean installation, removal, upgrade from v1, and reinstall in both clients.
+- Confirm each capability activates from representative natural-language requests and unrelated prompts do not activate it.
+- Confirm the skill summaries are initially available while MCP tool schemas are discovered only when needed.
+- Exercise every documented tool chain with successful, empty, ambiguous, paginated, and partially failed responses.
+- Verify source attribution and financial period semantics.
+- At a high level, test first sign-in, reconnect, expired-session recovery, cancellation, logout, and denied authorization in both clients.
+- Confirm no API keys, bearer tokens, or credentials are stored in the repository or plugin configuration.
+
+## Assumptions and Defaults
+
+- One repository and one shared set of skills will serve both clients; there will not be separate Claude and Codex forks.
+- OAuth is mandatory for the v2 plugin release and is completed before plugin integration begins.
+- Deferred MCP schemas are intentional; the initial-context requirement is satisfied through concise skill metadata, not eager-loading all 11 tools.
+- Existing REST API-key users remain supported; MCP and the distributed plugin expose OAuth only.
+- GitHub is the first distribution and validation channel; public marketplace submissions follow a successful stable release.
+
diff --git a/public/marketplace.json b/public/marketplace.json
index acf9fca..1f255b2 100644
--- a/public/marketplace.json
+++ b/public/marketplace.json
@@ -1,11 +1,21 @@
{
- "name": "Expert System",
+ "name": "expert-system",
+ "owner": {
+ "name": "STAR MODE",
+ "url": "https://github.com/starmode-base"
+ },
"plugins": [
{
"name": "expert-system",
- "source": "github://starmode-base/expert-system-plugin",
- "version": "1.0.0",
- "description": "Research intelligence and macroeconomic data for Claude Code"
+ "source": {
+ "source": "github",
+ "repo": "starmode-base/expert-system-plugin"
+ },
+ "version": "2.0.0",
+ "description": "Curated research, FRED macroeconomic data, and SEC company financials with source provenance."
}
- ]
+ ],
+ "metadata": {
+ "description": "Expert System research, macroeconomic data, and financials plugins."
+ }
}
diff --git a/public/privacy.html b/public/privacy.html
new file mode 100644
index 0000000..208b943
--- /dev/null
+++ b/public/privacy.html
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+ Privacy Policy — Expert System
+
+
+
+
+
+
Privacy Policy
+
Last updated: September 20, 2026
+
+ This policy describes how STAR MODE handles information when you use
+ Expert System, including its website, REST API, and MCP plugin
+ connections.
+
+
Information processed
+
+
+ Account information: authentication identifiers and
+ available email, display name, and nickname; plan tier and
+ subscription status.
+
+
+ Requests: the search text, company identifiers,
+ document IDs, series IDs, date ranges, and other arguments your client
+ sends to fulfill a request. The MCP integration receives tool
+ arguments, not automatic access to your full chat history or local
+ files.
+
+
+ Usage and technical information: per-account monthly
+ request counts by endpoint, session and token-revocation records, and
+ operational error logs. Hosting and authentication providers may
+ process connection metadata such as IP addresses and device/browser
+ information.
+
+
+ Billing: Stripe customer and subscription identifiers
+ and payment status. Payment details are handled through Stripe.
+
+
+
How information is used
+
+ We process information to authenticate users, return requested research
+ and data, enforce access and usage limits, manage subscriptions,
+ troubleshoot failures, and protect the service. Browser sign-in uses
+ cookies and server-side session records. MCP credentials are managed by
+ your client and authentication provider; the distributed plugin contains
+ no user credentials.
+
+
Service providers and your AI client
+
+ Auth0 handles authentication, Vercel hosts the service, Neon provides
+ database infrastructure, and Stripe handles payments. Research search
+ text is sent to OpenAI to generate embeddings for semantic search.
+ Requests for economic and company data may involve FRED and SEC data
+ services. These providers process information needed for their functions
+ under their applicable terms and privacy practices.
+
+
+ Results and, when requested through the profile tool, your available
+ account identifier, name, and email are returned to your connected
+ client. Claude, Codex, and other clients have their own data policies.
+ Information may be processed in countries where we or our providers
+ operate.
+
+
Retention and choices
+
+ Account, usage, billing, and operational records persist as needed to
+ operate the service and address security, accounting, or legal
+ requirements. There is no single automatic deletion period for all
+ records. Signing out or uninstalling a plugin does not delete your
+ account, cancel a subscription, or remove provider logs and backups.
+
+
+ You can stop sending requests, disconnect the plugin, sign out, and
+ manage your subscription from your account. Contact us to request
+ access, correction, or deletion of account information. We may need to
+ verify account ownership; applicable obligations and backup retention
+ may limit immediate deletion. Rights vary by location.
+
+
Security and changes
+
+ Use the client’s sign-in flow and keep credentials private. No service
+ can guarantee absolute security. We may update this policy as the
+ service changes; the date below identifies this version.
+
+
Contact
+
+ Contact STAR MODE through
+ Expert System support. For an account or privacy request, ask for a private contact channel
+ before providing identifying information. Do not post personal data,
+ credentials, or billing details in public issues.
+
+
+
+
+
diff --git a/public/terms.html b/public/terms.html
new file mode 100644
index 0000000..0bfdedf
--- /dev/null
+++ b/public/terms.html
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+ Terms of Service — Expert System
+
+
+
+
+
+
Terms of Service
+
Last updated: September 20, 2026
+
+ These terms govern your use of Expert System, operated by STAR MODE,
+ including the website, API, and MCP plugins. By using the service, you
+ agree to these terms. If you do not agree, do not use the service.
+
+
Accounts and access
+
+ Use an account you are authorized to control, protect your credentials,
+ and keep account information accurate. Your agent may request read
+ access on your behalf. You are responsible for requests you authorize
+ and for complying with applicable laws and your organization’s rules. Do
+ not bypass access controls or usage limits, interfere with the service,
+ or access another person’s account without permission.
+
+
Data and permitted use
+
+ Expert System provides curated research and economic and financial
+ information. Third-party sources retain their rights. Access to a result
+ does not grant ownership or unrestricted redistribution rights; follow
+ the source’s applicable terms and retain attribution. Use the service
+ only for lawful purposes.
+
+
Accuracy and financial information
+
+ Data may be delayed, incomplete, revised, or incorrect. Generated
+ summaries and analysis may contain errors. Verify important claims
+ against original sources, including dates, units, and fiscal periods.
+ The service provides information, not personalized investment, legal, or
+ tax advice, and does not execute trades or guarantee investment
+ outcomes.
+
+
Plans and billing
+
+ Usage limits, prices, and billing intervals are displayed in the service
+ or at checkout. Paid subscriptions are governed by the terms shown at
+ purchase. Manage your subscription through your account; uninstalling a
+ plugin does not cancel it. Mandatory consumer rights remain applicable.
+
+
Availability and suspension
+
+ We may change features, data coverage, or limits, and the service may be
+ interrupted. We may restrict access for misuse, security concerns,
+ nonpayment, or legal requirements. You may stop using the service at any
+ time and contact us about account deletion.
+
+
Disclaimers and responsibility
+
+ To the extent permitted by applicable law, the service is provided as
+ available without warranties of accuracy, completeness, uninterrupted
+ availability, or fitness for a particular purpose. You are responsible
+ for decisions made using its outputs. Nothing in these terms excludes
+ rights or liabilities that cannot lawfully be excluded.
+
+
Privacy and changes
+
+ Our Privacy Policy explains data handling.
+ We may revise these terms and publish an updated date. Review changes
+ before continuing to use the service.
+
+
Contact
+
+ Contact STAR MODE through
+ Expert System support. For an account or privacy request, ask for a private contact channel
+ before providing identifying information. Do not post personal data,
+ credentials, or billing details in public issues.
+
+
+
+
+
diff --git a/src/routes/api/v1.docs.ts b/src/routes/api/v1.docs.ts
index 1df816c..009c032 100644
--- a/src/routes/api/v1.docs.ts
+++ b/src/routes/api/v1.docs.ts
@@ -34,7 +34,7 @@ Connect an OAuth-capable HTTP MCP client to the canonical https://expert-system.
Tool arguments use the same field names as REST, with native arrays for ids and a boolean for recent. Path parameters become tool arguments. POST arguments match the REST JSON body. Results are REST-equivalent JSON in structuredContent and serialized text; application failures set isError and include _meta.httpStatus (plus relevant HTTP headers in _meta.httpHeaders).
-MCP and REST share quotas and endpoint buckets. Authentication and validation failures, discovery, initialization and protocol errors are free. Valid tool calls, including catalogs, provider failures and partial results, count once. Current MCP and older Streamable HTTP clients share the stateless endpoint; OAuth and legacy HTTP+SSE are not supported.
+MCP and REST share quotas and endpoint buckets. Authentication and validation failures, discovery, initialization and protocol errors are free. Valid tool calls, including catalogs, provider failures and partial results, count once. Current MCP and older Streamable HTTP clients share the stateless endpoint; OAuth is required; legacy HTTP+SSE is not supported.
---
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 3b680be..9e3ba0a 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -190,10 +190,10 @@ function LandingPage() {
- Works with any agent that supports the{" "}
+ Shared workflows for agents that support the{" "}
Agent Skills
{" "}
- standard. Or use the{" "}
+ standard. See GitHub for Codex plugin installation. REST
+ developers can use the{" "}
{/* Footer links */}
-
From db57d8941c14b3500b9c949b3cd3b39d18c65aac Mon Sep 17 00:00:00 2001
From: "Griffin (AI)"
Date: Sun, 20 Sep 2026 06:28:49 -0700
Subject: [PATCH 2/6] Add plugin contract check to CI
Runs expert-system-plugin's packaging checks against this repository's tree
so tool renames, marketplace drift, or missing policy pages fail here.
Co-Authored-By: Claude Opus 5
---
.github/workflows/plugin-contract.yml | 42 +++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 .github/workflows/plugin-contract.yml
diff --git a/.github/workflows/plugin-contract.yml b/.github/workflows/plugin-contract.yml
new file mode 100644
index 0000000..8d253e4
--- /dev/null
+++ b/.github/workflows/plugin-contract.yml
@@ -0,0 +1,42 @@
+name: Plugin contract
+
+# Tool names, the hosted marketplace copy, and the public policy pages are part
+# of the contract consumed by starmode-base/expert-system-plugin. This job runs
+# that repository's packaging checks against the server tree in this PR, so a
+# rename or removal here fails before it breaks installed plugins.
+#
+# The plugin is checked out at its default branch. A coordinated breaking change
+# that is correct on both sides will fail here until the plugin side merges;
+# land the plugin PR first, as documented in AGENTS.md.
+
+on:
+ pull_request:
+ push:
+ branches: [main]
+
+jobs:
+ contract:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out server
+ uses: actions/checkout@v4
+ with:
+ path: expert-system
+
+ - name: Check out plugin
+ uses: actions/checkout@v4
+ with:
+ repository: starmode-base/expert-system-plugin
+ path: expert-system-plugin
+
+ - uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: latest
+
+ - run: bun install --frozen-lockfile
+ working-directory: expert-system-plugin
+
+ - run: bun run plugin:check
+ working-directory: expert-system-plugin
+ env:
+ EXPERT_SYSTEM_SERVER_ROOT: ${{ github.workspace }}/expert-system
From e0d49cec46ced0cbe2ea09d6bfd3115bc728f855 Mon Sep 17 00:00:00 2001
From: "Griffin (AI)"
Date: Sun, 20 Sep 2026 06:32:10 -0700
Subject: [PATCH 3/6] Drop the plugin contract CI job
The check lives in expert-system-plugin instead, on PRs and a nightly
schedule, so server CI is not coupled to the plugin's default branch.
Co-Authored-By: Claude Opus 5
---
.github/workflows/plugin-contract.yml | 42 ---------------------------
1 file changed, 42 deletions(-)
delete mode 100644 .github/workflows/plugin-contract.yml
diff --git a/.github/workflows/plugin-contract.yml b/.github/workflows/plugin-contract.yml
deleted file mode 100644
index 8d253e4..0000000
--- a/.github/workflows/plugin-contract.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: Plugin contract
-
-# Tool names, the hosted marketplace copy, and the public policy pages are part
-# of the contract consumed by starmode-base/expert-system-plugin. This job runs
-# that repository's packaging checks against the server tree in this PR, so a
-# rename or removal here fails before it breaks installed plugins.
-#
-# The plugin is checked out at its default branch. A coordinated breaking change
-# that is correct on both sides will fail here until the plugin side merges;
-# land the plugin PR first, as documented in AGENTS.md.
-
-on:
- pull_request:
- push:
- branches: [main]
-
-jobs:
- contract:
- runs-on: ubuntu-latest
- steps:
- - name: Check out server
- uses: actions/checkout@v4
- with:
- path: expert-system
-
- - name: Check out plugin
- uses: actions/checkout@v4
- with:
- repository: starmode-base/expert-system-plugin
- path: expert-system-plugin
-
- - uses: oven-sh/setup-bun@v2
- with:
- bun-version: latest
-
- - run: bun install --frozen-lockfile
- working-directory: expert-system-plugin
-
- - run: bun run plugin:check
- working-directory: expert-system-plugin
- env:
- EXPERT_SYSTEM_SERVER_ROOT: ${{ github.workspace }}/expert-system
From 1e72d961c2344d9eeb4ca297314eb865afce49fa Mon Sep 17 00:00:00 2001
From: "Griffin (AI)"
Date: Sun, 20 Sep 2026 06:38:17 -0700
Subject: [PATCH 4/6] Move plugin sync details into documentation
AGENTS.md keeps the trigger and the command; the rest lives in
documentation/PLUGIN_SYNC.md and is linked for discovery.
Co-Authored-By: Claude Opus 5
---
AGENTS.md | 15 +++------------
documentation/PLUGIN_SYNC.md | 30 ++++++++++++++++++++++++++++++
2 files changed, 33 insertions(+), 12 deletions(-)
create mode 100644 documentation/PLUGIN_SYNC.md
diff --git a/AGENTS.md b/AGENTS.md
index 0e6e9cb..88747a7 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -27,21 +27,12 @@ During development, apply schema changes using `bun run db:push` (`drizzle-kit p
## Server–plugin synchronization
-Expert System is maintained in two repositories, normally checked out as siblings:
+The plugin lives in the sibling `expert-system-plugin` repository. Do not duplicate it here. This repository owns the MCP server, OAuth, the website, and the public privacy/terms pages.
-- `expert-system` owns the MCP server, OAuth, tool schemas and response semantics, website, and public privacy/terms pages.
-- `expert-system-plugin` owns the plugin manifests, shared skills, installation documentation, packaging tests, and plugin releases. Do not duplicate the plugin package in the server repository.
-
-When changing MCP tool names, arguments, responses, errors, limits, pagination, units, fiscal-period semantics, endpoint URLs, or OAuth requirements, inspect the corresponding code and instructions in **both** repositories. Update affected plugin skills, `agents/openai.yaml` dependencies, manifests, tests, and documentation together with server changes. The server contract is defined by `src/server/mcp/tools.ts` and its referenced schemas/operations; do not infer it from stale skill text.
-
-The plugin's `.claude-plugin/marketplace.json` is canonical. Keep the server's `public/marketplace.json` identical whenever plugin versions, descriptions, or source references change. Keep identity and version metadata synchronized across the plugin's portable, Claude, and Codex manifests; transport declarations must point to the same MCP endpoint. Policy URLs in plugin metadata must correspond to pages hosted by the server.
-
-For changes affecting this shared contract or a plugin release, run this command **from the plugin repository**, in addition to each repository's relevant checks:
+When changing MCP tool names, arguments, responses, errors, limits, endpoint URLs, OAuth requirements, `public/marketplace.json`, or the policy pages, update the plugin repository in the same change and run its check:
```bash
EXPERT_SYSTEM_SERVER_ROOT=../expert-system bun run plugin:check
```
-Use the actual server checkout path if the repositories are not siblings. The cross-repository test is skipped when `EXPERT_SYSTEM_SERVER_ROOT` is unset; a standalone green run is not synchronization validation. The check verifies tool names, marketplace parity, and policy files, but does not validate argument/response semantics or live OAuth behavior. Review affected schemas and workflows and run relevant server tests; perform client smoke tests when connection or packaging behavior changes. Update contract assertions only for intentional changes, never merely to make drift checks pass.
-
-Preserve compatibility with already-installed plugin versions where possible. For breaking changes, document the required plugin version and rollout order in `documents/plugin-release.md` in the plugin repository. If work spans both repositories, link the companion PRs and report checks for each. If a companion checkout is unavailable, report the synchronization work and checks still needed; do not claim the change is release-ready.
+Server CI does not run that check. See [documentation/PLUGIN_SYNC.md](documentation/PLUGIN_SYNC.md) for what it covers, what it misses, and release rules.
diff --git a/documentation/PLUGIN_SYNC.md b/documentation/PLUGIN_SYNC.md
new file mode 100644
index 0000000..be63db8
--- /dev/null
+++ b/documentation/PLUGIN_SYNC.md
@@ -0,0 +1,30 @@
+# Server–plugin synchronization
+
+Expert System is maintained in two repositories, normally checked out as siblings:
+
+- `expert-system` owns the MCP server, OAuth, tool schemas and response semantics, website, and public privacy/terms pages.
+- `expert-system-plugin` owns the plugin manifests, shared skills, installation documentation, packaging tests, and plugin releases. Do not duplicate the plugin package in the server repository.
+
+## What to update together
+
+When changing MCP tool names, arguments, responses, errors, limits, pagination, units, fiscal-period semantics, endpoint URLs, or OAuth requirements, inspect the corresponding code and instructions in **both** repositories. Update affected plugin skills, `agents/openai.yaml` dependencies, manifests, tests, and documentation together with server changes. The server contract is defined by `src/server/mcp/tools.ts` and its referenced schemas/operations; do not infer it from stale skill text.
+
+The plugin's `.claude-plugin/marketplace.json` is canonical. Keep the server's `public/marketplace.json` identical whenever plugin versions, descriptions, or source references change. Keep identity and version metadata synchronized across the plugin's portable, Claude, and Codex manifests; transport declarations must point to the same MCP endpoint. Policy URLs in plugin metadata must correspond to pages hosted by the server.
+
+## Checking
+
+Run this **from the plugin repository**, in addition to each repository's relevant checks:
+
+```bash
+EXPERT_SYSTEM_SERVER_ROOT=../expert-system bun run plugin:check
+```
+
+Use the actual server checkout path if the repositories are not siblings. The cross-repository test is skipped when `EXPERT_SYSTEM_SERVER_ROOT` is unset; a standalone green run is not synchronization validation.
+
+The plugin repository's CI runs this check on its own pull requests and nightly. Server pull requests do **not** run it, so drift originating here surfaces on the next nightly run at the earliest — run the check locally when changing the contract.
+
+The check verifies tool names, marketplace parity, and policy files. It does not validate argument/response semantics or live OAuth behavior. Review affected schemas and workflows and run relevant server tests; perform client smoke tests when connection or packaging behavior changes. Update contract assertions only for intentional changes, never merely to make drift checks pass.
+
+## Releasing
+
+Preserve compatibility with already-installed plugin versions where possible. For breaking changes, document the required plugin version and rollout order in `documents/plugin-release.md` in the plugin repository. If work spans both repositories, link the companion PRs and report checks for each. If a companion checkout is unavailable, report the synchronization work and checks still needed; do not claim the change is release-ready.
From 9ff4a6151135aeaa76a978d1b45a140e773c1662 Mon Sep 17 00:00:00 2001
From: "Griffin (AI)"
Date: Sun, 20 Sep 2026 06:41:33 -0700
Subject: [PATCH 5/6] Add a plugin:check script
Runs the plugin repository's checks against this checkout, so the
synchronization command works from either repository.
Co-Authored-By: Claude Opus 5
---
AGENTS.md | 2 +-
documentation/PLUGIN_SYNC.md | 6 +++---
package.json | 1 +
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index 88747a7..d37a610 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -32,7 +32,7 @@ The plugin lives in the sibling `expert-system-plugin` repository. Do not duplic
When changing MCP tool names, arguments, responses, errors, limits, endpoint URLs, OAuth requirements, `public/marketplace.json`, or the policy pages, update the plugin repository in the same change and run its check:
```bash
-EXPERT_SYSTEM_SERVER_ROOT=../expert-system bun run plugin:check
+bun run plugin:check
```
Server CI does not run that check. See [documentation/PLUGIN_SYNC.md](documentation/PLUGIN_SYNC.md) for what it covers, what it misses, and release rules.
diff --git a/documentation/PLUGIN_SYNC.md b/documentation/PLUGIN_SYNC.md
index be63db8..b0ee6bb 100644
--- a/documentation/PLUGIN_SYNC.md
+++ b/documentation/PLUGIN_SYNC.md
@@ -13,13 +13,13 @@ The plugin's `.claude-plugin/marketplace.json` is canonical. Keep the server's `
## Checking
-Run this **from the plugin repository**, in addition to each repository's relevant checks:
+Run this from either repository, in addition to each repository's relevant checks:
```bash
-EXPERT_SYSTEM_SERVER_ROOT=../expert-system bun run plugin:check
+bun run plugin:check
```
-Use the actual server checkout path if the repositories are not siblings. The cross-repository test is skipped when `EXPERT_SYSTEM_SERVER_ROOT` is unset; a standalone green run is not synchronization validation.
+This repository's script runs the plugin repository's test suite against this checkout. It assumes the repositories are siblings; set `EXPERT_SYSTEM_PLUGIN_ROOT` if they are not. Run from the plugin repository instead with `EXPERT_SYSTEM_SERVER_ROOT=../expert-system bun run plugin:check` — the cross-repository test is skipped when that variable is unset there, so a standalone green run is not synchronization validation.
The plugin repository's CI runs this check on its own pull requests and nightly. Server pull requests do **not** run it, so drift originating here surfaces on the next nightly run at the earliest — run the check locally when changing the contract.
diff --git a/package.json b/package.json
index 2e67ba0..0898f74 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"format": "prettier --write .",
"lint": "eslint --max-warnings 0 --fix",
"test": "vitest",
+ "plugin:check": "root=$PWD; cd \"${EXPERT_SYSTEM_PLUGIN_ROOT:-../expert-system-plugin}\" && EXPERT_SYSTEM_SERVER_ROOT=\"$root\" bun run plugin:check",
"env:pull": "bunx vercel@latest env pull .env && ./scripts/dev-env.sh",
"clean": "rm -rf node_modules tsconfig.tsbuildinfo bun.lock .output .vinxi && bun install",
"db:generate": "drizzle-kit generate",
From ffd1128156dae42d3e808c61e7202267ca9ca6e4 Mon Sep 17 00:00:00 2001
From: "Griffin (AI)"
Date: Sun, 20 Sep 2026 06:44:15 -0700
Subject: [PATCH 6/6] delect plan files
---
documents/expert-system-mcp-oauth-plan.md | 198 ----------------------
documents/expert-system-plugin-plan.md | 116 -------------
2 files changed, 314 deletions(-)
delete mode 100644 documents/expert-system-mcp-oauth-plan.md
delete mode 100644 documents/expert-system-plugin-plan.md
diff --git a/documents/expert-system-mcp-oauth-plan.md b/documents/expert-system-mcp-oauth-plan.md
deleted file mode 100644
index 691b7d4..0000000
--- a/documents/expert-system-mcp-oauth-plan.md
+++ /dev/null
@@ -1,198 +0,0 @@
-# Auth0 OAuth 2.1 for the Expert System MCP
-
-## Summary
-
-Replace Clerk with Auth0 across the application, then expose `/api/mcp` as an
-OAuth-only MCP resource server. REST API keys remain supported, but MCP clients
-authenticate through Auth0 using Authorization Code + PKCE.
-
-Auth0 is preferred because its MCP support, CIMD registration, and RFC 8707
-resource handling are generally available, while the repository's Clerk
-integration is outdated and Clerk CIMD remains beta. This follows the
-[OpenAI OAuth guidance](https://developers.openai.com/plugins/build/auth),
-[current MCP authorization specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization),
-[Claude Code OAuth behavior](https://code.claude.com/docs/en/mcp), and
-[Auth0 Auth for MCP](https://auth0.com/ai/docs/mcp/overview).
-
-OAuth interoperability is the release gate for the plugin plan in
-[`expert-system-plugin-plan.md`](./expert-system-plugin-plan.md).
-
-## Implementation Changes
-
-### 1. Replace Clerk application authentication
-
-- Remove `@clerk/tanstack-start`, `ClerkProvider`, Clerk UI components,
- `createClerkHandler`, and Clerk-specific middleware.
-- Configure one Auth0 tenant per stable environment and create:
- - A first-party Regular Web Application for the Expert System website.
- - An Auth0 API whose identifier is the canonical MCP URL, such as
- `https://expert-system.starmode.dev/api/mcp`.
-- Use `openid-client` for the server-side web authorization-code flow instead
- of turning the application into a browser-only SPA:
- - `/api/auth/login` generates `state`, `nonce`, and an S256 PKCE verifier.
- - `/api/auth/callback` validates the transaction, exchanges the code,
- validates the ID token, upserts the user, rotates the local session, and
- redirects to the original safe same-origin path.
- - `/api/auth/logout` revokes the local session, clears the cookie, and
- redirects through Auth0 logout.
-- Store opaque web-session tokens in an HttpOnly, Secure, SameSite=Lax cookie.
- Store only a SHA-256 token hash in a new `auth_sessions` table, with user,
- Auth0 `sid`, expiry, and revocation timestamps.
-- Add an Auth0 back-channel logout endpoint that validates signature, issuer,
- audience, events, `sid`/`sub`, and absence of `nonce`, then revokes matching
- local sessions.
-- Replace Clerk UI helpers with root-loader authentication state and local
- sign-in/sign-out links. Preserve the existing protected-page behavior.
-- Replace the hard-coded Clerk developer identity with a `DEV_AUTH0_SUBJECT`
- environment variable.
-- Replace reuse of `CLERK_SECRET_KEY` for X OAuth cookie encryption with a
- dedicated `APP_COOKIE_SECRET`.
-
-### 2. Reset and normalize application identities
-
-- Replace `users.clerkUserId` with a unique `users.auth0Subject`.
-- Add nullable `displayName`; allow `email` to be initially nullable because an
- MCP access token is only required to supply a stable `sub`.
-- Web login requires and synchronizes a verified email before creating a web
- session. MCP-only users can be provisioned from `sub` and enriched when they
- later use the website.
-- Keep the existing internal `users.id` as the stable identity for quota,
- Stripe, API keys, organizations, and the MCP profile tool.
-- Update the shared auth middleware to resolve an active local session, load the
- internal user, and expose the same `viewer` contract expected by existing
- server functions.
-- Reset user-linked development data during the schema transition, as
- authorized. Use `bun run db:push` while iterating and generate the final
- migration only immediately before the PR.
-
-### 3. Configure Auth0 for MCP
-
-- Enable Auth0's Resource Parameter Compatibility Profile so the MCP `resource`
- parameter maps to the registered MCP API audience.
-- Define one API permission: `expert-system:read`.
-- Require RS256, Authorization Code + S256 PKCE, explicit consent, short-lived
- access tokens, and rotating refresh tokens.
-- Prefer CIMD:
- - Pre-register the published OpenAI and Claude client metadata documents after
- validating their redirect URIs and metadata.
- - Advertise CIMD support through Auth0.
-- Enable DCR only as a compatibility fallback for older clients. Treat it as a
- public registration endpoint: apply Auth0 third-party application controls,
- require consent, monitor registrations, and periodically remove abandoned
- clients.
-- Use stable development/staging domains and separate Auth0 tenants or
- applications. Do not use ephemeral Vercel preview URLs as production OAuth
- resource identifiers.
-
-Required server configuration will include:
-
-- `AUTH0_ISSUER`
-- `AUTH0_WEB_CLIENT_ID`
-- `AUTH0_WEB_CLIENT_SECRET`
-- `AUTH0_MCP_RESOURCE`
-- `APP_COOKIE_SECRET`
-- `SITE_ORIGIN`
-- `DEV_AUTH0_SUBJECT`
-
-No Auth0 client secret or access token belongs in plugin manifests or repository
-files.
-
-### 4. Protect the MCP resource
-
-- Wrap the existing `mcp-handler` endpoint with `withMcpAuth`, with
- authentication required and `expert-system:read` as the required scope.
-- Verify Auth0 access tokens locally with `jose` and Auth0 JWKS:
- - Allow only the configured asymmetric algorithm.
- - Validate signature, exact issuer, `exp`, `nbf`, and canonical MCP
- audience/resource.
- - Require `sub` and `expert-system:read`.
- - Reject ID tokens, web-session tokens, REST API keys, and tokens issued for
- any other API.
-- Attach the resolved internal `userId`, Auth0 subject, client ID, scopes,
- expiry, and resource to request-local MCP `AuthInfo`.
-- Return protocol-level authentication responses:
- - `401` with `WWW-Authenticate` for missing, invalid, expired, revoked, or
- wrong-audience tokens.
- - `403` with `error="insufficient_scope"` and the required scope for valid
- tokens lacking permission.
-- Serve public, CORS-enabled metadata at:
- - `/.well-known/oauth-protected-resource/api/mcp`
- - `/.well-known/oauth-protected-resource` as a compatibility alias
-- Both documents identify the exact `/api/mcp` resource, Auth0 issuer,
- `expert-system:read`, and MCP documentation URL. The `WWW-Authenticate`
- challenge points to the path-specific document.
-- Keep `/api/mcp` OAuth-only. Continue accepting `esak_...` API keys on REST
- `/api/v1` routes.
-
-### 5. Add the authenticated profile tool
-
-Add `get_profile` as the twelfth MCP tool:
-
-- Empty input object.
-- Returns exactly one profile for the authenticated token:
- - `id`: stable internal `users.id`.
- - Optional `email`, `name`, and `nickname` when available.
-- Mark it read-only and set `_meta["openai/profile"] = true`.
-- Publish the exact OpenAI-compatible output schema.
-- Do not accept a user ID or account selector from the caller.
-- Do not charge quota for this identity-only tool.
-
-Update the plugin plan and MCP documentation to describe OAuth sign-in, remove
-MCP API-key/header instructions, and retain API-key documentation only for REST
-users.
-
-## Public Interfaces
-
-- New browser routes: `/api/auth/login`, `/api/auth/callback`,
- `/api/auth/logout`, and `/api/auth/backchannel`.
-- New public OAuth discovery routes under `/.well-known/`.
-- MCP gains `get_profile`; the existing eleven data tools retain their schemas
- and responses.
-- `users.clerkUserId` becomes `users.auth0Subject`.
-- MCP authentication changes from `Bearer esak_...` to an Auth0 OAuth access
- token with audience equal to the canonical MCP URL and scope
- `expert-system:read`.
-- REST authentication and quota behavior remain unchanged.
-
-## Test Plan
-
-- Unit-test JWT verification for valid tokens and failures involving issuer,
- audience/resource, signature, expiry, not-before time, token type, missing
- subject, and missing scope.
-- Verify metadata JSON, path-specific discovery, CORS preflight, and exact
- `WWW-Authenticate` challenges.
-- Test `401` versus `403` behavior and confirm authentication failures consume
- no quota.
-- Test MCP provisioning, stable internal identity, profile output, and isolation
- between concurrent users.
-- Re-run all existing MCP parity and billing tests after replacing API-key MCP
- fixtures with authenticated principals.
-- Test web login for state, nonce, PKCE, callback replay, unsafe return paths,
- session fixation, cookie flags, expiry, logout, and Auth0 back-channel
- revocation.
-- Verify Stripe, usage, API-key management, developer authorization, and X OAuth
- still resolve the correct Auth0-backed user.
-- Run end-to-end staging flows with MCP Inspector, Codex/OpenAI, and Claude Code:
- - Initial discovery and consent.
- - CIMD and DCR fallback.
- - Tool discovery and execution.
- - Access-token refresh.
- - Revocation and reauthentication.
- - Denied/cancelled consent.
- - Wrong resource and insufficient scope.
- - Logout and reconnection.
-- Complete the repository checks:
- `npx tsc --noEmit && bun run lint && bun run format`, followed by the full
- Vitest suite and a production-equivalent Vinxi build.
-
-## Assumptions
-
-- Existing development users and user-linked data may be cleared; no production
- identity migration is required.
-- Auth0 becomes the single identity provider for both website sessions and MCP
- OAuth.
-- CIMD is preferred; DCR exists only for backward compatibility.
-- The current MCP endpoint, tool behavior, quota accounting, and REST API remain
- otherwise unchanged.
-- Plugin packaging and marketplace work resumes only after OAuth passes real
- Codex/OpenAI and Claude interoperability tests.
diff --git a/documents/expert-system-plugin-plan.md b/documents/expert-system-plugin-plan.md
deleted file mode 100644
index 7339364..0000000
--- a/documents/expert-system-plugin-plan.md
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-# Expert System Plugin for Claude Code and Codex
-
-## Summary
-
-Convert the repository into one portable plugin that works in Claude Code and Codex, with shared skills and a single remote MCP server. The three skill summaries—research, macro, and financials—will be visible in initial agent context; individual MCP tool schemas will remain discoverable on demand to control context size.
-
-OAuth availability is the release gate. Plugin integration begins only after
-the MCP endpoint supports OAuth. The authoritative implementation specification
-is the sibling [Auth0 OAuth 2.1 plan](./expert-system-mcp-oauth-plan.md).
-
-## Order of Operations
-
-1. **Freeze the cross-client contract**
-
- - Retain the plugin ID and MCP server name `expert-system`.
- - Keep the existing endpoint: `https://expert-system.starmode.dev/api/mcp`.
- - Define the 11 current MCP tools as the initial supported surface.
- - Set the release target to `2.0.0` because installation, authentication, and execution change materially.
-
-2. **Complete the OAuth server milestone**
-
- - Implement and validate the sibling
- [Auth0 OAuth 2.1 plan](./expert-system-mcp-oauth-plan.md).
- - Make OAuth available on the production MCP endpoint.
- - Confirm that both Codex and Claude Code can discover authentication, sign in, reconnect, refresh an expired session, and sign out.
- - Keep API keys only for REST `/api/v1`; MCP is OAuth-only.
- - Do not begin plugin integration or end-to-end testing until this gate passes.
-
-3. **Create the dual-client plugin package**
-
- - Add canonical portable `plugin.json` and `mcp.json` files following the [Agent Plugins format](https://developers.openai.com/plugins/build/plugins).
- - Keep `.claude-plugin/plugin.json` for Claude Code and `.codex-plugin/plugin.json` as a Codex compatibility overlay.
- - Add `.mcp.json` for Claude Code, pointing at the same remote HTTP MCP endpoint.
- - Remove `userConfig.api_key` and all hardcoded authorization headers.
- - Do not use Claude’s `alwaysLoad`; capability routing through skills is the intended initial-context behavior.
- - Move the Claude marketplace manifest from root `marketplace.json` to `.claude-plugin/marketplace.json` and use the documented GitHub source form.
-
-4. **Convert the existing skills from REST to MCP**
-
- - Preserve the shared `skills/research`, `skills/macro`, and `skills/financials` paths so both clients use the same instructions.
- - Rewrite each skill around MCP tool sequences rather than direct `/api/v1` requests.
- - Give each skill a concise, trigger-rich description so its capability is visible and routable from initial context.
- - Add `agents/openai.yaml` to all three skills, declaring the `expert-system` MCP dependency and user-facing metadata as described in the [Codex skill guidance](https://developers.openai.com/plugins/build/skills).
- - Preserve the existing Claude command names where possible: `/expert-system:research`, `/expert-system:macro`, and `/expert-system:financials`.
-
-5. **Map workflows to tools**
-
- - Research: `search_takeaways` → `get_takeaways` → optional `get_document_content`; use `get_recent_takeaways` for recent-feed requests.
- - Macro: `list_macro_series` when resolution is needed, followed by `get_macro_observations`.
- - Financials: discover supported metrics as needed, then use single- or multi-metric company-financial tools and return source provenance.
- - Define consistent responses for empty results, ambiguity, pagination, partial batch failures, and unavailable tools.
- - Preserve source links and document provenance in user-facing answers.
-
-6. **Validate through GitHub before directory submission**
-
- - Run both manifest validators and repository-level static checks.
- - Install Claude Code directly from the GitHub marketplace and install the Codex package from a clean checkout through a temporary personal marketplace.
- - Test clean profiles so previously cached MCP or skill registrations cannot mask packaging failures.
- - Publish a GitHub prerelease, run a short interoperability soak, then tag the stable `2.0.0` release.
- - After the GitHub release is stable, submit it to the Claude plugin marketplace and the OpenAI universal plugin directory.
-
-7. **Update documentation and release operations**
- - Replace the Claude-only/API-key README with separate Claude Code and Codex installation sections.
- - Describe OAuth sign-in only from the user’s perspective.
- - Document the three capabilities, expected permission prompts, update/uninstall steps, and `/mcp` troubleshooting.
- - Add the privacy, terms, support, and repository metadata required by the public directories.
- - Monitor MCP connection/authentication failures, skill-routing misses, tool errors, and regressions after release; retain the previous Git tag as the rollback point.
-
-## Public Interfaces and Repository Shape
-
-```text
-plugin.json
-mcp.json
-.mcp.json
-.claude-plugin/
- plugin.json
- marketplace.json
-.codex-plugin/
- plugin.json
-skills/
- research/
- SKILL.md
- agents/openai.yaml
- macro/
- SKILL.md
- agents/openai.yaml
- financials/
- SKILL.md
- agents/openai.yaml
-README.md
-```
-
-The portable MCP declaration will identify `expert-system` as a remote `streamable-http` server. Claude’s `.mcp.json` will declare the equivalent HTTP connection. Neither configuration will contain tokens, client secrets, or user-specific headers.
-
-## Test Plan
-
-- Validate every JSON/YAML manifest and ensure names, versions, URLs, and descriptions remain synchronized.
-- Run `claude plugin validate .` plus the Codex plugin validator.
-- Verify clean installation, removal, upgrade from v1, and reinstall in both clients.
-- Confirm each capability activates from representative natural-language requests and unrelated prompts do not activate it.
-- Confirm the skill summaries are initially available while MCP tool schemas are discovered only when needed.
-- Exercise every documented tool chain with successful, empty, ambiguous, paginated, and partially failed responses.
-- Verify source attribution and financial period semantics.
-- At a high level, test first sign-in, reconnect, expired-session recovery, cancellation, logout, and denied authorization in both clients.
-- Confirm no API keys, bearer tokens, or credentials are stored in the repository or plugin configuration.
-
-## Assumptions and Defaults
-
-- One repository and one shared set of skills will serve both clients; there will not be separate Claude and Codex forks.
-- OAuth is mandatory for the v2 plugin release and is completed before plugin integration begins.
-- Deferred MCP schemas are intentional; the initial-context requirement is satisfied through concise skill metadata, not eager-loading all 11 tools.
-- Existing REST API-key users remain supported; MCP and the distributed plugin expose OAuth only.
-- GitHub is the first distribution and validation channel; public marketplace submissions follow a successful stable release.
-