From f29708bb3eab5293757b39a119ec782cd2d01db9 Mon Sep 17 00:00:00 2001 From: abhijitt-code Date: Wed, 23 Sep 2026 18:05:52 +0530 Subject: [PATCH 1/3] Serve the TypeScript-style MCP docs page on Python GET /. --- .gitignore | 9 + MANIFEST.in | 1 + README.md | 3 + .../calculator_server.cpython-312.pyc | Bin 10920 -> 0 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 2119 -> 0 bytes .../auth/__pycache__/api_key.cpython-312.pyc | Bin 4151 -> 0 bytes .../auth/__pycache__/config.cpython-312.pyc | Bin 4059 -> 0 bytes .../auth/__pycache__/jwt.cpython-312.pyc | Bin 6834 -> 0 bytes .../auth/__pycache__/oauth.cpython-312.pyc | Bin 11222 -> 0 bytes nitrostack/cli/install.py | 2 + nitrostack/cli/main.py | 9 +- nitrostack/cli/pack.py | 2 + nitrostack/cli/vendor.py | 199 +++ .../additional_decorators.cpython-312.pyc | Bin 6896 -> 0 bytes .../core/__pycache__/app.cpython-312.pyc | Bin 33340 -> 0 bytes .../core/__pycache__/context.cpython-312.pyc | Bin 8564 -> 0 bytes .../__pycache__/decorators.cpython-312.pyc | Bin 8239 -> 0 bytes .../core/__pycache__/di.cpython-312.pyc | Bin 3734 -> 0 bytes .../core/__pycache__/errors.cpython-312.pyc | Bin 1666 -> 0 bytes .../core/__pycache__/module.cpython-312.pyc | Bin 1734 -> 0 bytes .../core/__pycache__/pipeline.cpython-312.pyc | Bin 14141 -> 0 bytes .../core/__pycache__/task.cpython-312.pyc | Bin 5304 -> 0 bytes nitrostack/core/app.py | 56 + .../__pycache__/event_emitter.cpython-312.pyc | Bin 3572 -> 0 bytes .../templates/flight-booking/.gitignore | 1 + nitrostack/templates/pizzaz/.gitignore | 1 + nitrostack/templates/starter/.gitignore | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 4812 -> 0 bytes nitrostack/transports/assets/landing.html | 1469 +++++++++++++++++ nitrostack/transports/assets/logo.png | Bin 0 -> 84321 bytes nitrostack/transports/http.py | 81 +- nitrostack/transports/landing_page.py | 120 ++ pyproject.toml | 2 +- .../test_basic.cpython-312-pytest-9.0.2.pyc | Bin 11792 -> 0 bytes ..._initial_tool.cpython-312-pytest-9.0.2.pyc | Bin 4757 -> 0 bytes .../test_oauth.cpython-312-pytest-9.0.2.pyc | Bin 9410 -> 0 bytes ...st_production.cpython-312-pytest-9.0.2.pyc | Bin 18648 -> 0 bytes .../test_tasks.cpython-312-pytest-9.0.2.pyc | Bin 16390 -> 0 bytes ...dget_metadata.cpython-312-pytest-9.0.2.pyc | Bin 6602 -> 0 bytes tests/test_cli.py | 8 + tests/test_cli_install.py | 22 +- tests/test_transport_http.py | 56 +- tests/test_transports.py | 2 +- tests/test_vendor.py | 63 + 44 files changed, 2037 insertions(+), 70 deletions(-) delete mode 100644 examples/__pycache__/calculator_server.cpython-312.pyc delete mode 100644 nitrostack/__pycache__/__init__.cpython-312.pyc delete mode 100644 nitrostack/auth/__pycache__/api_key.cpython-312.pyc delete mode 100644 nitrostack/auth/__pycache__/config.cpython-312.pyc delete mode 100644 nitrostack/auth/__pycache__/jwt.cpython-312.pyc delete mode 100644 nitrostack/auth/__pycache__/oauth.cpython-312.pyc create mode 100644 nitrostack/cli/vendor.py delete mode 100644 nitrostack/core/__pycache__/additional_decorators.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/app.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/context.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/decorators.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/di.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/errors.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/module.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/pipeline.cpython-312.pyc delete mode 100644 nitrostack/core/__pycache__/task.cpython-312.pyc delete mode 100644 nitrostack/events/__pycache__/event_emitter.cpython-312.pyc delete mode 100644 nitrostack/testing/__pycache__/__init__.cpython-312.pyc create mode 100644 nitrostack/transports/assets/landing.html create mode 100644 nitrostack/transports/assets/logo.png create mode 100644 nitrostack/transports/landing_page.py delete mode 100644 tests/__pycache__/test_basic.cpython-312-pytest-9.0.2.pyc delete mode 100644 tests/__pycache__/test_initial_tool.cpython-312-pytest-9.0.2.pyc delete mode 100644 tests/__pycache__/test_oauth.cpython-312-pytest-9.0.2.pyc delete mode 100644 tests/__pycache__/test_production.cpython-312-pytest-9.0.2.pyc delete mode 100644 tests/__pycache__/test_tasks.cpython-312-pytest-9.0.2.pyc delete mode 100644 tests/__pycache__/test_widget_metadata.cpython-312-pytest-9.0.2.pyc create mode 100644 tests/test_vendor.py diff --git a/.gitignore b/.gitignore index 2cab5e6..513a6b4 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,15 @@ flight-book-app/ my-pizza-app/ my-test-server/ new-app/ +my-app/ +y-server/ + +# Vendored SDK copies from `nitrostack-py init` (user projects only) +vendor/ + +# Local preview captures +.landing-preview.png +*-landing-preview.png # Node widgets (if installed locally in examples/templates) node_modules/ diff --git a/MANIFEST.in b/MANIFEST.in index 1fd03b5..b3d51d6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ recursive-include nitrostack/templates * recursive-include nitrostack/cli/templates * +recursive-include nitrostack/transports/assets * include nitrostack/templates/starter/.python-version include nitrostack/templates/starter/.gitignore include nitrostack/templates/starter/uv.toml diff --git a/README.md b/README.md index 91f98b7..0654181 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ nitrostack-py dev --port 4000 --widget 4001 nitrostack-py start --port 4000 --widget 4001 ``` +`init` / `install` vendor this SDK into `vendor/nitrostack` and pin it with `[tool.uv.sources]` so NitroCloud `uv sync` and Open URL use this documentation page (not the older PyPI stub). Do not put a `file:` URL in `[project].dependencies` — that breaks the cloud wheel metadata. + Once scaffolded, follow the next steps printed by the CLI to run your server, configure environment variables, and try it out. --- @@ -260,6 +262,7 @@ NitroStack apps can run over three transports, selected via `MCP_TRANSPORT_TYPE` - **`stdio`** (default outside production): JSON-RPC over stdin/stdout — the standard mode for desktop MCP clients (Claude Desktop, Cursor, etc.). - **`http`**: Streamable HTTP + legacy SSE over a real network port, for cloud/remote deployments. Exposes: + - `GET /` — documentation landing page (connection setup for Cursor/Claude/ChatGPT plus the registered tool catalog). Same page TypeScript NitroStack serves on Open URL. - `POST/GET/DELETE /mcp` — Streamable HTTP (session-based JSON-RPC + SSE streaming). `/mcp` and `/mcp/` are equivalent; the server does not 307 between them (MCP Inspector needs the no-slash URL for its SSE GET). - `GET /sse` + `POST /mcp/messages/` — legacy HTTP+SSE for older clients (trailing slash required so messages aren't swallowed by the Streamable HTTP `/mcp` mount) - `GET /mcp/health` — health check (`status`, active session count, uptime) diff --git a/examples/__pycache__/calculator_server.cpython-312.pyc b/examples/__pycache__/calculator_server.cpython-312.pyc deleted file mode 100644 index f0de6648f3872011385f996a793af97768d2a3ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10920 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 W>>JNsW&V=;oM|jLDP{w)c>f8;hf}No diff --git a/nitrostack/__pycache__/__init__.cpython-312.pyc b/nitrostack/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index d4322cd1c9df9e64ba9cea25f4ea1508f48e2460..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2119 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 b)s@n(AJX1$g%%pD5FntC@XTZES_=Ia6x?iA diff --git a/nitrostack/auth/__pycache__/config.cpython-312.pyc b/nitrostack/auth/__pycache__/config.cpython-312.pyc deleted file mode 100644 index f7f1b56225c5d3472aabd676f63a5ae050feb956..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4059 zcmb6cZERE5^}a8^=a1MXhR`NJUgDtO4!eZ$wE%&XgcTZswruL~GK}$i4h}DNxbK+| z>!n2O?MUBr{nR6Hg{PtfmYqp0Yn_!@BBXJX#yHGW!BTsMTcTd7k-&?3Q|-LT)Kc!27$ zXmrgh-Wz<}3-|PsIyiDVGc=&$tC^JAPwLd{)kHd@sfp2~aft*nL)jcw6AqO~ikeR5 zHA5%ft4S@RBn>r@&ZZof!Xc3ae;oX+ybkal${-UZDBT(+hnq|^>@3&J!*tKOVRDYc z7|`;+?lO2s&9KYCYV#V6tp3k6vh>{R#;|uC0hT7?XuyARBg1hh&=p2uA8`+>_t=jn z1XJiizqpIggv)dd2VT_WJW$HVn?PpMi!uto`aR}$yCRsbt4L>V?*{462GT<9`42)E zOo$VbDSqd-MN|4N{zg0qn`$6|c4=eJnBoy?EoqH~H}Hlnb^F&m1ONm&{G5OUkMp>N z1-P+(=LEW6krba67zs{zX+ki)N}a=dhZ#rXD2zJ5Vq+|W&LIYVx1-m%b7+hSBV)5; z!8U|XPq;x7(!3KM(=+^%!>P@~O*P!X6t~H|j}(vT2I&1jaJ~$u-&n_XXJ>78UI9Iy zf+pN=xo^K^&tuFOvdhfB+YBR80T<7evT$rqaE0C z+ENpXY$9SJWu*_|%8$}iK-ip4L`W7HoXZm4N+B-wT1JO_!RJQRED>}AXGV!fH6^AL0?$fEfyk>mUb)s|d zr@D&u!J%Z{NDkIM8XX-sF6FXOUAer5ItWsi25no!Mxj(B5*gT&NE8}uD^~Ms%%Rg< zqhA20T}Kr^+V#p!{ugR@;TUGve!@bL;8tP6j-<>krfTxfpmUt5lS*zt+nGRc>l z!}kkQh4;-#{z-Fq+L(QN=IwcXvHfs)TU)tl$8_6!hs)vi+0L2Hxzv2eLU{jF&t&)H zm9pG2E6#|&cTaY&qO*aSz`U>^9{^hH)ybaweN%mNo2Jf|cSr4`O<#HM%yI~|v_9id z!*OQ075TP43GJ9P?weEQVrchg!QLkgyNZ!F78?4B!M=)sHb*NQ2t5l^`Qnyi-#%?X zo40?B_`2|y!NzhhbkB3wvlNs|LAe-y{p0N)2a0c=E5?6bJU3VzJYQ@{ECw$;C$$u8 zEd^V@t++wMH~Jy4^hbOAy?*pjSFD%i{u=Gx1=HUeBp^Lzg4U74(|dS@1dXrfKI;wFBHcpWj}zzrsrQ4?0S_7(mvrjDhEP$%vxE`iUG)7?*HvtkC#^X;yiAVUzxS0AM4p|6S#tc2_HTTR*LDENmsmZKfz*G?{bcM4~iFSa&T1d2e)Xxvc|EmT6GrpbNq00yR|sjgD}D;2jz_n?Ly zlb7cBxqP{ta7V;un2uH4}GuzeXvUv zRbG{9eJ=FDE)_c28Ws9rp~koSV5h9cJ<#b&xEnszzpgY8$!TJr>tLy+t)MWh;~CXn zhxUFZYjP(4hT4fBV z)Wn$95Bt$)vQP}ODV6xKIs}DQ#R<4mUX8d2m(uk0N_yx<5lS0v_jP(v$SN?bw??Ei z#1PKqjKY?+K8!hJ`Z#r(>8_)vK@^h9jqT-a-z#s~UVce_>J~zto8nU+a&KOe5fv(|g1adB7zG;z z%xTIvP5}){J5s2JEjJ$oM9%@ZfxZxe5D%-ta_q#i*Dr*uSb@13DiqrwQYhI&1L)B7 zPv*jN`rNLW^ToD(^GdO;v($9BRDa}as%(Wru1(7=sAKSpLRt;M(rDZhD+9S8q?GBes$*d=?n=$?AOoDjdTwpCI?= zXwL%L^BIbKjt=~r@&0n#Gd9MwR1g5T0PC;N#(l%Lp zw?fs*Vp(mY{SmXUA`zA9s{ANgB)ZZ{i}oMdKQXQpGZby4+@f3n2k=HepJdL*}FRt9Ccge_?g*|jpCa3q}}Cqq~=MnvHv5lz=v zeb$hRC6ZkQ%WS3l4!I#hL&l%fYRC=kOd+U++~Qh68%SXimb$m9Q^ST zFL9l~B??Aq!Xlb3;=auiH^GXQi+so=S|zASmI+ql#U5U?L623m!zkv)Ug&W^j}7+X zQfgo`DS+ z$A&vXWpePhHVkBeWS9&ILrG5=7HU=H5|ZJdR#iUKc&MSImS#zS8NbR?)DN{IaUgL5 z2?#1LONoii`ea;+AJY#9M)#k7NtUR5dNMMjL{6t-3QfyOBzk6GdRCcArv_y4OhfBw z;F>xeKc@tzXH`oWb{bQ{;W4Ja%S1*o3lHH{c8gv1*)Ty4&fxT(%zl#HvJ zWipJ+iVWr_Nq`+!w~5l(uqaJLW)e!cdc0?(*>GJi0bXU(vTBAykI{5WbY?W)caGj7`xAMbxs8zx|ZVj*fu0%Y(p}`q4mtb zd85&RHM%wkK$Ut#t9BcjHtz>%YgHQW`i2D3wwm-N{UB{aY0<86`Ty^ou%cZX#{rh# z^#PmZ#U`c2Sd7@Lv>Iiw-R_HgR$xg+P}+^wI6k%wDZ?9jig$15f~weJ^cs2A^fSg} z4ep;gra5DJpNO7}`F-+d?#E@a7C0f_y(=|N{U@ZY%2q=*?l(&HJY&sRlwPAA?>9>I z{94rs#nEPMNX8nnHq=qZW@sU6ukR0bX@^}3CrKYs4F6903FR5`3c19*tDGa}xmU(Py(*KujrTxhWR(Mdt8(CKfkYHlIC^sMvArq>wl=^* zXJS(2l-X&O7b8l9;{CYC&!9nFn*suUre-iVGlrR(A=}L3h>Wq_c+Dunpw%SSt_1iS zZhQ?V8u>w(Q6>iVfoCzj8Ih&EL#lg*CgjM36n=B>5P*oZ2rz=m3XM&xCQ-tAfT24< zR>lFUPR0q$AO~;+8RmiwegIW4Ou zeLobRrOHnwBT%HLA{95oKkx!3e61q`Q7c zqweS0?{g^l8f74y=NgapZVjjbB?mTIqxXi`&Zk#b7K|O=Jb|5?F&!LKT$oN z(VLz}Z}n_j?7y;WY1j3>>x0X^drLi!-{>#)9Go93dpj4x^WhcmK+!u;h~D%LZpPbN z>>2)V7c zA4c98$-h*1r0CmQ?%jT6U}>P*SBAa=?;OZKR&W%%hp=zw(#~3+u7X>=4>gQz4BF{0 zc#G~`Ia7satj{u+g$lv^>|fenm?-r>Ivus?>L+9Jw)B z>U=8aD!aW4Tj#fy+`TLAK+zp2JX~@Q=1jL*I~I=4AI-nK`1+@(K70L>*GsL3S6WXL zTThf)pUGLj>Ud}|R_b^(=Ui>sa%oHc`TVc)$-?f!YlUZ*n}(My!~eOvo3#4ABaG9l zHn&zd$bXR0vE@hI$K2!#xAj;L_l1uEstVd;-W>SF!8qer#b&^-ZlAKOQZ?cT3k<6z zvS%L0uL-4wrt3iOZGeiWK_<&(!KsS8Qp47wpjcp?S^}qQ0;g-raNx|C46iveyU|e{Kus&N|PZI-wbwGGUhrwh}Xb@Ap>C8aAq}#(9l;cX04({ zv^Ho=Fjg;G=Rgm0;KVebX;bif6kZJ9BWtrUrP^w_yUP)=#3gDhGfx$5}!j%0LM>q&#HEZ3+jfooB#=t-Cu8V??++ zB);7kqn^`1#t}!qvmuF2LvnMudv2-A;MZo_v0*r<-gl-ZLlS1%MDCuMnhk!K$pL=c zJx+&U{M&eo<~+wzXCsN2=m$&hpGebWL zG4(qbhY!4sDFg4m@qTGILuE#8BQHi_5>krpg7P|$Q3VyOwo?486vbF-a@{wq0WWmc zb@1Y>L}L@P_kkBW|FbZoJOJbZDYtdzpTF!`eEy@h!nUQZ_g*iyJ(3%%gN{Sj%~wy9 zJo}a%`|1#bz5ufHB#^llL&G)q8>Bs2$BT$>{D2GmdL%{+(tfSuP&F9iPsU_8kmyv9 z;&q;DKBmQH>dk>RRgk9>5CwS=`c>P@k;II2gwiynh%_mpB>Dsrgd_AxB!`gv63Hl% z!$?rU^d%swE1FJDM*u?T=!A}7qktdnG95&&{YbR94L&nHc;nO|%(%u2(uz!vV&^d= zPa`>n{**92f*|Y4}v$}h4(GtwrE}dBP zRe09=iw{m#2xOOETEnbjBff_p)VsEKFPxu0zi2AB{$~EW>#wd-``AkRc(HxF)c#z~ zvD)IzyFWO&=qvelUEfyp?J0KdDYgvd%(uMVRScB8F z3&N7?)7H;AKk58S_m}>4gCJY826;|>`09JF7QDEuq0dG>8Tr!pWaDf)BjTUOKRoc> zfyJ3p_rUem&$>V9{<2#iaaXD3(PhV@t4(b=m-ZsA@>(D=eDcWX3rAj5xxt~S@$rBi z19GWIQVNGvTR5zTRiW$%hu?yWp!ew47%dM)V4+`Q9!qGw=rc$#6nPb50a(WH6~)Mf zM$iw-zXfuUz_PdQEO%`MxK{S}-?7^S-)cv9MSvW-yd4!YmMp~6o!>J*P_bgoM%Gt>7X6lSU%EBX&4>kjU6`iR%3MqBD1t`YG%(9(=q`}E&BWs?cL&Pt+sa;F z+0%K~DtK%;^IZqAwys$GMT@^=>0PnxE?Rbfy5q*=O$!7(TXHu2tlxk!0%q;M15|`E zm4K-BXd)uZNeKehV#5VbBf|ue`c=k5(@ri01^GE37s;y7yzw@>1dn!`A+O$MEY)u_ z){NWyogHdx95K1?uu#$_3pDF?9j(3YB{T=2xdjB7stKYI;9>Pwhv!f6O{#76Kyxsf zrczLU#T2!zwruPaV-!zQKUZyM>vyYKhIRRa6z>P3Z5e$Ed|5Ee*Tio8y1pjPuZi_v wWP6cp|Aqv@7ZR?Qz1ZL!)(_btZEznAKrbDZvX%Q diff --git a/nitrostack/auth/__pycache__/oauth.cpython-312.pyc b/nitrostack/auth/__pycache__/oauth.cpython-312.pyc deleted file mode 100644 index f451c9a499d8cf951f752151534af65f0d1e4abc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11222 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 diff --git a/nitrostack/cli/install.py b/nitrostack/cli/install.py index 2bb09d3..951fddb 100644 --- a/nitrostack/cli/install.py +++ b/nitrostack/cli/install.py @@ -186,6 +186,8 @@ def install_dependencies( ) print("NITROSTACK — Install" + (" (production)" if production else "")) + from nitrostack.cli.vendor import ensure_vendored_nitrostack + ensure_vendored_nitrostack(root) local_pin = requirements_uses_local_nitrostack(requirements) use_uv = bool(_uv_bin() and os.path.isfile(pyproject) and not local_pin) print(f"Target: {venv_dir(root)}") diff --git a/nitrostack/cli/main.py b/nitrostack/cli/main.py index d624ad8..1ab03b3 100644 --- a/nitrostack/cli/main.py +++ b/nitrostack/cli/main.py @@ -1299,6 +1299,8 @@ def init_project(name: str = None, template: str = None, skip_install: bool = Fa name=os.path.basename(os.path.abspath(name)), description=description, ) + from nitrostack.cli.vendor import ensure_vendored_nitrostack + ensure_vendored_nitrostack(name) lock_with_uv(name) widget_routes = ensure_python_widgets(name) print("\n\033[32m✓\033[0m Project created") @@ -1313,14 +1315,19 @@ def init_project(name: str = None, template: str = None, skip_install: bool = Fa lines = f.readlines() new_lines = [] for line in lines: - if line.startswith("SERVER_DESC="): + if line.startswith("SERVER_NAME="): + new_lines.append(f'SERVER_NAME="{os.path.basename(os.path.abspath(name))}"\n') + elif line.startswith("SERVER_DESC="): new_lines.append(f'SERVER_DESC="{description}"\n') elif line.startswith("SERVER_AUTHOR="): new_lines.append(f'SERVER_AUTHOR="{author}"\n') else: new_lines.append(line) + has_name = any(line.startswith("SERVER_NAME=") for line in new_lines) has_desc = any(line.startswith("SERVER_DESC=") for line in new_lines) has_author = any(line.startswith("SERVER_AUTHOR=") for line in new_lines) + if not has_name: + new_lines.append(f'SERVER_NAME="{os.path.basename(os.path.abspath(name))}"\n') if not has_desc: new_lines.append(f'SERVER_DESC="{description}"\n') if not has_author: diff --git a/nitrostack/cli/pack.py b/nitrostack/cli/pack.py index 717203e..b2a805c 100644 --- a/nitrostack/cli/pack.py +++ b/nitrostack/cli/pack.py @@ -460,6 +460,8 @@ def pack_project( Returns a dict with ``files``, ``wheel`` (path or planned name), and ``dry_run``. """ root = os.path.abspath(root or os.getcwd()) + from nitrostack.cli.vendor import ensure_vendored_nitrostack + ensure_vendored_nitrostack(root) files = collect_pack_files(root) name, version = _project_name_and_version(root) dist_name = _pep503_wheel_name(_normalize_dist_name(name)) diff --git a/nitrostack/cli/vendor.py b/nitrostack/cli/vendor.py new file mode 100644 index 0000000..7e565b0 --- /dev/null +++ b/nitrostack/cli/vendor.py @@ -0,0 +1,199 @@ +"""Vendor the running NitroStack SDK into a scaffolded project. + +Cloud deploy zips the project (not the developer's .venv) and `uv sync`s +from `pyproject.toml`. Putting a PEP 508 `file:` URL in `[project].dependencies` +breaks NitroCloud's Python uv builder (`Failed to parse metadata from built +wheel`). Keep the dependency name as `nitrostack` and point uv at the copy +with `[tool.uv.sources]`. +""" +from __future__ import annotations + +import os +import re +import shutil +from pathlib import Path +from typing import Optional + +from nitrostack.cli._shared import write_text_atomic + +VENDOR_REL = os.path.join("vendor", "nitrostack") +_REQ_PATH = "./vendor/nitrostack" + +_SKIP_DIR_NAMES = { + "__pycache__", + ".venv", + "venv", + ".git", + ".mypy_cache", + ".pytest_cache", + ".ruff_cache", + "node_modules", + "templates", + ".egg-info", +} + +_QUOTED_NITROSTACK = re.compile( + r'(["\'])nitrostack(?:\s*(?:===|==|!=|~=|>=|<=|>|<)\s*[^"\']+)?' + r'(?:\s*@\s*file:[^"\']+)?\1', + re.IGNORECASE, +) + + +def running_nitrostack_root() -> Path: + """Directory that contains the `nitrostack` package used by this CLI.""" + import nitrostack + + package_dir = Path(nitrostack.__file__).resolve().parent + parent = package_dir.parent + pyproject = parent / "pyproject.toml" + if pyproject.is_file() and "name" in pyproject.read_text(encoding="utf-8"): + return parent + return package_dir + + +def _ignore(_directory: str, names: list) -> list: + skipped = [] + for name in names: + if name in _SKIP_DIR_NAMES or name.endswith(".egg-info"): + skipped.append(name) + return skipped + + +def _write_minimal_pyproject(dest: Path) -> None: + import nitrostack + + version = getattr(nitrostack, "__version__", None) or "0.3.2" + dest.mkdir(parents=True, exist_ok=True) + (dest / "pyproject.toml").write_text( + "[build-system]\n" + 'requires = ["setuptools>=61.0.0"]\n' + 'build-backend = "setuptools.build_meta"\n\n' + "[project]\n" + 'name = "nitrostack"\n' + f'version = "{version}"\n' + 'description = "NitroStack Python SDK (vendored)"\n' + 'requires-python = ">=3.10"\n' + "dependencies = [\n" + ' "mcp>=2,<3",\n' + ' "pydantic>=2.0.0",\n' + ' "starlette>=0.30.0",\n' + ' "uvicorn>=0.20.0",\n' + ' "watchfiles>=0.18.0",\n' + ' "anyio>=4.0.0",\n' + ' "packaging>=23.0.0",\n' + ' "tomli>=2.0.0; python_version < \'3.11\'",\n' + "]\n\n" + "[project.scripts]\n" + 'nitrostack-py = "nitrostack.cli.main:main"\n\n' + "[tool.setuptools.packages.find]\n" + 'include = ["nitrostack*"]\n\n' + "[tool.setuptools]\n" + "include-package-data = true\n\n" + "[tool.setuptools.package-data]\n" + 'nitrostack = ["transports/assets/*"]\n', + encoding="utf-8", + ) + + +def copy_running_nitrostack(dest: Path) -> None: + """Copy the CLI's nitrostack package into ``dest`` (a installable tree).""" + if dest.exists(): + shutil.rmtree(dest) + dest.mkdir(parents=True, exist_ok=True) + + root = running_nitrostack_root() + src_package = root / "nitrostack" + if not src_package.is_dir(): + src_package = root + shutil.copytree(src_package, dest / "nitrostack", ignore=_ignore, dirs_exist_ok=True) + + src_pyproject = root / "pyproject.toml" + if src_pyproject.is_file() and src_package != root: + shutil.copy2(src_pyproject, dest / "pyproject.toml") + manifest = root / "MANIFEST.in" + if manifest.is_file(): + shutil.copy2(manifest, dest / "MANIFEST.in") + else: + _write_minimal_pyproject(dest) + + assets = dest / "nitrostack" / "transports" / "assets" / "landing.html" + if not assets.is_file(): + raise RuntimeError( + f"Vendored SDK is missing the documentation page at {assets}. " + "Update nitrostack and retry." + ) + + +def _pin_text(text: str) -> str: + """Keep `[project].dependencies` as a plain name (valid wheel Requires-Dist).""" + return _QUOTED_NITROSTACK.sub(lambda match: f"{match.group(1)}nitrostack{match.group(1)}", text) + + +def _pin_requirements(path: Path) -> None: + if not path.is_file(): + path.write_text(f"{_REQ_PATH}\n", encoding="utf-8") + return + lines = path.read_text(encoding="utf-8").splitlines(keepends=True) + found = False + out = [] + for line in lines: + stripped = line.strip() + if stripped and not stripped.startswith("#") and re.match(r"(?:-e\s+)?(?:\./)?nitrostack(?![\w.-])", stripped, re.I): + out.append(f"{_REQ_PATH}\n") + found = True + elif stripped in {"./vendor/nitrostack", "-e ./vendor/nitrostack"}: + out.append(f"{_REQ_PATH}\n") + found = True + else: + out.append(line) + if not found: + if out and not out[-1].endswith("\n"): + out[-1] = out[-1] + "\n" + out.append(f"{_REQ_PATH}\n") + path.write_text("".join(out), encoding="utf-8") + + +def _ensure_uv_source(text: str) -> str: + if re.search(r"^\[tool\.uv\.sources\]", text, re.MULTILINE): + if re.search(r"(?m)^nitrostack\s*=", text): + return re.sub( + r"(?m)^nitrostack\s*=\s*.*$", + 'nitrostack = { path = "vendor/nitrostack" }', + text, + count=1, + ) + return re.sub( + r"(?m)^(\[tool\.uv\.sources\]\s*)", + r'\1nitrostack = { path = "vendor/nitrostack" }\n', + text, + count=1, + ) + if not text.endswith("\n"): + text += "\n" + return text + '\n[tool.uv.sources]\nnitrostack = { path = "vendor/nitrostack" }\n' + + +def pin_project_to_vendor(project: Path) -> None: + pyproject = project / "pyproject.toml" + if pyproject.is_file(): + text = pyproject.read_text(encoding="utf-8") + write_text_atomic(str(pyproject), _ensure_uv_source(_pin_text(text))) + _pin_requirements(project / "requirements.txt") + + +def ensure_vendored_nitrostack(project: str, *, quiet: bool = False) -> Optional[str]: + """Copy this CLI's SDK into ``project/vendor/nitrostack`` and pin deps. + + Returns the vendor path, or None when the directory is not a project. + """ + root = Path(os.path.abspath(project)) + if not (root / "pyproject.toml").is_file() and not (root / "requirements.txt").is_file(): + return None + if (root / "nitrostack" / "transports" / "assets" / "landing.html").is_file(): + return None + dest = root / VENDOR_REL + copy_running_nitrostack(dest) + pin_project_to_vendor(root) + if not quiet: + print(f"Vendored NitroStack SDK at {dest}") + return str(dest) diff --git a/nitrostack/core/__pycache__/additional_decorators.cpython-312.pyc b/nitrostack/core/__pycache__/additional_decorators.cpython-312.pyc deleted file mode 100644 index 7c978a446a67d45060fff53bba5f0c1d1e05958f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6896 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 ofueMtX(UhOe~f}ZmK0d{a%zyJUM diff --git a/nitrostack/core/__pycache__/app.cpython-312.pyc b/nitrostack/core/__pycache__/app.cpython-312.pyc deleted file mode 100644 index 2f7c654650a0ecd7c508914ef42d78c63b7cfaee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33340 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 diff --git a/nitrostack/core/__pycache__/decorators.cpython-312.pyc b/nitrostack/core/__pycache__/decorators.cpython-312.pyc deleted file mode 100644 index a92614eb3753c223d1541c9a23ea4be69efc2053..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8239 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 diff --git a/nitrostack/core/__pycache__/di.cpython-312.pyc b/nitrostack/core/__pycache__/di.cpython-312.pyc deleted file mode 100644 index 0d33e9b01369bc870f273accf143527b76556411..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3734 zcmaJ@U2GKB6~6PgJG&n5`Ul50G2|KpX8CbaA}W;-P-4^I0*-{q11q=N$;`DGvpehD z83Vi8t*ppZ*A=NjYGq3_lB-s&5q;<*&&f-wK6H(VFw;s!YWmQ(Ev9OezVw`#o%Ldw zUTMy~bMD`{=X~eqPpz$S0`0e>$EVj}^mqITn_M4ko`b;>F^MT;Nlr)$IWaBfq_mWi z({fHpD*_S8d&Csyi7DL|gI(!}88sCqF`*Y2lcE`!SJKgfoKpXZ3sQBO(88Y+0;yFUcO&nl2(AzYRXNV zh^fqzbkvM6)r38hvKgJ1(=k(JaWe)V@*-v&cr89pWN}#20{>b;NF}_Mkr%$?=7A=EF#4xcQ+xA{FFOQb}mq2J!-G!bS(IZGtdSg`Z@adJ->yC-7)hBGr<#||WTst;XaIfa=V~%;Pi92EBIh!!8 zp_ziGO)e=2G`6qmE@yWtp3|sS)a#9-4L7v&RI$DJ89qzHg)KnlNG(Eo_f(`$T6rh@?<^~YnI&R@m9}i- z|21q~ARNz3iC`7ZrU10O;Kdu7bW(yRJ1jfdES;KxdCSdYio2Qx47vCMrwzy)**JW( zBHv2*-6u(3P>wT3-KAg{;LOL`KKKEwfo69?TS+(t^S-8cU-Bhooa%Ij=dW8P42`Vr zI74G8fp^2Yl*rLb{o5S8jnY81YVboT7OLTXzS$|x(=@P zGP|HS;~43h&jlW~X(i~JX-NnzQx;3&+(47f1h-+S(5AezB)~c{jn2ERZP{3Wlw(TS zNG@8I1i+9VVI@;833rL9d@6-Eek{1?WqvC`BAO!i>xe4LQ>3hvLrBGnKaK;&{03n*pS{iiwI-Wk zw#jUxKtC)57^a8(I6x7v2zmf71X_BH6;eZu6Gj8qKu>UjxBdTw!TT)RPZQ0)0r59y%w*t6 zPI1q7bt?zGr$8WI9ekJ`ScQybp-?%2pB`!gM*r zP)3Izz{x0V&|Prvh(3dw^rDbtP`6&}>`jBs;F~;%_O_m5nM^9yDu>tl&q0RqSk5Lj4d56Asj15E*J3(b{j1EWLl{{k4{X zjn3|+Gk4CcoLK8jRkakPz+~s5ynjzIFSy!E8x$ZGb%i3fw#cdk~CTI(ItRc-otgtT?vc9zet zcC05Mdu{aWuC)H86OP!>dLL_aO`|Kje%JS_zExwr|M-{Mn-Gz9_0&`;HX}Ug-o1RW z+I_fkt`;Zz4mX9gjbwKv`StS_($@Qo2)MN4NOkD^7sG$P@W%^ZoUUFmswS%%lhvbB z>m66CcD}0R|67xA`qR$GE}=kf6El zksyg<^zrZX39fNCka@Dvwrg(msnYgLl$1T25{b0ea0L2@v_BKY1`kHhR8cur1F~;< zq(-1yxx9&8O;waPR)%W?x<5#M_dwpnzgpse(z85XBhamkKgTW*2VXzNhk(9N2ccZ} zZ5{&h6UYk-WKNtSKZWWIvvklV#R{1epw!pOLP;1WDXI7aKT?b^a2VaiaxG7DI=@Es zx(n(K9kr*K;p!h|Sr8m9v5#ggfG=e?XR?-Ixiky46wOa=1u2U;!P=k%YLs9g1`3H` zdUFEEF9Z*bSQ0&S4Aj}2!^9_%o0?^|- zHEJ=anC60tDQ1R>DDJVgo_#8tH}tG?dZ;lyhCA`(uc7km>8nV$TE9{|AFFgtrR(ax z$Lf(a^~mb*BlQg^v@3DnbWpA#*5GoymwyM3z}Nn;UarNrZsaF{{~j(F00MUas8nsP zw2^GD$Td+`I)Co|n?MJAt*a{U3b5gqx2hL`i~yM+z%!Oy9CLaAbW~iR4ZMPX8wr}D zUNN2uyy!GP1w2%zgLne(6okK#*S{pM|3`jT5PJSae0omQgs$6{mj~`#c}`&HpY%Wc Cy-sZa diff --git a/nitrostack/core/__pycache__/errors.cpython-312.pyc b/nitrostack/core/__pycache__/errors.cpython-312.pyc deleted file mode 100644 index 734f4787b14c907b4aec22a4fbb7fed4425606e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1666 zcmb7^L2DC16vt;bNwaC2R;xvVm+=@%a}Ww5QpL7PJOn8!7y`?5ciL>bnc2?F*2Z%W z9=)|E5j+(?ieEr;@!%H_5-*;dH%T@VXu&M(+c*C=yZd|d-psdhc^>KOOa1=gPZyzI zFc@Ejk<q>5K;b8`?QX6g8a?HQmr@=DKb**IRkTdAxH< zgH%PF?Fhle`+K`2k~GBc+LU3X1lI@e&pA_=RE<%GohK%Uw%X4C?u2IH|*RamZVBzE-+7(aUp#ygEs9D ze3HFdYluAjz68dAEPz)Y8)%>YnD%i-3-Os~S9hu8sR(F;t7klA;jmsco0(uik5ej@ zE}$4q$C1R0E4&ZyTmuXJA;3Tq+0s79U?DUU?5&rAcM>&?I<>quYGNj1MLS7M6#XCK z6(9y<)_Dm=X6-?miL|&~A1>tDQz9u2Vj`tpD}h6rP!>`abaBKEX#j14N8NaJ$!`M% zn49{}O1_b;B7|mQt88ZsQ2f~1rcb8JZovkGLAm#+>45k|x58c*t2V{kbsTV}NW`eP zrV;Ky3Sd_Coi)OXECmS7l)}muXZz7XDy(g`X0vOeN!;327!oBpS6Pl|n8Sl4I@6(oMYf);3ia z5p|_d;mwIitsqhly;kJF|L6q-2V+GFQct}(+DNIY9y(+1(hVYS?QhIr9 zd|m-m?ha}XpCADKWJX8wZKd@qRdxUd7+RnTby($e4l%5#?B=NI z3JgRBj6iM=gI)^1gBC^b&;0GrSMGZ>k(E_*%{N!<3Qf|ZZF@9btNY(N_Oyo|b$M4x zj!Rb3lxAvmS7sYBU?2AGQTPd*D)}dOPDaP~7mi17HNM;~Y~yDmN9fkcl?+egPEvyH`Id3&O%AEDXvu46Roe$e^KlFM#LdbD>BRAMLX2s<$2 zQR^EDTVM-raa;Tr+5t`2;8wv?*yNItYx2p+H&HTDe)*j}K$#0*fC4@M0aq3|7ReeXL{jS(VHPw_3GfBjv>#Ws0wX5}0>RIcj)OPEqRMW<4 zyZ!0Hh%Z@QsZH-BBZ=YweOosu{37fC|7^A?G`XhOL{0t$+-sNNG2DO~z&MN905oxK zNfX{%K#fcK81);~QmsQenmJ{)Cb=W@tC5(RY55t8Qa&XuVcqaplB(KZ;tsJDGVau9 zeYj1UIm;=TmN!3hHl?zqpHld{0bcff6!r~_3orE~8|6 zLq)${tJteu*OQely-lpkNosD9X$kj}VrJ&jyyxAkbb__kdrBeZA%w5MT)_I(@+)Der| p($Fs2U4E_{_KwFAb7eqJaU1V`_Uz$d{z@z}m(uNe!*)z^{SS=EoOS>J diff --git a/nitrostack/core/__pycache__/pipeline.cpython-312.pyc b/nitrostack/core/__pycache__/pipeline.cpython-312.pyc deleted file mode 100644 index 879e925068bd19e03091931739a9d2fae1ea1eeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14141 zcmeG@TW}lKb-UPIyh(s0NbmuY%ZDgZlxSO)OhuMR@gdO?EmAe*D5f6}#9dM#L4e)` zMUe&_$5uno)uhyHJncf+kz4zSrx#ym9&$$=>l$U3wAl!B~jn>yu)Gslig^E;U&8(xS z%alL~w2vC62WcAPI-hQw8Dz%UL3W%Q9ZbG;SU=lQ`?Mj9Uk- z<9UO5B+dEq$8Cc)64(3e;{}5SG^L|@D8X=n5{#nZHAd}wu#jL)fHh}fiwM>NSZfy6 zA<_h&2l)KgV9Xd^Q$N&TG0C$*o;|Bh3BeWswlE9p6pBQ>SXc&ihjoJE0y|hL6a%Ix zg((3{ncxJBBZVmiOu0}7n35Ex9559^1z?;hj0-R>(qAR?SEY?`u#(`a0mr9tRRmW9 zxY{(X+C-TsVV6)Zvcfiz5gJ5Z*e=!xjiMFC%Rx_M#Mm2*7Sm+BB<&<=GFp-@BWW^L zlCB_WGE$Om5^IGWqEXb7RI|tomkT>DaD#Qzbxke*jx=qe6_elzdWL)+S#HuROoxA3 zF?M-;KF=ASsIZTE<)FfzoSqOB;|VDc3=9Q)im`tp=neQiKB&!2NuCM0NvGHkpBINF z5#JT?2gUP2#nLeuJex{DNlW)pOnAJ0QG%rH^B$iUx`qmeB`F{c;c&FTrXp)Dh+L*b zYLFJFL7hMY!E_=!%nA%F12@e!aSGQn>5&A*FqG<6FNwiP$v>209nuoUUxMG76+kaV zLz~mo_n0aARl4t03P#V$qHkC#fLs~N^8Ck#y7oWyxGYNYQzM?qpyw&SHz);Upw!r| ziRs|kfPa@PjAdb;8VX3_Qxo0^(FZeZnV43rLmt1|GZgfm^9042LNd&jY#eS{*$Cj@ zs1IMDRt7#=!+F1`W9dFv3ZvWY_l%2fw_xm3@cJVwkKHa>ITbx{98!_T9$#e# z)w)>Y_e4+2QP@n1?IEi%xG6L+IHf7I?H+)h zrQHB>xF#rh{PJ)>8lTC>PFvDx6haw^cDqjF7JUvm)g4FZvj_XgA>93lLx7u5MrnZC z?)VaL#_?;90$3SXWsj?L!(zW9-PTJi+u`%Ly+98g@%mt|DV&JEfVb;b*~e63VmU=Wf(lh$M^xN$$l_}}fH`1Cfeu1U4a2%HHB1Y-3)WdW zL=R9+OrOFIPx^<3Xsrl*QPLK{Z><}^EA(Y5n9dDBb0d^?Tnu7oB+S#VrOM1eIz+kC zIz2=|H@ZH>;vOHGaH|7uVidy&uze7AD(i!Ti_{Lansm}Z_(%@}P<8tYs`4-iBB*Q+ z$kmxj&>N{nS`PRELmr>p){@TVv1Tm*P||lQYM1sbS6y~hPf9%NTqt&0sb#Z0ZMe0(!#U3}VO8)vDrDITP8CA zohzNOnx22Iza5Gldn#J<6fQ*7#)ZH>H!g%dw@;}b$~9xz%u;Z8(Efv112b6zGTe2< zAAkvI#6JP?jl_2$AxOnds7|zU4b(&SFRxjuU$$O56D$ARPr6r%f7}}_?+LRPZ5v6B zJ#8epDczHF5(*HtpP{v3nCQhn2x?miwNnFLNAEAd#58(84)Klju0krLs%}E@eOO6T z1FpKI?&X&2wK3PhTkOiI*Yl#TKRk9}}nfVJR@qOX9PWq8#M4 z(_#xL{AeIBCi8H<%N3XRvYX})6Lr51gjDZO@q5PJhAHYi^8__Tqtm0w*f(QJ zFQ#Hht@05GR}Ne=c`E-5h|)Rlkf<1dW!$}opE%iMA;y5hz$r_@c`H_kfqnqDh#v|% zGd_|Q@R^)#0d{c%yGYMqS%W0X0pB^WO~6D!&yOhWN4zc|D+bYj&MO7{V0WeMeZ`Qf zu9(oZL;OZ+OSV*o8{9KELP;cJ5zkMELqSo%F3A}h86Sh{3_;surc|BUMqdmb#N;0U zAZ~+q3d`b!wb8=bcws}duwm)BSmA?j7LHw;insPeTYKWIz0ua*+eag(o`|&$##^6> zwmuVakH%WZ!iKkOC5fWayLzgak2`io9Xn%=mar+Qvzki()p{^dwLM;SU$pAJYk9G% zws3!rGFnnEcJN&~`bORMP78I@Ohf#p<-X2#=H`AD<83s? z+Zl-Wy}H4iFu2`9UdV^cv@ls#g`)y#;pP7%FK{IOFfRcWS4B;Ml}_=&*8qz{-(=2MPA zl_g0NTL>#N43!A0W!MP+SA~^S5YmmNg%ylA6$C~T0U*xUkS>Vk8VQ*k0gS*|CWsCT z5=L>xIUz0TSP*rbp!dOrz$^!%jvYlWTuumaTCYT0p?#MVLg{hM8iHt>k`OX%D#i?2 zYg^O%WFCye4o%L#%lWc)hy=V=8&gZLJxS>yA@X;2IJoubzXb9f2z z+LtB~oI@~$;5-0D4_61?aaqX=2F66cd%`pA3wVT+Gj+Hv$-d=D4xf_x;Ai27Jzk$E z?B|=>tc>8d)eK<05F4jI3w!CF4Uuurm?u*v$yI!_h+XY(Y9ec$$x|U2| z?_2DT*ms7xe{oc=(>X<^vbU`dCCcmK<;~IZ=H+9t^44%~qNFBX(h@CcS)PoQ><#yT zu5xWplvZE0T(K-2j+O2J6?6HyOV2IsTYfC&ygyN1bG7+O^U_$Xe0Rc8ak=+W?-Cbt zG;A4nRwb&o-7PS=^20qBA5A(aN2#jSbf&U|wdha#=KJDSK5FG7bw^g7T^Wkh99y;a z-YF{mB*{UMU(0BJyx7rxxRAc7>#XRmqHa~vkhoQ4I&5QZZLd0PX5Qd9z`SAR0P}{8 zfq0)ZhHHlsMpZoMQIY%_7=%b#Vd+3&=_|N0qOjnL3JX4JJ*@JX6qdQa0~kwHSsi9% zlZ?tDS^Vyn2YAoWkSNQky@5>6dnN_gheINN#_Jcn{t@*selJ~B4+rP}*Hyo7UG);k z+~-8 zO8(MhtaMkRqxT=GZd651oLcSp!otku=Py0KG_owkoV(-BeNpGW>qV>1gOO)WC(7%u zwp?jhu85WIO*pD9_g(5++8c8;Z5emgB&r(ME5&3rReqTM=q^v$%igCpD#y;12UhAL zHAhyhJz2^TouQx{kJv#uHXn9TH+Rv8%h{VP#Snj;p#lFo+lh%c$}sUpIgN3b=|~>) z#>M&_ps2l$^FIl%lhkAe8+s&gJXk`O$HE34UhM0HlBR405hYevStPh*RmauWy zD$o~I^KJQx5YP^yv0QF$kydDyX& zKdL=cfUB3C{0a2_?}Ua^H@Cccbt^ZiXC@Sx>43KKSK+sI0yyIp>s;Pk{+vzan)xDF zGq^OJrC`l~$8tl6(li-fY;LA2=L@wG=@Wx4bz%U=qC{W3KjT=;xHDg*St?_n&)c;& zUe24ZkWOXn^ZB$U7Ib6XuuqQ8=LzK9%`7ut0b>W5Kg(`0_VfzQazTqWv-z_5^6xSl zkAcn3ZN?oTCZyNOY?v2w@c^tlgCjWr&4%;Bj&O0gK3xNe2F$U7;O!V z*0jZF(*-U`%Qk4;2CeIH zx8q*VZ5?pNto^T^0#j>B_Wyr?47dP4BjIsF-%Lq|dXyJLzgHCaGt>MCUZAVqRGrie zL?QxibFTbr$bN-Y`B8vZZa(0~5Va|$Kytn9z7k5=}_onTk@zq_$U(nOWEefW;EAAScvCI;(EH66wDx9JWW z`<-Hl{fO=;V1I0b*bOt?QN-S`a2PM35f&j_cL&eFfYEujh7SK%bojyo6coOzU{EoU z#}4cG2PHqL(1;b7%hWu*nFN~$KGAma07V|wHPI5*fy*)U=P8z~>s^KMpAVAPD(ST` z9`Jd_&j_BjnI}KZ!i;;y)?FaG@iky(-L%HzFcKN{Kip<6J{Pav6RqBJ?bP+5)#^_5 zWPxTqjQB6%qaGW+g*A|Br!_7r-n6foqrbOd{|viCt^Lsp)Z5O^h+Q4q|Kd8Dy3ZX7E#!AoBuai-mg|X@b{RxNy?db63v6aamriesGIrTgLM1md!zy zEvKWIM}A*JzJnd67wy4_T^$)*G~sq4mmG@igeZ-Jzf*gPtUgj9CK_I>NP7S%Mo9!W zqbv$dF2zIyynDzeD;$Z!>tpq;ufl-℞Owk!%)Y3X3-r(p79GEf;YkD7LK4hvlX3 zV43_ZY9R7e9K>HBK(3dNhSFsOXA$5oR$m%rq--zZP}EA~u}fM7NqGM+y8z(1EFBIV zIs_X&9aO38*i7Wk?D*{$25-~kJ#ei0gh=9FmQ{z3CLEP<$F`_r+mbitxIcV2;i`$d zTB5F&<*AsfHD1yh?oo=$@04tdG_=J^+9URM5Vhs}T{~6kTI~MnOxXIC#r|gli>_F4 z!*ao!#XAy(Rg2GFx-Z=Ib63rRG2!In&c>*-ak&&swgvW%vu=52Wpvf~M+=iAfr$%G#uns;&(`x>zvZ|AF3MYD<<-rFCKJo$Bq&)}K}Hg*&>m z|Fl0=ejwcYD;=HJMZa5d|20>vqHX?B7$N`AT`N_+eQD-rRlCD|iGuQYL2b04cBw5^ zushs|752Paao;s-tl}UkU;W^F`BX{mSD%U7>LSLvpzy! zod0rjcLV)5bT_a6z8+#f?5GELvy$$v)!(e@I0%Vb6?At!d&|XPyp~2-kFamXpdN|& znX;6-9bAp6<2O$pID-4#m~la-?W`ygI z!=%R%WVr5cF^OIU#jL)sQ1=GL(-;^N;b)=-PHTZbeVTCTA(bbs+1w}n2wMCm{N#TG z@SiG|-L0hxTycA2)ZQ4g?|9+p2kb7c{sRg?@-%Jb9B&mj#fqEbw&sYjIbv)6=#Itl zK4k{HrSRuf+ZN0j4l0j1_bjkU9a9jX;lb`-m4CB*xdYg=rZryC8mVZFJ6b=yjopnZ5)(*-N8Uf_%{US^-oL&`b8l2PW3tl|PN%&qu zegAC47z$g(gwH>N@V^9EGGjXXX#oCFq9t`HtKK)Gp|2EX`M^jK!AsavDap+s>?=!X zzN&w5;4#*KfXM6nG4>Dwu$d_Gl8?M0BafTNV;gdZtzHhyLlLe_{s zkhgL!6BOeC^=}w$(k;kEdr|%&Kv+(iew(WK1$8J+9eSIp_yyJRHnrnzYWH0|O&_Jh zkKCp3i>W8+g;GpCNm3qqp%GIa8s2*9EFb7}bVHH?u*N_V-h$E%ca1dNM~C-eu|861 zfL=I@sR24^X6fQZcJc8mmNg2ZNh^RQc4;um-=Br(UapAN@68|3bA_4<4$f%if~^e9%ePViZ8~3<#V!Z diff --git a/nitrostack/core/__pycache__/task.cpython-312.pyc b/nitrostack/core/__pycache__/task.cpython-312.pyc deleted file mode 100644 index d3cec68211ee827e3bbfa64f0d842148dc4e407e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5304 zcmdrQOKcn0@o_&SMXpT!{G()vGD*u+B-^cPr&b)dh9%c<61lAt6eR>~8SY9Yy(HDQ z%Oqsk#06Y{22xlC3Rp%^L`NCE2t^M$^w4`RX61nF#zh0Pmz+vV1p@TcnYSM<720vp zTOYugd2i-@=FR8L@=yK!A%g8xD*sQQ{?0l!5Ny2r6Cmypg(yCaq%G`A`=HNhT!ByX z1tBdI#I#uOr~N*QA1DOVK_B7B_lUyZB8u>kvsO#@u`v^}Ye!H`q0OB4|2_7lUDWbxuyuz!3Djo*TvY-gJ z#Izr_@SA;aX7n2iMT1rr&42;4oKsBRFtjXhuZ9R|{Ow-x;mS2%jmS98nu0wTw|gA) zY}E)coHLQUOF5E+pZmghJ6DLw?^{&9J+%+BIxvL+%LHr zSM(`7jJoGg1n9Z@Dg=6AX9nxJ`zs>w`W>Ee#G&%z4%NXAZ4zb-IHMJk^23$CTcS5| z#g(drc8KXlh8n7pn*o)+5JB{EYLMdLOh2%UvTp9Puv}1eJ+q>kK_z3TMy{Zme6jSd z8AP&LDnhqxWX({Ps=!y|jA2H!jBd!~Rh)nW6xB5QS4)~E=Zc0(-^pmEpQ?IUGfYvX zv_wrQr_0$)F{^5ts+fU{UMXgCB~x5@M=cs=NP&%H73maj3c9K-v%|8Lb@Z25EcWm7 zm*$q<(p9Q2tz^nZW~rDnXbH5)-k4pj7(Xo)XLaRPok3_&)%Q?=ww~^bz~RLKpyxOQvp11F;h@w*$l~Yp`?^Gq$OGYSvjNG99}ml z#dt7zxOqB(lL?IhqUb#oos zZsvom$Tmd3tfRumxX#-B#()9Pjg&) zuR4(CH1rmxlpiu?S=CcMrk9RKuuT*~ABp>p0Y|^=x(cjdleoYF0Pv@Q;d|0uY5hmr1IfDhm+(LYs_8SPJF+<@ToM}7Kt?YobchmCNE$c zs6(g*RTS5;jRIqxDhg^8PIkl1aPL0vQlO08@?nSSV9yM#Fg9 z_xK2N548q$>*VPO{foH%A z(y8*Q<6WWi75-UVBi`$plGF8aGcwtTOg;*p*%AS;(4hDd_0C<<7mE+fUGLTSUW)4b zA#Qk2q+o_~BZcKVH@6vXe(IH}@@_2;$F-YhMvt$Fyj#mV@`Si?!*{+Z;N&A635Uw# zwd`qo;)Y*@uqhQ*H5DrM>L}VJ=JsQHIh%!4w_Mh=N=ourxf40K#WNEt3m=L_Ojn9! zb65=F#X$_&Pg=jTvlT|sE-&fgy#n*}B7k0jG<>Kzoc!}}vNbWiCjLfhP0g=~j|UR1 zi6nNvKI`@lsD3A)=pop*x3k4w+}VEq3}-v^6=&ll%@&zfSMl{&js-dcGyb-{A5@i>fz|91zQ zgzZxY=uuQ0(;!VCz{8gjFM_@P$pWu2yg^yl^eg4s7 zD0~tDOVSu|6ca2xhu{JLQ+T^n(&%@wk98`&ga9vsP9caPU>}Vsq!3`T(XWEH|BAHY z$(xt!^J~LvxwUb4e71$;=i-$8cDWv6VmApXF&k!=&iTbC^S$@~uM z+rr3dOKh=#7{>zw+Dz;qvPFPu4>1W&JiE!a37{=u2azoSR6EEdg0Kc`1ZZoRp-)D3 zuxASb)gEyLVJR5cwB_Mkj^I-cDC?T>a-l|Hl`0nQrr)Tn!k;&m;hFK6iTudxD`Zzs z0AJNjks<3lk6EePa%S+n^*_M{`UcDd!x8;BfHv>*`933&&&a;Nk(q5W^H*~COF{BY SKP3RZ9DBtV-ys0l;r;{Wxdxd4 diff --git a/nitrostack/core/app.py b/nitrostack/core/app.py index a0bc83e..9d9b069 100644 --- a/nitrostack/core/app.py +++ b/nitrostack/core/app.py @@ -128,6 +128,59 @@ def resolve_http_host() -> str: return (os.environ.get("HOST") or "127.0.0.1").strip() or "127.0.0.1" +def _read_dotenv_value(root: str, key: str) -> Optional[str]: + path = os.path.join(root, ".env") + if not os.path.isfile(path): + return None + try: + with open(path, encoding="utf-8") as handle: + for raw in handle: + line = raw.strip() + if not line or line.startswith("#") or "=" not in line: + continue + name, value = line.split("=", 1) + if name.strip() != key: + continue + return value.strip().strip('"').strip("'") or None + except OSError: + return None + return None + + +def _project_identity(root: Optional[str] = None) -> Dict[str, Optional[str]]: + """Name / version / description for the `GET /` documentation page.""" + cwd = root or os.getcwd() + name = os.environ.get("SERVER_NAME") or _read_dotenv_value(cwd, "SERVER_NAME") + description = os.environ.get("SERVER_DESC") or _read_dotenv_value(cwd, "SERVER_DESC") + version = None + path = os.path.join(cwd, "pyproject.toml") + if os.path.isfile(path): + try: + text = Path(path).read_text(encoding="utf-8") + except OSError: + text = "" + if not name: + match = re.search(r'(?m)^name\s*=\s*"([^"]+)"', text) + name = match.group(1) if match else None + if not description: + match = re.search(r'(?m)^description\s*=\s*"([^"]+)"', text) + description = match.group(1) if match else None + match = re.search(r'(?m)^version\s*=\s*"([^"]+)"', text) + version = match.group(1) if match else None + if not name: + name = os.path.basename(os.path.abspath(cwd)) or None + return {"name": name, "version": version, "description": description} + + +def _apply_project_identity(config: "ServerConfig") -> None: + ident = _project_identity() + generic = (config.name or "").strip().lower() in {"", "app", "mcp-server"} + if generic and ident.get("name"): + config.name = ident["name"] + if not config.description and ident.get("description"): + config.description = ident["description"] + + @dataclass class ServerConfig: name: str @@ -149,6 +202,8 @@ class ServerConfig: session_timeout_ms: Optional[int] = None json_response: bool = False extensions: Optional[Dict[str, str]] = None + # Subtitle on the `GET /` documentation page. + description: Optional[str] = None def mcp_app(module: Type, server: ServerConfig): @@ -524,6 +579,7 @@ def __init__(self, app_class: Type): self.server_config = ServerConfig(name=app_class._mcp_module_config.name or "mcp-server") else: raise ValueError("Invalid application class. Must be decorated with @mcp_app or @module.") + _apply_project_identity(self.server_config) self.mcp_server: Optional[NitroStackMcpServer] = None era_resolution = resolve_protocol_era_resolution( diff --git a/nitrostack/events/__pycache__/event_emitter.cpython-312.pyc b/nitrostack/events/__pycache__/event_emitter.cpython-312.pyc deleted file mode 100644 index 7d8820e7dfef704559e36b63e2b48bff68200983..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3572 zcmbtWU2Gf25#Ht9k;fm2lu5a=BE=^usdJJgyGqj-w&Yfp1h+{ex3K$TM)u{*JIbW_ zqwbw7i=_gg5mE|JVWemy1!+(TGM1aEkuR1JL*n*qMo!E6)AC%vqa;TiN@b?IXgwYnxOmQF3r8nNBs*__WT(q zrewFpjb#=raa>KM)GI07;wKU@)8fCLFicChFgFV#@!YJL$Y#`3%-PJL-s)iIU0~LT zPEfC?OQTUv=e1TipTARG5*0ua)c6L8TN9Q^)T4zow=QZP-K&YZPxl{!FErRAE^6Lo zAsVR9!dzAEha0rm@<3JQ)>=T;3b$&r0+ZMEj5(Q3n5NFAEH~55IhKjhswUW>NjUiL zyar^A;Nv6Nxp(bC_~j-Q{7{??nLE2Blf^hwv@4<`%bt8Z)v58PZ_SuBcOJ9x4E?Q;NT5PXfd zUm&an#H>4t9R4m2rc%W%1YhyiUnx(eKnT37@|`=2Yp%o<5FookQk zUaV>%yDXoQ0;K90u&fnQu4Lyj+O9;V7H{aOc%zP@0@h2Iijr$@QnMz;ix_P{K-1UX zDDbPn$EQXM{6n$Z*4Xmdj!`md8e%0rmx)=vSV}bv#ax)xW3|AA?+NlY&fW$Fa7On> z&UMOyGyegFc{&2$?*Cn$Vz4Cfggq_q%5!noovO7csauP6z)H)l&d%x?P3BoA3|SYF zZY0kGF;Hs>n&Z(nrq7^#S>33)=bOy-Z}WJBaRSH^+4i@uU-*Ucfl~4x-R?hHn7Dav z<=pyfrNEJGF>o`u5?uF{#J;lFUlRK_CN}$v1EUYc(~gx02|va&(#cA%b|<>e|3bX_T_G$=WBcHI)P{CHp`)YH`VUz2|7dScIWck1iADDLKb;1+4WEo(XglOTAZ~( z0_XGfFn9+N+4n)e_qjFhT|oeSGGg-zN>*RyAy{4|tD!z(Vgj|>3xrKA3Z`AHQIHHc z@51`i-rHO7iOP5tyYLAxd``I6y6qASDb#H&XXJ5MKVu+ z!_8BfpUU;xFp#P>L(&<`vXjzPHKU~fXz?tQj^untq_~<$>Do!jqCVN{fRY19S{}d? zWHQqVCyZE@W#`O9Mo0AF8^H2T-iYb;bHL(^1;cV1rUoZi!aPfux+TO@bH-KK-GJnm z;3}4PH%p5()}p$BF0=t%MKq6E=h~WpjH1uOI^&l>{zN_l2uC`~5xEqR%aOrSWN;(- zQSXDuXu zFMjsKPY(4~+@$^J-=4Wir28px!Iz=%n(sYdIV6=rQn7FHZu0JQ@tbcJr!N)Xyj;Be zR93@*4%a<_jvaL0bGINL=0JS!AVt2z zd*+yMuV;)u(=XhAQGkj2{Q`*YAHzkmi}_(6hM=qRQ+DB%gBDaUtUi!Ce2S9JYI7;% z1B&v!IW^_XFodJ!w+mBRhv$XH!noZ*B+ua-XPAs(u4jmIhJnj^kQ_nsB_Own9o%*u zu=TJBW+3AyK$gjND6;gm$3p0-ixawcIO1-rAXo7L_tZt}GT@%NdExYv04IETW4uD3 z+q_|SAAh&_?Tf#?Wb?&%atEg>K94ZE!Bq%!ni{n>#419PkN!x6W4xbek{R z-A7-1h9gH|w3%JinqC)pL;UYZKz<0xNTVijPK&z=Bu+Kga$pgH_B@ff+&6rP%LyGq zKs6y|%&e4F*)>U(;1zd05z{3Q#95YL*A*mTj$H$vg1NxA?m0e?-R6_Hk zTXrr3`6*o^EAT|veQ281w>xBGeqvWY{uDOXe5=5sVU?1P<;|{W5_@-NDs>e zeoO57RE(6xo|4$}0Bij#CGnNb`x0$VZ$l1MCjZm6+|%#4F_8}w*UhRKJa z`J5QAadQfXcnTXqf{#?k0^*1hYNy#a$SC{`%xo2oQu>Ja9+B4HlhHC6{VP8}`<@UW Ql_(Wy`+E2pfzICPU(=NefB*mh diff --git a/nitrostack/templates/flight-booking/.gitignore b/nitrostack/templates/flight-booking/.gitignore index 01e5284..ef4f256 100644 --- a/nitrostack/templates/flight-booking/.gitignore +++ b/nitrostack/templates/flight-booking/.gitignore @@ -5,3 +5,4 @@ __pycache__/ .env !.env.example .DS_Store +vendor/ diff --git a/nitrostack/templates/pizzaz/.gitignore b/nitrostack/templates/pizzaz/.gitignore index 01e5284..ef4f256 100644 --- a/nitrostack/templates/pizzaz/.gitignore +++ b/nitrostack/templates/pizzaz/.gitignore @@ -5,3 +5,4 @@ __pycache__/ .env !.env.example .DS_Store +vendor/ diff --git a/nitrostack/templates/starter/.gitignore b/nitrostack/templates/starter/.gitignore index 01e5284..ef4f256 100644 --- a/nitrostack/templates/starter/.gitignore +++ b/nitrostack/templates/starter/.gitignore @@ -5,3 +5,4 @@ __pycache__/ .env !.env.example .DS_Store +vendor/ diff --git a/nitrostack/testing/__pycache__/__init__.cpython-312.pyc b/nitrostack/testing/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index b3e6d2d16a29ff9328fa652f1927de2445da94f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4812 zcmdT|U2Idy6`uR+|2T;q5^w-RSinF`fMw}s>9)b4%kmQ{0;<+ZYdQDc1c&Qu@7!xh zQb*kaT6wjt8upOk_qSStiM3 z*(A$gomIIkpX9SbQpk!)G3!dY7{Zb_h|FCkGJlh`H6-0*LQMPzR${ElpB~FACfB2l z#dy<|mGY@{K5w?1kn%nGyqb~HMkc3yBP|&@I%fL&6?$HwiJUf+88#bgJ4v>Bn~Ign ziU!P8qL3sblO!uMNlxKqRuN=QCPTc;U*>OCx+X$kIlRo=VsBPjZgI{LTZhiWp$m@0G4cd!2+r6M=a3u$e2Z0Wm%ydI z3-kP#y~@2S2xNj|Ns$yeXSRNFfc(J!3+@6F6Z^(}Xw6RDa*r5e@>)8pfOm<`9_^MI z7jgEp;)i*kxX2h2V;}E$`T*k+*x69x2i2UER`u88c)Z}FeKF2-r&2g!DrI_86|(~G zPo>^2q*c4+=VS%9`8bj29ykN5(Fcap1tUG6p{MA0*q!+?I9sh#m(Q(|4&cV%pa)W^ z4D?N<;`uStRhgSMgGyY!jz+yq9{3w+D{yozkQh%;0ehMp zxPy)XjxI{uP`(bx_}b^1!2`|uNg#hG|9Xc!5{b8I%6seJ?6((p9$WMr|CD7sO=SXP zg(Kb*Od0FYt7XShxNAP#HPgBfes!tg)e`sTVDsd@_eV>?GDm{lkM%~-dGV_~4a{$u z9zTDZ1c0UOAgu9E^i}l16*RzAQe=uG1)N>RNQ~)=*`p9)bVVJqROmRYvOzpE+o0o- zXYA5x48aH;H~S7*4y`HiKXls$ZUB+#Nz>s%R?!Syss;qe(U6zmxAGfsF*|sQWCR5D zWn^{8RT_2QlK_z!$JsB!2EV9=5j^m^0tRB8P=vr@YXhsuP4EV8(keyHux(;2t`ij(2r`g@CMq*Dpf5#tF-XW-YQ!575R!5!DwGw!j`3QWPcjEz(aekWua} za)Gg+MHuf-q*YaqrlUqKr$z_Iq8QK7j21P{Dm56s3xF7b6j2%5X!-&|v8+I}XVPkB zT#=!NUQmtrp$ts5_%~8_>xTL0VnWi_RXEZ<+O;Sw3DCAYRVpT;mc{QUOrVD0F8wRBv zmi7@nrj>kF!ZC*_ePh3o9_iT-*4V9xABdI z<|A|dBg^5ot4FRJSqg8P4{uuv@0kzpnb|VySqL9mYB*Hl$|7ltl>GO7EtAsq{foX$ zA4)emes*@I>8I*)WW&_k*Ip?d{{$M<4|^AVv0Kv2u7&v5KH79Io>&e?r<<;vEFHcd zTr*ji8d?m#v>b{4r2AU;r28+8kuu9QZCQ?NM8Wjgg~;x?@NSr_F;w!FH<4h1`Rq|U zY1{OWFxai*gOgvC3f5-1jtmE#q zvdFJxkYC3EZ*m2isX@Ieu)GXz@xKBrPG~&^E9@}b*{fiMeF3agZ~iK*ur?rQ0A4SI z7Ou!oa9Z0c=z!#|3OxQI|4iuMiX8pUDp0Cs7nL=9vkGm3%ua}_vEvsr*MydmIJKBG;FHSeZ%oVh9R}exsT@}v4nOM-mFS-SK z(wBgk0Z6Fil(P=H4I8#2i6Pm6WG9mSNM1pLcx6Eh?L;mP#DS@ODA@%w@BDtNCiRIQv=?Eg(#B^pc*tHzl zz7*-2k91ve-*0N0T7N@aY}#!JJLe;vlkNw>*12HE3t(;^3BLB(qxkbt&fD9@-1alQ z0)IPjXbV*C>}~9Ik-IDp{9Tu?w}rdg%pxCVkZ<9De|F}yro?rnn#Uw6S<2BV!2ACcNU(Z>0w2$jb%p~ z^VCPLcUUn}_SpK+wW9VlSaM9L%OUIt{R%W$FP2pq!aJvaNlYg?D;4Zs~*i>d+ zLff=lCh(ctop^{}c!yOQ%FT?>I@PyA;8PaELTEZsCh(c*wLY``D_ASpl?mmkE4kPFtT@=@HiKmEn5&Vjfd8#^B$HVSAgnKr^IOU%7E9N0m6FxAx-{ z-=+2o)iQ;(uiCwu?t}It{&kvw&iHEA(RPqvG0exL{bMq)Kn6bLPccmBAwg=b=0A-Q BMb!WR diff --git a/nitrostack/transports/assets/landing.html b/nitrostack/transports/assets/landing.html new file mode 100644 index 0000000..029c526 --- /dev/null +++ b/nitrostack/transports/assets/landing.html @@ -0,0 +1,1469 @@ + + + + + + {{server_name}} - MCP Server Documentation + + + + + + +
+
+ +
+ +
+
+ +
+

