Skip to content

Instantly share code, notes, and snippets.

View cab938's full-sized avatar

Christopher Brooks cab938

View GitHub Profile
@cab938
cab938 / watcher.py
Created November 7, 2025 19:44
Logging for MCP client server communication over stdio
#!/usr/bin/env python3
"""
Transparent stdio wrapper for MCP processes.
This helper launches a child process, forwards stdin, stdout, and stderr between
the parent and child, and tees every byte into timestamped log files. The wrapper
avoids writing to stdout so that MCP JSON exchanges remain intact. Optional
verbose logs go to stderr for troubleshooting.
Examples
absl-py==2.2.2
aiofiles==24.1.0
aiohappyeyeballs==2.6.1
aiohttp==3.11.18
aiosignal==1.3.2
alembic==1.15.2
altair==5.5.0
annotated-types==0.7.0
anyio==4.9.0
argon2-cffi==23.1.0
aiofiles==23.2.1
aiohappyeyeballs==2.4.3
aiohttp==3.10.10
aiosignal==1.3.1
altair==5.4.1
annotated-types==0.7.0
anyio==4.6.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622
197.109.77.178 - kertzmann3129 [21/Jun/2019:15:45:25 -0700] "DELETE /virtual/solutions/target/web+services HTTP/2.0" 203 26554
156.127.178.177 - okuneva5222 [21/Jun/2019:15:45:27 -0700] "DELETE /interactive/transparent/niches/revolutionize HTTP/1.1" 416 14701
100.32.205.59 - ortiz8891 [21/Jun/2019:15:45:28 -0700] "PATCH /architectures HTTP/1.0" 204 6048
168.95.156.240 - stark2413 [21/Jun/2019:15:45:31 -0700] "GET /engage HTTP/2.0" 201 9645
71.172.239.195 - dooley1853 [21/Jun/2019:15:45:32 -0700] "PUT /cutting-edge HTTP/2.0" 406 24498
180.95.121.94 - mohr6893 [21/Jun/2019:15:45:34 -0700] "PATCH /extensible/reinvent HTTP/1.1" 201 27330
144.23.247.108 - auer7552 [21/Jun/2019:15:45:35 -0700] "POST /extensible/infrastructures/one-to-one/enterprise HTTP/1.1" 100 22921
2.179.103.97 - lind8584 [21/Jun/2019:15:45:36 -0700] "POST /grow/front-end/e-commerce/robust HTTP/2.0" 304 14641
241.114.184.133 - tromp8355 [21/Jun/2019:15
Ronald Mayr: A
Bell Kassulke: B
Jacqueline Rupp: A
Alexander Zeller: C
Valentina Denk: C
Simon Loidl: B
Elias Jovanovic: B
Stefanie Weninger: A
Fabian Peer: C
Hakim Botros: B
#!pip install html5lib #install html5lib, only needs to be run once
#You might need to restart kernel after running with the menu Kernel>Restart
import pandas as pd
import numpy as np
from scipy import stats
df=pd.read_html('https://proxy.mentoracademy.org/getContentFromUrl/?userid=user&url=https://www.ncdc.noaa.gov/cag/global/time-series/asia/land/ytd/12/1910-2016', header=0)[0]
pop1=df[df['Year']<1950]['Anomaly(1910-2000 Base Period)'].apply(lambda x: x.split('°C')[0]).astype(float)
pop2=df[df['Year']>=1950]['Anomaly(1910-2000 Base Period)'].apply(lambda x: x.split('°C')[0]).astype(float)
print("Mean anomaly values before 1950 {}, and mean after 1950 {}".format(np.mean(pop1),np.mean(pop2)))
!pip install html5lib #install html5lib, only needs to be run once
#You might need to restart kernel after running with the menu Kernel>Restart
import pandas as pd
import numpy as np
from scipy import stats
df=pd.read_html('https://proxy.mentoracademy.org/getContentFromUrl/?userid=user&url=https://www.ncdc.noaa.gov/cag/global/time-series/asia/land/ytd/12/1910-2016', header=0)[0]
pop1 = #put the cleaned list of all temperature anomalies for pre 1950
pop2 = #put the cleaned list of all temperature anomalies for 1950 and above
print("Mean anomaly values before 1950 {}, and mean after 1950 {}".format(np.mean(pop1),np.mean(pop2)))
#!pip install html5lib #install html5lib, only needs to be run once
#You might need to restart kernel after running with the menu Kernel>Restart
import pandas as pd
import numpy as np
from scipy import stats
df=pd.read_html('https://proxy.mentoracademy.org/getContentFromUrl/?userid=user&url=https://www.ncdc.noaa.gov/cag/global/time-series/northAmerica/land/ytd/12/1880-2016', header=0)[0]
pop1=df[df['Year']<1950]['Anomaly(1910-2000 Base Period)'].apply(lambda x: x.split('°C')[0]).astype(float)
pop2=df[df['Year']>=1950]['Anomaly(1910-2000 Base Period)'].apply(lambda x: x.split('°C')[0]).astype(float)
print("Mean anomaly values before 1950 {}, and mean after 1950 {}".format(np.mean(pop1),np.mean(pop2)))
!pip install html5lib #install html5lib, only needs to be run once
#You might need to restart kernel after running with the menu Kernel>Restart
import pandas as pd
import numpy as np
from scipy import stats
df=pd.read_html('https://proxy.mentoracademy.org/getContentFromUrl/?userid=user&url=https://www.ncdc.noaa.gov/cag/global/time-series/northAmerica/land/ytd/12/1880-2016', header=0)[0]
pop1 = #put the cleaned list of all temperature anomalies for pre 1950
pop2 = #put the cleaned list of all temperature anomalies for 1950 and above
print("Mean anomaly values before 1950 {}, and mean after 1950 {}".format(np.mean(pop1),np.mean(pop2)))
#!pip install html5lib #install html5lib, only needs to be run once
#You might need to restart kernel after running with the menu Kernel>Restart#
import pandas as pd
import numpy as np
from scipy import stats
df=pd.read_html('https://proxy.mentoracademy.org/getContentFromUrl/?userid=user&url=https://www.ncdc.noaa.gov/cag/global/time-series/northAmerica/land/ytd/12/1880-2016', header=0)[0]
pop1=df[df['Year']<1950]['Anomaly(1910-2000 Base Period)'].apply(lambda x: x.split('°C')[0]).astype(float)
pop2=df[df['Year']>=1950]['Anomaly(1910-2000 Base Period)'].apply(lambda x: x.split('°C')[0]).astype(float)
print("Mean anomaly values before 1950 {}, and mean after 1950 {}".format(np.mean(pop1),np.mean(pop2)))