caspian-utils 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/docs/auth.md CHANGED
@@ -3,7 +3,7 @@ title: Authentication
3
3
  description: Manage session-backed authentication in Caspian with `casp.auth`, `AuthSettings`, the global `auth` object, centralized `auth_config.py`, page decorators, RPC protection, role-based routes, and optional Google or GitHub OAuth providers.
4
4
  related:
5
5
  title: Related docs
6
- description: Use the fetch-data guide when sign-in happens through RPC, then use the state guide for transient auth-adjacent request state, validation to guard credentials, and routing or project structure to place auth files correctly.
6
+ description: Use the fetch-data guide when sign-in or signout happens through RPC, then use the state guide for transient auth-adjacent request state, validation to guard credentials, and routing or project structure to place auth files correctly.
7
7
  links:
8
8
  - /docs/fetch-data
9
9
  - /docs/state
@@ -50,6 +50,7 @@ from casp.auth import (
50
50
 
51
51
  - Define app-wide auth behavior in `build_auth_settings()` and apply it once at startup with `configure_auth(...)`.
52
52
  - Use `auth.sign_in(...)` and `auth.sign_out(...)` instead of setting or clearing session keys directly.
53
+ - Prefer `pp.rpc(...)` plus `@rpc(require_auth=True)` for signout buttons or menus rendered in pages or components. Use a dedicated signout route only when you need a plain HTML form POST or a no-JavaScript fallback.
53
54
  - Use `@require_auth`, `@require_role`, and `@guest_only` for page access rules.
54
55
  - Use `@rpc(require_auth=True, allowed_roles=[...])` for browser-triggered actions that need protection.
55
56
  - Use `StateManager` only for transient auth-adjacent request state; keep the authenticated session itself owned by `casp.auth`.
@@ -112,12 +113,52 @@ Important behavior from the current implementation:
112
113
  - `default_token_validity` is parsed by the installed auth runtime with the format `^\d+(s|m|h|d)$`. Use values such as `30m`, `1h`, or `7d`.
113
114
  - `token_auto_refresh` only changes behavior when the request lifecycle calls `auth.refresh_session()`. In the installed `auth.py`, the flag alone does not refresh expiry by itself.
114
115
  - The framework `AuthSettings` dataclass defaults `is_all_routes_private=True`, but the project example above explicitly changes that to `False`.
116
+ - In generated app-owned config like this workspace, `src/lib/auth/auth_config.py` starts with `is_all_routes_private=False`, so routes are public by default until the app chooses stricter route protection.
115
117
  - `public_routes`, `auth_routes`, `private_routes`, and `role_based_routes` are exact path matches in the installed `Auth` methods.
116
118
  - `private_routes` matters only when `is_all_routes_private=False`.
117
119
  - `role_based_routes` currently expects `PATH -> [ROLES]`, not role names keyed to paths the other way around.
118
120
  - `role_identifier` defaults to `role`, and the current `auth.sign_in(...)` flow also normalizes `userRole` into `role` when possible.
119
121
  - `api_auth_prefix` defaults to `/api/auth` and should stay centralized here rather than being hard-coded across routes.
120
122
 
123
+ ## Choosing Public vs Private Route Mode
124
+
125
+ Make this decision at app setup time in `src/lib/auth/auth_config.py`.
126
+
127
+ - In the default app-owned starter pattern used in this workspace, routes start public because `is_all_routes_private=False` in `src/lib/auth/auth_config.py`.
128
+ - If the application has only a few public pages and most routes require auth, set `is_all_routes_private=True` and list the exceptions in `public_routes`.
129
+ - If the application has many public pages and only a few protected areas, keep `is_all_routes_private=False` and list only the protected routes in `private_routes`.
130
+ - In the current runtime, `auth_routes=["/signin", "/signup"]` stays public by default, and most apps do not need to change it unless the user explicitly asks for different auth routes.
131
+ - In all-private mode, the default `public_routes=["/"]` keeps the home page public unless you change that list.
132
+ - `token_auto_refresh=True` does not make routes private. It only enables sliding-session refresh when the request lifecycle calls `auth.refresh_session()`.
133
+ - You do not need to modify Caspian core files for this decision. Keep the policy in `src/lib/auth/auth_config.py`.
134
+ - If you customize `src/lib/auth/auth_config.py`, add it to `excludeFiles` in `caspian.config.json` so update commands do not overwrite your local auth policy.
135
+
136
+ Example all-private setup with a few public exceptions:
137
+
138
+ ```python
139
+ return AuthSettings(
140
+ default_token_validity="1h",
141
+ token_auto_refresh=False,
142
+ is_all_routes_private=True,
143
+ public_routes=["/", "/pricing", "/about"],
144
+ auth_routes=["/signin", "/signup"],
145
+ private_routes=[],
146
+ )
147
+ ```
148
+
149
+ Example mixed app with many public routes and only a few protected areas:
150
+
151
+ ```python
152
+ return AuthSettings(
153
+ default_token_validity="1h",
154
+ token_auto_refresh=False,
155
+ is_all_routes_private=False,
156
+ public_routes=["/"],
157
+ auth_routes=["/signin", "/signup"],
158
+ private_routes=["/dashboard", "/settings", "/billing"],
159
+ )
160
+ ```
161
+
121
162
  ## Environment Variables
122
163
 
123
164
  The installed auth code reads several values from `.env` when explicit values are not passed.
@@ -414,16 +455,58 @@ src/
414
455
  signup/
415
456
  index.py
416
457
  index.html
417
- signout/
418
- index.py
458
+ signout/
459
+ index.py
419
460
  dashboard/
420
461
  index.py
421
462
  index.html
422
463
  ```
423
464
 
424
- Use `guest_only()` on signin and signup routes, use `auth.sign_in(...)` inside the owning RPC action after validation and credential checks, and protect private destinations with `require_auth()` or central route policy.
465
+ Use `guest_only()` on signin and signup routes, use `auth.sign_in(...)` inside the owning RPC action after validation and credential checks, prefer RPC for signout UI actions, and protect private destinations with `require_auth()` or central route policy.
466
+
467
+ Preferred signout pattern: auth-protected RPC from a page or component.
468
+
469
+ Use this when the logout trigger lives in a page, layout, header, dropdown, or reusable component. The HTML can live at page level or component level.
470
+
471
+ ```html
472
+ <div>
473
+ <button onclick="signout()">
474
+ Sign out
475
+ </button>
476
+
477
+ <script>
478
+ async function signout() {
479
+ await pp.rpc("signout");
480
+ }
481
+ </script>
482
+ </div>
483
+ ```
484
+
485
+ ```python
486
+ from casp.auth import auth
487
+ from casp.rpc import rpc
488
+
489
+
490
+ @rpc(require_auth=True)
491
+ def signout():
492
+ return auth.sign_out()
493
+ ```
494
+
495
+ Fallback signout pattern: dedicated route.
496
+
497
+ Use this when you need a plain HTML form POST, a no-JavaScript fallback, or a full-route signout endpoint.
498
+
499
+ HTML:
500
+
501
+ ```html
502
+ <form action="/signout" method="post">
503
+ <button type="submit">
504
+ <span>Log Out</span>
505
+ </button>
506
+ </form>
507
+ ```
425
508
 
426
- Simple signout route example:
509
+ Route: `src/app/(auth)/signout/index.py`
427
510
 
428
511
  ```python
429
512
  from casp.auth import auth, require_auth
@@ -659,11 +742,17 @@ Validate and authenticate close to the input boundary.
659
742
  Common placement patterns are:
660
743
 
661
744
  - put centralized policy in `src/lib/auth/auth_config.py`
745
+ - decide public-vs-private route mode at app start in `src/lib/auth/auth_config.py` instead of scattering route privacy logic across route files
746
+ - use `is_all_routes_private=True` only when most routes should require auth; otherwise keep `is_all_routes_private=False` and maintain `private_routes`
747
+ - keep public exceptions in `public_routes`, and leave `auth_routes=["/signin", "/signup"]` alone unless the app explicitly needs different auth endpoints
662
748
  - call `configure_auth(build_auth_settings())` during startup
663
- - keep sign-in, signup, signout, and reset-password handlers in the owning route backend under `src/app/**/index.py`
749
+ - keep sign-in, signup, and reset-password handlers in the owning route backend under `src/app/**/index.py`
750
+ - prefer signout through `pp.rpc("signout")` with `@rpc(require_auth=True)` when the trigger lives in page or component UI
751
+ - use a dedicated signout route only for no-JavaScript, form-post, or full-navigation edge cases
664
752
  - use `@rpc()` for browser-triggered auth actions and page decorators for full-route protection
665
753
  - use `Validate` and `Rule` from `casp.validate` before password checks, user lookup, persistence, or external provider flows
666
754
  - keep reusable auth helpers in `src/lib/auth/`
755
+ - protect customized auth policy files from updater overwrite with `excludeFiles` in `caspian.config.json`
667
756
 
668
757
  For browser-triggered auth forms, pair this page with `fetch-data.md`. For credential and form validation, pair it with `validation.md`.
669
758
 
@@ -673,15 +762,22 @@ If an AI agent is deciding how to handle auth in Caspian, apply these rules firs
673
762
 
674
763
  - Treat `casp.auth` as the default authentication layer.
675
764
  - Centralize route visibility, redirects, and RBAC policy in `src/lib/auth/auth_config.py`.
765
+ - Decide route mode early in `src/lib/auth/auth_config.py`: use `is_all_routes_private=True` when most routes should require auth, otherwise keep `is_all_routes_private=False` and list protected routes in `private_routes`.
766
+ - In app-owned starter config like this workspace, treat `is_all_routes_private=False` as the default starting point, which means routes begin public until the app opts into stricter protection.
767
+ - Treat `public_routes` as the public exception list for all-private apps. In the current defaults, `/` stays public and `auth_routes=["/signin", "/signup"]` stays public too.
676
768
  - Apply settings at startup in `main.py` with `configure_auth(build_auth_settings())`.
677
769
  - Register provider instances in `main.py` with `Auth.set_providers(...)` when Google or GitHub OAuth is enabled.
678
770
  - Use `auth.sign_in(...)` and `auth.sign_out(...)` for session lifecycle changes.
771
+ - Prefer `pp.rpc("signout")` plus `@rpc(require_auth=True)` for logout buttons or menus in pages and components.
772
+ - Use a dedicated `/signout` route only for plain HTML form POST, no-JavaScript fallback, or other full-navigation edge cases.
773
+ - Do not treat `token_auto_refresh` as a route-privacy switch. In the current app it only affects sliding-session refresh if `auth.refresh_session()` is called.
679
774
  - Use `@require_auth`, `@require_role`, and `@guest_only` for page-level access rules.
680
775
  - Use `@rpc(require_auth=True, allowed_roles=[...])` for protected browser-triggered actions.
681
776
  - Keep `SessionMiddleware` outermost so auth, CSRF, and RPC handlers can read `request.session`.
682
777
  - Use [state.md](./state.md) only for transient auth-adjacent request state, not as the auth session store.
683
778
  - Align `SESSION_LIFETIME_HOURS` with `default_token_validity` unless you intentionally want different cookie and auth-payload expiry windows.
684
779
  - Prefer exact route strings in `public_routes`, `auth_routes`, `private_routes`, and `role_based_routes`.
780
+ - Protect customized `src/lib/auth/auth_config.py` from updater overwrite by adding it to `excludeFiles` in `caspian.config.json`.
685
781
  - Keep auth secrets and OAuth provider credentials in `.env`.
686
782
  - Set `AUTH_COOKIE_NAME` explicitly so the session middleware cookie name and auth settings stay aligned.
687
783
  - Use `.venv/Lib/site-packages/casp/auth.py` only when the task is about framework auth internals or debugging installed behavior.
@@ -3,10 +3,11 @@ title: Commands
3
3
  description: Use the current Caspian CLI reference to choose the right scaffold, starter-kit, update, and Prisma regeneration workflow for the current workspace.
4
4
  related:
5
5
  title: Related docs
6
- description: Start with installation for new apps, then use database and structure docs when commands affect schema, generated ORM files, or project layout.
6
+ description: Start with installation for new apps, then use database, MCP, and structure docs when commands affect schema, server tooling, generated ORM files, or project layout.
7
7
  links:
8
8
  - /docs/installation
9
9
  - /docs/database
10
+ - /docs/mcp
10
11
  - /docs/routing
11
12
  - /docs/project-structure
12
13
  - /docs/index
@@ -18,6 +19,8 @@ This page documents the current Caspian command families used with this workspac
18
19
 
19
20
  The current workspace includes a local `prisma` binary, but it does not include local `create-caspian-app`, `casp`, or `ppy` binaries under `node_modules/.bin`. Treat project creation, project update, and Python ORM generation as external `npx` workflows rather than project-local executables.
20
21
 
22
+ The current workspace also includes a local MCP run path through `npm run mcp`, which starts the app-owned FastMCP server via `settings/restart-mcp.ts`.
23
+
21
24
  Examples below use `npx create-caspian-app` for readability. If you want to force the latest published scaffold package explicitly, you can use `npx create-caspian-app@latest` instead.
22
25
 
23
26
  This updated reference includes the newer updater behavior and the current scaffold behavior:
@@ -29,7 +32,7 @@ This updated reference includes the newer updater behavior and the current scaff
29
32
  - Windows-safe execution that resolves `npx.cmd` on Win32
30
33
  - scaffold behavior that reuses an existing `.venv` instead of recreating it every time
31
34
 
32
- Before running update commands, read `caspian.config.json` because it controls feature flags and `excludeFiles` overwrite protection. In the current workspace that config shows `backendOnly: false`, `tailwindcss: true`, `mcp: false`, `prisma: true`, `typescript: false`, and `componentScanDirs: ["src"]`.
35
+ Before running update commands, read `caspian.config.json` because it controls feature flags and `excludeFiles` overwrite protection. In the current workspace that config shows `backendOnly: false`, `tailwindcss: true`, `mcp: true`, `prisma: true`, `typescript: false`, and `componentScanDirs: ["src"]`.
33
36
 
34
37
  ## 1. Main Command Families
35
38
 
@@ -66,6 +69,38 @@ npx casp update project
66
69
 
67
70
  Use when you are inside an existing Caspian project and want to refresh framework-managed files using the project's `caspian.config.json`.
68
71
 
72
+ ### Run the local MCP server
73
+
74
+ ```bash
75
+ npm run mcp
76
+ ```
77
+
78
+ Use when you want the workspace's app-owned FastMCP server only.
79
+
80
+ ### Run the full local stack including MCP
81
+
82
+ ```bash
83
+ npm run dev
84
+ ```
85
+
86
+ Use when you want BrowserSync, Tailwind, the Python app server, and MCP together.
87
+
88
+ ### Inspect the local MCP config directly
89
+
90
+ ```powershell
91
+ .venv\Scripts\fastmcp.exe inspect src/lib/mcp/fastmcp.json
92
+ ```
93
+
94
+ Use when you are debugging the nested FastMCP config or checking which tools the current MCP server exposes.
95
+
96
+ ### Run FastMCP directly with the nested config
97
+
98
+ ```powershell
99
+ .venv\Scripts\fastmcp.exe run src/lib/mcp/fastmcp.json --no-banner
100
+ ```
101
+
102
+ Use when you want the raw FastMCP path without the npm wrapper.
103
+
69
104
  ### Regenerate ORM after schema changes
70
105
 
71
106
  ```bash
@@ -80,6 +115,8 @@ npx ppy generate
80
115
 
81
116
  Use when `prisma/schema.prisma` changes and you need migrations, seed flow, and the generated Python ORM layer to stay aligned.
82
117
 
118
+ Because this workspace keeps `fastmcp.json` under `src/lib/mcp/`, plain `fastmcp run` from the project root does not auto-detect the config. Use `npm run mcp` or pass the explicit config path.
119
+
83
120
  ## 2. Supported Flags And Options
84
121
 
85
122
  ### For `create-caspian-app`
@@ -606,6 +643,10 @@ This is useful for protecting:
606
643
  - entry-point files
607
644
  - other locally modified framework-managed files
608
645
 
646
+ Auth example:
647
+
648
+ - add `./src/lib/auth/auth_config.py` to `excludeFiles` when you customize route privacy policy, public-route exceptions, redirects, or other app-specific auth settings there
649
+
609
650
  If you exclude a file, the updater preserves it, but you are responsible for merging future framework changes into that file manually.
610
651
 
611
652
  ## 10. Operational Notes
@@ -3,9 +3,10 @@ title: Fetch Data
3
3
  description: Fetch first-render and interactive data in Caspian with async route functions, `@rpc()` actions, `pp.rpc()`, streaming, and uploads, with RPC as the default browser-to-server data path.
4
4
  related:
5
5
  title: Related docs
6
- description: Use the routing guide to place route logic correctly, then use the auth guide for protected actions, the state guide for transient request-scoped mutation state, the cache guide for reusable first-render HTML, and the PulsePoint runtime guide for client-side `pp.rpc()` details.
6
+ description: Use the routing guide to place route logic correctly, then use the auth guide for protected actions, the MCP guide for AI-facing tools, the state guide for transient request-scoped mutation state, the cache guide for reusable first-render HTML, and the PulsePoint runtime guide for client-side `pp.rpc()` details.
7
7
  links:
8
8
  - /docs/auth
9
+ - /docs/mcp
9
10
  - /docs/state
10
11
  - /docs/database
11
12
  - /docs/cache
@@ -19,6 +20,8 @@ This page explains how data fetching works in Caspian. Use route functions for i
19
20
 
20
21
  Treat RPC as the default way for browser code to talk to Python in Caspian. Do not reach for ad hoc fetch calls to custom JSON endpoints, alternate transport layers, or older helper names unless the task explicitly requires that shape.
21
22
 
23
+ MCP is a separate integration surface. Do not place app-owned FastMCP tools in route `index.py` files or treat `@rpc()` actions as a replacement for MCP tools. In this workspace, MCP tool definitions live under `src/lib/mcp/` and are documented in `mcp.md`.
24
+
22
25
  ## Overview
23
26
 
24
27
  Caspian has two main data-loading paths:
@@ -7,6 +7,7 @@ related:
7
7
  links:
8
8
  - /docs/installation
9
9
  - /docs/commands
10
+ - /docs/mcp
10
11
  - /docs/project-structure
11
12
  - /docs/components
12
13
  ---
@@ -37,8 +38,9 @@ The packaged Caspian docs distributed by the current toolchain also live here:
37
38
 
38
39
  - `installation.md` - First-time setup flow for creating a new Caspian application
39
40
  - `commands.md` - Main Caspian CLI workflows for project creation, generation, updates, and config-aware maintenance
41
+ - `mcp.md` - Workspace FastMCP server layout, nested config path, local launch flow, and MCP-specific AI routing rules
40
42
  - `database.md` - Prisma schema, migration, seed, and client-generation workflow for the current workspace, plus Python-side helper caveats
41
- - `auth.md` - Session-backed authentication with `casp.auth`, centralized `auth_config.py`, decorators, RBAC, and OAuth provider helpers
43
+ - `auth.md` - Session-backed authentication with `casp.auth`, centralized `auth_config.py`, public-vs-private route mode guidance, RPC-first signout guidance, RBAC, and OAuth provider helpers
42
44
  - `components.md` - Create reusable Python components, template-backed UI, JSX-style imports, and the single-parent root rule for component HTML files
43
45
  - `pulsepoint.md` - Default reactive frontend runtime contract for component scripts, state, effects, directives, and client-side behaviors
44
46
  - `fetch-data.md` - Initial server-side data loading and browser-triggered RPC flows with `pp.rpc()`, streaming, uploads, and auth-aware actions
@@ -57,7 +59,7 @@ Preferred lookup order:
57
59
 
58
60
  1. Read `node_modules/caspian-utils/dist/docs/index.md` to discover available local docs.
59
61
  2. Read `./caspian.config.json` before making any feature assumption. Use it to confirm which project capabilities are enabled and which directories or tooling rules apply.
60
- 3. Read `database.md` for Prisma setup and ORM usage, `auth.md` for session auth and route protection, `components.md` for reusable UI authoring, `pulsepoint.md` for browser-side reactive runtime behavior, `fetch-data.md` for data flows, `state.md` for transient request-scoped state, `cache.md` for page caching, and `validation.md` for input boundaries.
62
+ 3. Read `database.md` for Prisma setup and ORM usage, `mcp.md` for the current FastMCP server layout and local run flow, `auth.md` for session auth and route protection, `components.md` for reusable UI authoring, `pulsepoint.md` for browser-side reactive runtime behavior, `fetch-data.md` for data flows, `state.md` for transient request-scoped state, `cache.md` for page caching, and `validation.md` for input boundaries.
61
63
  4. For authored component, route, and layout HTML files, generate exactly one top-level lowercase HTML element. Think React-style single parent wrapper: keep any owned PulsePoint logic in a plain `<script>` inside that root, do not handwrite `pp-component="..."` or `type="text/pp"` because Caspian injects those runtime attributes automatically, and treat `<!-- @import ... -->` comments as file-level directives that belong above the authored root element instead of inside `<div>`, `<section>`, or `<html>`. When several component tags come from one Python file, import them from that exact file path, for example `<!-- @import { Breadcrumb, BreadcrumbItem, BreadcrumbList } from "../components/Breadcrumb.py" -->`.
62
64
  5. Prefer local docs before generating code, commands, or migration guidance.
63
65
  6. Check `node_modules/caspian-utils/dist/docs/` for packaged Caspian docs when local docs need more detail.
@@ -3,8 +3,10 @@ title: Installation
3
3
  description: Learn how to create a new Caspian application so AI agents use the first-time setup flow instead of assuming an existing project is already in place.
4
4
  related:
5
5
  title: Related docs
6
- description: Continue with the routing and structure guides after scaffold so the new app follows Caspian conventions.
6
+ description: Continue with the routing, structure, and MCP guides after scaffold so the new app follows Caspian conventions and keeps optional FastMCP files in the right place.
7
7
  links:
8
+ - /docs/commands
9
+ - /docs/mcp
8
10
  - /docs/routing
9
11
  - /docs/project-structure
10
12
  - /docs/index
@@ -54,6 +56,8 @@ The interactive wizard walks through the main project options, including:
54
56
  - Feature toggles such as backend-only mode, Tailwind CSS, Prisma, MCP, and TypeScript
55
57
  - Other scaffold options exposed by the current CLI version
56
58
 
59
+ If the project enables MCP, use `mcp.md` after scaffold to place the app-owned FastMCP server and config files correctly for the current workspace conventions.
60
+
57
61
  ## Recommended VS Code Setup
58
62
 
59
63
  For the best development experience, use these VS Code extensions:
@@ -83,7 +87,8 @@ In this workspace, `npm run dev` is backed by BrowserSync plus PostCSS watchers,
83
87
  Once the project is scaffolded:
84
88
 
85
89
  - Read `database.md` when the app includes Prisma ORM support or needs database changes.
86
- - Read `auth.md` before wiring session config, sign-in or signout routes, route guards, or OAuth providers.
90
+ - Read `mcp.md` when the app includes MCP support or needs FastMCP server, config, or launch-flow changes.
91
+ - Read `auth.md` before choosing public-vs-private route mode, wiring session config, sign-in or signout flows, route guards, or OAuth providers.
87
92
  - Read `pulsepoint.md` before generating interactive frontend behavior.
88
93
  - Read `fetch-data.md` before adding browser-triggered reads, writes, uploads, or streams.
89
94
  - Read `validation.md` before handling forms, auth input, or RPC payloads.
@@ -97,5 +102,6 @@ If an AI agent is reading this page, treat it as the source for new-project inst
97
102
  - Use this workflow when the user is creating a Caspian app from scratch.
98
103
  - Do not use existing-project migration or update commands unless the project already exists.
99
104
  - After scaffold, default to PulsePoint for interactive UI, RPC for browser-to-server data flow, and `casp.validate` for validation.
105
+ - If MCP is enabled, read [mcp.md](./mcp.md) before editing FastMCP files or assuming where the server config should live.
100
106
  - Once the app exists, check [routing.md](./routing.md) before creating or changing routes under `src/app/`.
101
107
  - Check [index.md](./index.md) first when deciding which local doc to follow.
@@ -0,0 +1,102 @@
1
+ ---
2
+ title: MCP
3
+ description: Use the workspace FastMCP setup through src/lib/mcp/mcp_server.py, src/lib/mcp/fastmcp.json, and settings/restart-mcp.ts, with npm-driven startup and explicit manual paths when running FastMCP directly.
4
+ related:
5
+ title: Related docs
6
+ description: Start with project structure for file placement, then use commands for local run flows and index for documentation routing.
7
+ links:
8
+ - /docs/project-structure
9
+ - /docs/commands
10
+ - /docs/fetch-data
11
+ - /docs/index
12
+ ---
13
+
14
+ This page documents the Model Context Protocol workflow present in this workspace.
15
+
16
+ The current repo enables MCP in `caspian.config.json`, keeps the app-owned FastMCP server at `src/lib/mcp/mcp_server.py`, keeps the FastMCP config at `src/lib/mcp/fastmcp.json`, and starts it through `npm run mcp`, which runs `settings/restart-mcp.ts`.
17
+
18
+ ## Overview
19
+
20
+ Use these rules as the default MCP workflow in this workspace:
21
+
22
+ 1. Read `caspian.config.json` and confirm `mcp: true` before assuming MCP files should exist or be started.
23
+ 2. Edit `src/lib/mcp/mcp_server.py` when changing FastMCP tools, server instructions, or server-owned helper logic.
24
+ 3. Edit `src/lib/mcp/fastmcp.json` when changing the transport, host, port, path, or server entrypoint.
25
+ 4. Edit `settings/restart-mcp.ts` when changing discovery order, environment overrides, or MCP log filtering.
26
+ 5. Use `npm run mcp` as the normal local launch flow.
27
+
28
+ ## Current Workspace Layout
29
+
30
+ - `src/lib/mcp/mcp_server.py` defines `mcp = FastMCP(...)` and the current workspace tools.
31
+ - `src/lib/mcp/fastmcp.json` points to `src/lib/mcp/mcp_server.py` and configures `streamable-http` on `127.0.0.1:5101/mcp`.
32
+ - `settings/restart-mcp.ts` is the npm-facing launcher. It resolves MCP config paths, starts FastMCP, and trims noisy banner or warning output down to essential lines.
33
+ - `package.json` defines `npm run mcp` as `tsx settings/restart-mcp.ts` and includes `mcp` in `npm run dev`.
34
+ - `caspian.config.json` is the feature gate. If `mcp` is false, the MCP runner exits cleanly without starting a server.
35
+
36
+ ## Current Tools
37
+
38
+ The app-owned MCP server currently exposes these read-only tools:
39
+
40
+ - `project_info` returns the project name, root path, version metadata, browser sync target, feature flags, and component scan directories.
41
+ - `workspace_files` returns the generated workspace file list, optionally filtered to `all`, `app`, or `public`.
42
+ - `component_inventory` returns the latest generated component map from `settings/component-map.json`.
43
+
44
+ Add or change tools in `src/lib/mcp/mcp_server.py`.
45
+
46
+ ## Running The Server
47
+
48
+ ### Preferred local commands
49
+
50
+ ```bash
51
+ npm run mcp
52
+ npm run dev
53
+ ```
54
+
55
+ Use `npm run mcp` when you want the MCP server only. Use `npm run dev` when you want BrowserSync, Tailwind, the Python app server, and MCP together.
56
+
57
+ ### Direct FastMCP commands
58
+
59
+ On this Windows workspace, the direct FastMCP commands are:
60
+
61
+ ```powershell
62
+ .venv\Scripts\fastmcp.exe inspect src/lib/mcp/fastmcp.json
63
+ .venv\Scripts\fastmcp.exe run src/lib/mcp/fastmcp.json --no-banner
64
+ ```
65
+
66
+ Because the config file lives under `src/lib/mcp/`, plain `fastmcp run` from the project root does not auto-detect it. Use `npm run mcp` or pass the explicit config path.
67
+
68
+ ## Config And Discovery Rules
69
+
70
+ `settings/restart-mcp.ts` currently resolves MCP server specs in this order:
71
+
72
+ 1. `MCP_SERVER_SPEC`
73
+ 2. `src/lib/mcp/fastmcp.json`
74
+ 3. `fastmcp.json`
75
+ 4. `mcp.json`
76
+
77
+ The runner also forwards these optional overrides to FastMCP:
78
+
79
+ - `MCP_TRANSPORT`
80
+ - `MCP_HOST`
81
+ - `MCP_PORT`
82
+ - `MCP_PATH`
83
+ - `MCP_LOG_LEVEL`
84
+
85
+ Keep the `source.path` value in `src/lib/mcp/fastmcp.json` root-relative as `src/lib/mcp/mcp_server.py`. Do not shorten it to `mcp_server.py` unless the launch working directory changes too, because FastMCP resolves that path from the current working directory.
86
+
87
+ ## AI Routing Notes
88
+
89
+ If an AI tool is working on MCP in this workspace, use this order:
90
+
91
+ 1. Read `caspian.config.json` to confirm `mcp: true`.
92
+ 2. Read `node_modules/caspian-utils/dist/docs/mcp.md` for the current workspace MCP rules.
93
+ 3. Read `src/lib/mcp/mcp_server.py` for tool definitions and server instructions.
94
+ 4. Read `src/lib/mcp/fastmcp.json` for transport and entrypoint configuration.
95
+ 5. Read `settings/restart-mcp.ts` and `package.json` for local start behavior.
96
+
97
+ Default placement rules:
98
+
99
+ - Put app-owned FastMCP tools in `src/lib/mcp/mcp_server.py`.
100
+ - Keep the default FastMCP config in `src/lib/mcp/fastmcp.json`.
101
+ - Keep npm-facing launch behavior in `settings/restart-mcp.ts`.
102
+ - If the MCP file layout changes, update this page, `AGENTS.md`, `.github/copilot-instructions.md`, and any workspace runner logic together.
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  title: Project Structure
3
- description: Understand the default Caspian project layout so AI agents place routes, reusable components, PulsePoint templates, RPC actions, validation helpers, auth code, configuration, and database changes in the correct directories.
3
+ description: Understand the default Caspian project layout so AI agents place routes, reusable components, PulsePoint templates, RPC actions, validation helpers, auth code, MCP files, configuration, and database changes in the correct directories.
4
4
  related:
5
5
  title: Related docs
6
- description: Start with installation for new apps, then use the component guide for reusable UI, the auth guide for bootstrap and session wiring, the routing guide to map URLs correctly, and the cache guide when route HTML should be reused safely.
6
+ description: Start with installation for new apps, then use the component guide for reusable UI, the auth guide for bootstrap and session wiring, the MCP guide for server layout, the routing guide to map URLs correctly, and the cache guide when route HTML should be reused safely.
7
7
  links:
8
8
  - /docs/installation
9
9
  - /docs/components
10
10
  - /docs/auth
11
+ - /docs/mcp
11
12
  - /docs/routing
12
13
  - /docs/cache
13
14
  - /docs/database
@@ -31,6 +32,7 @@ Before an AI agent decides which Caspian features are available in a workspace,
31
32
  - `src/` contains routes, page templates, styles, and shared libraries.
32
33
  - `src/components/` contains reusable Python components and optional same-name HTML templates.
33
34
  - `src/lib/auth/auth_config.py` contains auth-specific configuration for the app.
35
+ - `src/lib/mcp/` contains the app-owned FastMCP server and nested FastMCP config when MCP is enabled.
34
36
  - `prisma/` contains the Prisma schema and seed scripts.
35
37
  - `public/` contains static assets served directly.
36
38
  - `main.py` is the application entry point.
@@ -62,6 +64,9 @@ my-app/
62
64
  lib/
63
65
  auth/
64
66
  auth_config.py
67
+ mcp/
68
+ fastmcp.json
69
+ mcp_server.py
65
70
  prisma/
66
71
  __init__.py
67
72
  db.py
@@ -112,6 +117,8 @@ Use this folder for shared helpers, reusable validators, RPC-facing service wrap
112
117
 
113
118
  This workspace already includes an app-owned Python database layer under `src/lib/prisma/`. Reuse that package for Python-side data access and keep any additional shared database helpers in `src/lib/`.
114
119
 
120
+ When MCP is enabled in the current workspace, this folder also contains the app-owned FastMCP server under `src/lib/mcp/`.
121
+
115
122
  ### Shared Database Helpers
116
123
 
117
124
  If your Python routes or RPC actions need reusable database access code, keep that helper layer under `src/lib/` and extend the existing `src/lib/prisma/` package.
@@ -122,6 +129,17 @@ In this workspace, Prisma schema and seed files live under `prisma/`, while the
122
129
 
123
130
  Use this folder for authentication-specific project code. The main auth configuration file lives at `src/lib/auth/auth_config.py`.
124
131
 
132
+ ### `src/lib/mcp/`
133
+
134
+ Use this folder for app-owned Model Context Protocol server files.
135
+
136
+ In the current workspace:
137
+
138
+ - `src/lib/mcp/mcp_server.py` defines `mcp = FastMCP(...)` and the current tool set.
139
+ - `src/lib/mcp/fastmcp.json` is the default FastMCP config used by `npm run mcp`.
140
+
141
+ Keep MCP tool definitions here instead of placing them in route files, `main.py`, or framework internals.
142
+
125
143
  ### `prisma/`
126
144
 
127
145
  This folder contains your database model definitions in `schema.prisma` and any seed logic such as `seed.ts`.
@@ -153,12 +171,22 @@ The core feature configuration file for the application.
153
171
 
154
172
  AI agents should read this file before making almost any feature-level decision. Use it to confirm which capabilities are enabled, which code generation paths make sense, and which directories should be scanned for components or other project assets.
155
173
 
156
- In the current workspace, `caspian.config.json` shows `backendOnly: false`, `tailwindcss: true`, `mcp: false`, `prisma: true`, `typescript: false`, and `componentScanDirs: ["src"]`.
174
+ In the current workspace, `caspian.config.json` shows `backendOnly: false`, `tailwindcss: true`, `mcp: true`, `prisma: true`, `typescript: false`, and `componentScanDirs: ["src"]`.
157
175
 
158
176
  ### `src/lib/auth/auth_config.py`
159
177
 
160
178
  The project auth configuration file. Use this path when changing authentication behavior.
161
179
 
180
+ ### `src/lib/mcp/mcp_server.py`
181
+
182
+ The app-owned FastMCP server module for this workspace. It exports the `mcp` server instance and should be the default place for workspace MCP tools.
183
+
184
+ ### `src/lib/mcp/fastmcp.json`
185
+
186
+ The default FastMCP config file for this workspace.
187
+
188
+ Because this file is nested under `src/lib/mcp/`, direct FastMCP commands should pass the explicit path, for example `fastmcp run src/lib/mcp/fastmcp.json`, unless the launch working directory changes.
189
+
162
190
  ### `src/app/layout.html`
163
191
 
164
192
  The root layout shared across pages.
@@ -204,9 +232,11 @@ If an AI agent is deciding where to make changes, use these rules first.
204
232
  - Put route templates and route-specific backend logic in `src/app/`.
205
233
  - Check [routing.md](./routing.md) when you need URL segment rules, layout nesting behavior, or dynamic route conventions.
206
234
  - Put reusable component files in `src/components/` and check [components.md](./components.md) for `@component`, `render_html(__file__)`, import comments, and single-root template rules.
235
+ - Use [mcp.md](./mcp.md) when the task involves FastMCP tool definitions, nested config discovery, or local MCP commands.
207
236
  - Keep `<!-- @import ... -->` comments above the single authored root element in route, layout, and component HTML files.
208
237
  - For route and component HTML files, always emit one top-level lowercase HTML element. Good: one wrapper containing the content and a plain `<script>` when needed. Bad: a wrapper element followed by a sibling top-level `<script>`, or handwritten `pp-component="..."` and `type="text/pp"` attributes in source.
209
238
  - Put shared helpers and reusable libraries in `src/lib/`.
239
+ - Put app-owned FastMCP code in `src/lib/mcp/`.
210
240
  - Use PulsePoint conventions in route templates for reactive frontend behavior.
211
241
  - Use `@rpc()` in route/backend code and `pp.rpc()` in client code for browser-triggered data flows.
212
242
  - Use `casp.cache_handler` when a route's first-render HTML should be reused safely across requests.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "caspian-utils",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Caspian tooling",
5
5
  "main": "index.js",
6
6
  "scripts": {