{{server_name}}

+ v{{server_version}} +

{{server_description}}

+
+ +
+
+ + + + Connection Setup +
+ +
+ + + + + + +
+ + +
+

+ Add via Cursor Settings UI (Settings > Features > MCP > Add New MCP Server): +

+
+ +
{
+  "mcpServers": {
+    // your other mcp servers
+    "{{server_slug}}": {
+      "url": "{{mcp_endpoint}}"
+    }
+  }
+}
+
+
+ + +
+

+ Connect remote tools directly via Claude's Web UI: +

+ +
+
+
+ Add custom connector + BETA +
+
+ +
+ Connect Claude to your data and tools. Learn more about connectors or get started with pre-built ones. +
+ +
+
+ +
+
+ + +
+
+ +
+ + + + Advanced settings +
+ +
+ Only use connectors from developers you trust. Anthropic does not control which tools developers make available and cannot verify that they will work as intended or that they won't change. +
+ + + +
+ +
+
+
+ + +
+

+ Configure custom tools directly via ChatGPT's Web UI: +

+ +
+
+ New App +
+ + +
+
+ + + +
+
+ PNG only. Best results at 256 x 256 px or larger. Max file size: 10 KB +
+
+ +
+
+ + +
+ +
+ + +
+ +
+
+ +
+ + +
+
+
+ + +
+
+ +
+ + +
+
+ +
+
+ + + + Custom MCP servers introduce risk. Learn more +
+ +
+ +
+ + OpenAI hasn't reviewed this MCP server. Attackers may attempt to steal your data or trick the model into taking unintended actions, including destroying data. +
+
+
+ + +
+
+ + +
+

+ Add the following configuration block under mcpServers in your Antigravity configuration file (~/.gemini/config/mcp_config.json): +

+
+ +
{
+  "mcpServers": {
+    // your other mcp servers
+    "{{server_slug}}": {
+      "serverUrl": "{{mcp_endpoint}}"
+    }
+  }
+}
+
+
+ + +
+

+ Add the following configuration block to your Codex configuration file (~/.codex/config.toml): +

+
+ +
[mcp_servers.{{server_slug}}]
+url = "{{mcp_endpoint}}"
+
+
+ + +
+

+ Connect directly using the Server-Sent Events endpoint: +

+
+ +
{{mcp_endpoint}}
+
+
+
+ +
+ + + + Available Tools +
+ +
+ + + + +
+ + {{tools_section}} + +
+

Powered by NitroStack - The Python MCP Framework

+
+
+ + + + + + + diff --git a/nitrostack/transports/assets/logo.png b/nitrostack/transports/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9909f2060086205bb8971049a3a93c78eb43b1 GIT binary patch literal 84321 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 Gqfhl3Mi`}M!+xu-!ecT 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೏mbw_ZLvF~rw<(oEK^@fMO;Ol?+*QnQAd0 zO~Mz{7uOS@&8p2{h7kmar&zQ4LWGfGyNWM8^#T}t`DL+>LTUn5oIMo7d5Aw&5VC#5 z+{g&6Y|D4MS`7*L$WdgN(Znwr&(e!46zWv5MSTUDyT;)ief`SIxk@Hk`L*(&HXOOa8Edlr^#D}0SrbV0^jrMmFxP% z(H1XSqaSyp47apJOH8B48<9uy2#MNQG!!?mAWZ_S0VHlI6>^cV23a7rSZC+Ou+~_gI_*xc_gj`kZP4lxNFQ?C2XPw_Ee^?;h3v4|=+PBC z@o%qrb=9>V7sQrpZ~7ijP#3BelkbGE7t_(II}R_XASqv}o}~U#Ld_fC#=yeHz>Z;t z78K(?NT?*z31VCu*iWliu$^3fmlJv8ztxg2e%hoj42zXDzL%zaFUwwACjMV=b6DRTfX&?^%4~KVNNyZCnogH) zyK*E-Z@4Tn^N46UN74LXkEU@XeQmtxjp;;gv9ObRoygR;(@tL8B^IrMET`Whaht3- z!zYS^4996fA0!EnDHCHP>@lt2ij~cL@CgVi1ic^x*_nARO)ZeHO}a-c>NI&>Q`A{- z1K4~nJm9$)9n1rM6>en;r!aa-IEizu(w+AY558`A{Py$@UipB({qpP2+l&6^D3}3* zS8!#z*-OHf^)FbNp4PO=Z_{`R@jEq%Yp#FLB|>sL`pJ4S+WdD1ifMR$1}-H0r}Ev%$ruxKQm>t?O^ARdsl0?FbMgCCS>8Q1awAU+N)w%^-wbk7hF6 zpd@;9gcokR_5tI@@N2BhMw9{*N;ZCv zyDk?+&||f2)it&!i=b_V7KM#^T8J$vyHR(@g;pg=*WM9$kaSvk5V8iyor;hUvKR>- z;KvRXMrb_fI*o{nokT5D!)-EC z-wwA#eRA!`r>&8<-CZ?Nh%AIU1z#;3LNBcAWENxsH77GkHw#6kS^iS8C&}0SN(*R*{Fns7km%LlR?7ZO0SDbYI*WP&Ux0>~*pLg`kz+y(0 zSl5EZMkMb|Iz>eGYm{9~f2(rYV}e%Yo#%^*(p*{vs#ssLkm>46)?oaifBNpD_WS8S z2r|Q%;=~*Dg+}4ZcXYK0yB8zs%|bf7C-r(|;g2gDja`pNX?1>Aw_}YwL)W`n#qYwf@bB- z@)G%Jx}X9+;RKP5a+HE*n5KoCA{l2mlnhBYO$8;s95hXZDhYbrb%B(P8IpITA`HRD zAWIH~MUs91lcaw?Ueq)FiLX5@*!7rSz44^yeD949{2BV6V`>JxNQE+>WGyA37$ZhE`!eA-|D|Dyp>mN0i z^(EV`eb9K2drl!>m$icCMz8plIbRRf*hd!A8tc-c-C16r#WdixVJl|DQ+#L?qX?#% z!p^FXqLD(7$unMo=VVc!Oke;ytl;>lga@k`JPKpq+<555$Nv0{r#|<;-uUpJQ>1?! zV>58+yT3AM*tSt#_%|QR8fCX@SIBf(4fd$A8-_5rKQbihfX0kzL^xC}qgbuT&m

`d+E1k14}--T|n&`66?a?9k-p#YL^9K94WRc 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 K$j0!bAO8ijJG^!P literal 0 HcmV?d00001 diff --git a/nitrostack/transports/http.py b/nitrostack/transports/http.py index a343747..c915005 100644 --- a/nitrostack/transports/http.py +++ b/nitrostack/transports/http.py @@ -14,7 +14,7 @@ session-count API or creation hook, so this is tracked via a thin ASGI middleware watching the `mcp-session-id` header) - A `/mcp/health` endpoint -- A root documentation page at `GET /` (browsers opening the HTTP port) +- A documentation landing page at `GET /` (connection setup + tool catalog) - Chrome DevTools discovery stubs at `GET /json` and `GET /json/version` so inspector probes do not 404 - JSON 404s for OAuth discovery / DCR (`/register`) so MCP Inspector does not @@ -26,7 +26,6 @@ from __future__ import annotations import contextlib -import html import logging import os import sys @@ -40,6 +39,7 @@ from starlette.routing import Mount, Route from starlette.types import ASGIApp, Receive, Scope, Send +from nitrostack.transports.landing_page import render_landing_page from nitrostack.widgets.preview_page import render_preview_page from nitrostack.core.di import DIContainer from pydantic_core import PydanticUndefined @@ -89,56 +89,22 @@ def _server_meta(mcp_app: "McpApplication") -> Dict[str, str]: } -def _landing_html( - name: str, - version: str, - endpoint: str, - public_mcp_url: Optional[str] = None, -) -> str: - safe_name = html.escape(name) - safe_version = html.escape(version) - mcp_path = html.escape(public_mcp_url or (endpoint.rstrip("/") or "/mcp")) - health_path = html.escape(f"{(endpoint.rstrip('/') or '/mcp')}/health") - return f""" - - - - - {safe_name} - - - - - - -""" +def _landing_tools(mcp_app: "McpApplication") -> List[Dict[str, Any]]: + tools: List[Dict[str, Any]] = [] + for entry in getattr(mcp_app, "_tools", {}).values(): + try: + schema = mcp_app._tool_input_schema(entry.input_model) + except Exception: + logger.exception("Landing page schema failed for %s", entry.config.name) + schema = None + tools.append( + { + "name": entry.config.name, + "description": entry.config.description or "", + "inputSchema": schema, + } + ) + return tools def _env_list(name: str) -> List[str]: @@ -599,11 +565,12 @@ async def health_check(request): async def root_page(request): meta = _server_meta(mcp_app) return HTMLResponse( - _landing_html( - meta["name"], - meta["version"], - endpoint, - public_mcp_url=_request_public_mcp_url(request), + render_landing_page( + name=meta["name"], + version=meta["version"], + description=getattr(getattr(mcp_app, "server_config", None), "description", None), + mcp_endpoint=_request_public_mcp_url(request), + tools=_landing_tools(mcp_app), ) ) diff --git a/nitrostack/transports/landing_page.py b/nitrostack/transports/landing_page.py new file mode 100644 index 0000000..0ca1972 --- /dev/null +++ b/nitrostack/transports/landing_page.py @@ -0,0 +1,120 @@ +""" +`GET /` documentation page, ported from the TypeScript SDK's +`StreamableHttpTransport.generateDocumentationPage`. + +The markup lives in `assets/landing.html` with `{{placeholder}}` tokens. +A project can override the header logo with `assets/logo.png` or +`src/assets/logo.png` in the working directory. +""" +from __future__ import annotations + +import base64 +import functools +import html +import json +import os +import re +from pathlib import Path +from typing import Any, Dict, List, Optional + +_ASSETS = Path(__file__).parent / "assets" +_PROJECT_LOGO_PATHS = ("assets/logo.png", "src/assets/logo.png") +DEFAULT_DESCRIPTION = "A powerful MCP server built with NitroStack" + +_SCHEMA_ICON = ( + '' + '' +) + + +@functools.lru_cache(maxsize=1) +def _template() -> str: + return (_ASSETS / "landing.html").read_text(encoding="utf-8") + + +@functools.lru_cache(maxsize=1) +def _default_logo() -> str: + return base64.b64encode((_ASSETS / "logo.png").read_bytes()).decode("ascii") + + +def _logo_base64() -> str: + cwd = Path(os.getcwd()) + for rel in _PROJECT_LOGO_PATHS: + path = cwd / rel + if path.is_file(): + try: + return base64.b64encode(path.read_bytes()).decode("ascii") + except OSError: + continue + return _default_logo() + + +def format_title(name: str) -> str: + if "/" in name or "\\" in name: + return name + return " ".join(word[:1].upper() + word[1:] for word in re.split(r"[-_]+", name)) + + +def _tools_section(tools: List[Dict[str, Any]]) -> str: + if not tools: + return ( + '
\n' + "

No tools are currently registered on this server.

\n" + "
" + ) + cards = [] + for idx, tool in enumerate(tools): + name = html.escape(tool.get("name") or "") + desc = tool.get("description") or "" + schema_btn = ( + f'" + if tool.get("inputSchema") + else "" + ) + cards.append( + f'
\n' + f'
' + f'{name}
\n' + f'

{html.escape(desc or "No description available")}

\n' + f" {schema_btn}\n" + "
" + ) + return '
\n' + "\n".join(cards) + "\n
" + + +def _script_json(value: Any) -> str: + """JSON safe to inline inside `` breakout).""" + return ( + json.dumps(value) + .replace("<", "\\u003c") + .replace(">", "\\u003e") + .replace("&", "\\u0026") + .replace("\u2028", "\\u2028") + .replace("\u2029", "\\u2029") + ) + + +def render_landing_page( + *, + name: str, + version: str, + mcp_endpoint: str, + tools: List[Dict[str, Any]], + description: Optional[str] = None, +) -> str: + title = format_title(name) + values = { + "logo_base64": _logo_base64(), + "server_slug": html.escape(re.sub(r"\s+", "-", title.lower())), + "server_name": html.escape(title), + "server_version": html.escape(version), + "server_description": html.escape(description or DEFAULT_DESCRIPTION), + "mcp_endpoint": html.escape(mcp_endpoint), + "tools_section": _tools_section(tools), + "tools_json": _script_json(tools), + } + return re.sub(r"\{\{(\w+)\}\}", lambda m: values.get(m.group(1), m.group(0)), _template()) diff --git a/pyproject.toml b/pyproject.toml index f3ad8a6..74a0dbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ include = ["nitrostack*"] include-package-data = true [tool.setuptools.package-data] -nitrostack = ["templates/**/*", "templates/**/.*", "cli/templates/*"] +nitrostack = ["templates/**/*", "templates/**/.*", "cli/templates/*", "transports/assets/*"] [tool.ruff] line-length = 100 diff --git a/tests/__pycache__/test_basic.cpython-312-pytest-9.0.2.pyc b/tests/__pycache__/test_basic.cpython-312-pytest-9.0.2.pyc deleted file mode 100644 index 51d1b21acd612f09e8a23d9f8ce1d0451bc20548..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11792 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 R{+Qil+MpsaUVa&t|4-K6duspy diff --git a/tests/__pycache__/test_initial_tool.cpython-312-pytest-9.0.2.pyc b/tests/__pycache__/test_initial_tool.cpython-312-pytest-9.0.2.pyc deleted file mode 100644 index cd8dfb81c0872cea8cc26c7763627e52950fe6db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4757 zcmeGfOKcm*b@s#MpVWu4E!mFf_$N9Q?K*a31g<}^tweAtq>XzhV_>o7uB4?&E<3Zb zO-2Iz5$YB&P~}qf(1UXdQn^5LD01zg0aElLSu&_h60|^per~iSz)jFY-<#!%G$SLo zo;sr5%zN|Z&HK&F+ds$S5d!T$$=3>h3=;A;MEoXZ09kKHge(w~m{O7CB+<(yB`-^) zq~-#WH>2e=F%!%MMIXwApqGo`QY06Vh!rYq^98s1LVs)Qk4$0(x8&XFbF}*BaPDq# z_@n1=4*K)0-s)Ned$F0yqU?=)ijNDM)na$4C)ZQz&GnX2xm2ky*H_w>+g941+uroa zj#7WFUm`MjotS|+Vru^S+<>43fflkNi;A~PZl_GF-bwNx?C&SIBES{(S1x+2B)1EA zd(4=%Yf_pd`1c^b81N>=ssyY`eq+^cvulpzUNE}>4q9om=jsq4Gz78+eaRB3N>wS- z`!5tWo{@O?HG^5-cTB5Tle5{3#3Fi<1?U2?M7rfw7gL)TIPpj9k==V^to3r|A<+X zU7j?iUE?w+O&#VM`K!Z~sypSBhnacxvI}Z50rhsXvXv^0f)oK_Fkonm?OuOSBDik?r96Hm$gQJuWk}zNxZ`fE3c^o(i z@ls8z!k*ba1QXcSM*+09w-kuGYD%VT1s*7V7MiLRFawrmYF2PUGlO%gpBa9i3spmz zFz*}lf_(`hj{&9*_?YsTQx^UbIZ*2wwW-C@PC1=-%4NtFh@y&7;Zf6Kd1_ZMKQM8? zex2o~tdhY40^>ngBGN{qmOD+$`Q|whw&2OUgEqYg;3ARmhLT({g+TXHiB#p^D%Yiq zGJdI+YHFOu^h|p>u_q&Y;Y5$3a?C1DP`p9t3ji4InNFuEx}OJ|w$*lTX?wOgje%gj z0RBn-eUmg2WY7M4iPg~VwdDS_8d< z)Qp`0Fh~9x=>9AaUW@NsOC4D28{7!0n%0QOfdltnZ4l^|PP`%dPv3rm=z0|9*A=4m zJdOeCWf6+xF-(3x?K1&7fW#=q!;3QG;R#@ReT&@h z#;c&|O7A)tr+u(hr>%#OhCqbGJ8z9H5(s-LB(__bEN)I9IdT>?pkJvduD5ExUiHQazesk$0Pe z^!L&@I+9^o??sEurfnu@$1_a4ZSbrqz=7Z>g5$M>!Jz(e1=mQ1A#tSEUv^x3!p1qGRVI`qG8FkwRpM4?jE=3|?_K4q2D z%?lp|kGJiZHYl~PS!Onq;(-da;jIZnD7luW78HBp{%<|iJaPtVHGHKE%DZ*kMW_K>sO}jB9xkpYefe*7~i3@DQCK93RZox=v;wfRg@!Pof#7rO5lmJ!a3lC z3zRyP_v#Z41ygi*-ik(9xQ8o7rNSend_@OGUW2+Ps<$D1?XJ|PjIs%(5#s^3TCo`4 z{u~cLQ5BprXxUo2{r48O#fP%+hC?>(~Idt@zn zXf4^h5l~Xv%{L#%NVI4EJ1ddFx;nU|4nAYb(EamE>JXZ8eknRsSMm3#N${{uxU3GL zDaf(X8m`1K<|kwH~PxjbV~JD}B}2M*``u*@+Zl(ej&>hWfen1l9R}}5HR|ZN} zg$E5*E$3~AD|EUnGNYqdpp+@gsymfK4>)=Wk=mRi@T?OHs%N#emKjUI@la9piT4%o?1vr?o%B9sPf-I{uy$pC0nkt+ zNrJ%~xs&*ugg+;dFUbp#;*xqdbSrc>c`G?D%^zJDd2eLl^n0i8AN^qD{gDq&zJKy} z^2foCf*&V8O8z0Va%Ak&V=H^#TIv14D*53*NWM<;Uy}Z(swDM3CIB`xNea*RZ@@VG zSR-<5zGqcRJ(a`Kfd&BpUkq|z1JTFZh#XoAZ(r*^u+(*MEzz|WOTcd$-x1T1f$ qjP)d-4Md-41Jb1Q1WK#1pVb~J{hz4=kJMcag{T7}2mTARiw&m$ diff --git a/tests/__pycache__/test_oauth.cpython-312-pytest-9.0.2.pyc b/tests/__pycache__/test_oauth.cpython-312-pytest-9.0.2.pyc deleted file mode 100644 index a575ff8b4c8ada9347e1ba07142fea77acebeca3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9410 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 diff --git a/tests/__pycache__/test_tasks.cpython-312-pytest-9.0.2.pyc b/tests/__pycache__/test_tasks.cpython-312-pytest-9.0.2.pyc deleted file mode 100644 index 505d9429ea375559d2e9d2a2f5a10e46c7c0c54a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16390 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" not in page.text + assert '", "inputSchema": {}}], + ) + assert "
-

{safe_name}

-

NitroStack MCP server v{safe_version}. This is not a website — connect with an MCP client.

-
-