diff --git a/documentation/blog/2025-08-04-mcp-jupyter-server/data-goose.png b/documentation/blog/2025-08-04-mcp-jupyter-server/data-goose.png new file mode 100644 index 000000000000..6cb26be888ee Binary files /dev/null and b/documentation/blog/2025-08-04-mcp-jupyter-server/data-goose.png differ diff --git a/documentation/blog/2025-08-04-mcp-jupyter-server/demo.ipynb b/documentation/blog/2025-08-04-mcp-jupyter-server/demo.ipynb new file mode 100644 index 000000000000..c92dc0613d05 --- /dev/null +++ b/documentation/blog/2025-08-04-mcp-jupyter-server/demo.ipynb @@ -0,0 +1,129 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "202be4dd-75c1-48ab-8ea1-2b1fa4eadf64", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0b47af89", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2mAudited \u001b[1m5 packages\u001b[0m \u001b[2min 11ms\u001b[0m\u001b[0m\r\n" + ] + } + ], + "source": [ + "!uv pip install numpy pandas scikit-learn seaborn matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a3f0df9b", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "from sklearn.linear_model import LinearRegression\n", + "\n", + "# Generate some sample data\n", + "np.random.seed(0)\n", + "X = 2 * np.random.rand(100, 1)\n", + "y = 4 + 3 * X + np.random.randn(100, 1)\n", + "\n", + "# Create a DataFrame\n", + "df = pd.DataFrame(data=np.hstack((X, y)), columns=[\"X\", \"y\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "465df04a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Intercept: 4.222151077447228\n", + "Coefficient: 2.9684675107010197\n" + ] + } + ], + "source": [ + "# Train a simple linear regression model\n", + "model = LinearRegression()\n", + "model.fit(df[[\"X\"]], df[\"y\"])\n", + "\n", + "# Print the coefficients\n", + "print(f\"Intercept: {model.intercept_}\")\n", + "print(f\"Coefficient: {model.coef_[0]}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1f4cb6bb", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAArIAAAImCAYAAACvjmnVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYQBJREFUeJzt3QeYE9X6x/GXvuzSpNtREESlrGC7Koq9IWLBAhYUxYKgXsGKXPFasCsIoqgoYEEFBOu1y/VvAUFEwUUUEFR6W9hdtuX/vGfN3iSbZNOnfT/Ps8bMZCeTw2zyy5n3nKnh8/l8AgAAADhMTat3AAAAAEgEQRYAAACORJAFAACAIxFkAQAA4EgEWQAAADgSQRYAAACORJAFAACAIxFkAQAA4EgEWQAAADgSQRZAXC6++GLzE82tt94qxx13nNidvo4OHToE/ey///5y8MEHy9lnny1vvfWWuM3q1avN65w+fXpGni+0fUN/Hn74YXEKbTPdZ21DAPZQ2+odAOA+1157rVxyySXiBAcccICMHDmy8n5ZWZmsWbNGJk2aJMOHD5cmTZrIMcccI27RsmVLee2112SvvfbK2HOee+65ct5554Vd16pVq4ztBwD3IcgCSLlMhqRkNWjQQLp27VpleY8ePeSII44wvXBuCrJ169YN+3rTqXXr1hl/TgDeQGkBgJQLLS3Q/3/yySdl9OjR8o9//EM6d+4sV1xxhaxYsSLo9+bNmyf9+/eXLl26yKGHHiq33HKLbNq0Kegxc+fONb97yCGHyEEHHWS2PWbMGCkvLw86df7CCy/IKaecYrb15ptvxv0a6tWrZ0JfjRo1KpfpczzzzDNy4oknmuc++eSTZfLkyVV+97nnnpPjjz/evM4LLrhAPvnkE7NP33zzjVmv+6vbGDt2rHmdRx11lGzdutWse/311+X000832z/22GPNY7WX2E/b45///KcceeSR0qlTJ+ndu7fMnDkzaB8fe+wx0y7+9nnkkUekpKQkYmmB/jsMGTLEbFMDp5ZcfPfdd5Xr/b/z3nvvmcfl5uaa/b7zzjuloKBAUuH+++83z/H1119XOZXvf33aDtr+Z5xxhmlb3Vdt38Df0fbSf/cPP/zQPM7fRgsWLJDvv//e9Azr7+q6r776Kuj3tK0+/fTTyuOmb9++lf9mkcRyzAJIH4IsgIx46aWX5LfffjOB5d///rf8+OOP5kM/MKBedtllkpWVJY8//rjcfvvt8u2335oShaKiIvOYn3/+2TxGT/drWBs/frx0797dBEINWYE0mFx55ZXy4IMPmoAWic/nk9LS0sqfnTt3mv287bbbZMeOHSYE+f3rX/8ygfzMM8+Up59+2gSe++67T5566qnKx+i+aN3nqaeeKuPGjTMB54YbbqjyvH/++ad8/vnn5nXoczVu3FgmTJggI0aMMD3Buv1+/frJs88+a5b5DRs2TH799Ve5++67zTotjdB29Ic5XfbKK6/IddddJ88//7xceOGFJlhrW4WzbNkyUw+sYVWDqe67hvdLL73UtH8gLcHYfffdzevSLxNvvPFGxO0G0nAd2MaBP3433nijtGnTxjxHcXGxaZ97773XtONZZ51lHqP7ps99/vnny8SJE+Wee+6RLVu2yNChQ6WwsLByW1oa8sADD8jVV18tTzzxhGzbts0E8JtuuskEWf330n93fU7/saU0gGpbXnTRReb39FjU17lkyZKwryuWYxZAmvkAIA79+/c3P9Hccsstvp49e1be1//Xn9LS0splY8aM8bVv3963adMmc//888/3nXHGGUGP+e2333wdO3b0TZkyxdyfMWOGb+DAgb6ysrLKx+j/d+vWzTdixAhzf9WqVWa7t99+e0yvRR8b+tOhQwdfr169fO+9917QvujyCRMmBG3jscce83Xq1Mm8jh07dvg6d+7su+eee4Ieo/um2/3666/N/SeffNLcnzt3buVjtm3bZn73rrvuCvrdadOmmccuXbrU3D/ooIN848ePD3r9DzzwgO+7774z9y+//HLfgAEDgrYxefJk38yZM4Pa58033zT3hw4d6jvssMN8+fn5lY8vKSnxnXzyyb5zzjkn6HduvvnmoO1efPHF5t8smnDtG/izcePGysfOnz/ft//++5tjQ19Djx49fFu2bKlcf9NNN/kmTZoUtP0PPvjAbGfBggVBbfv5559XPkb/zXTZ66+/Xrns/fffN8sWL14c9Ht6jPkVFhb6jjzySN8NN9xg7mub6WO0PWI9ZgGkFzWyADJCT/HWqlUrqG5SaU+a9mgtXLjQ9H75e0jVnnvuKW3btpUvv/zS9E5qz5z+aK/p8uXLZeXKlaa3TE85+0+d+3Xs2DGm/TrwwANN76Zat26d6VnTbentvvvuW/k47fHUfdPT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CKW1qu+//75069bNlAroLAFKT/8r/7WTteRgl112kV133dWETe3Z1dP4n3zyiRlo5f+devUSf23aS6oXbBg3bpwZALZixQq55557pGfPngkHWe151u1s2LDBlFO8/PLLJrTrzAg6SE0HfWkPtb42AAC8pnGDepZnlkRRWpAmdWuLXH9eV3MABNL7Q/rmZqTWRKfQ0umr9EdDoc5EoFNoaZDzD+zSGQr0tLpejEIfc99995neVq2D9U+npbMc6BXBbrjhBnMhhREjRph5YPXCCuedd558+umnlaP+E52Cy+/kk0+WRx991Jz61+m9Ro4caWpm/bMQJEKn3dIpvXTmAg3DOnvB119/LWeddZZceOGFZjCYznYQ65XFAABwk4bZdeX6vrmWZpZE1fClarZ7h/AHrU6dOlVZp72Wy5cvNyPlk5lwXwcz6bZ0GwU7y0yRtNaXaNe8fqux8wGRCYHtoyES0dsmVcelG+hZBp15Qgft+c8U4H9on8hom+hon+i80j75BcVxZ5Z0tU20vBaI0oI00wPA68EVAADYX0MHZhbOpQIAAMCRCLIAAABwJIIsAAAAHIkgCwAAAEciyAIAAMCRCLIAAABwJIIsAAAAHIkgCwAAAEciyAIAAMCRCLIudfHFF0uHDh2Cfg466CA59thjZdSoUVJYWChueI233nprWp9D22369OmW7gMAAAiPS9S62Kmnnip33HFH0PWQ//vf/8r9998v5eXl8q9//UucbMyYMVKrVi3P7wMAAF5FkHWxrKwsadGiRdCyvffeW3788Ud59913HR9kmzRpYvUu2GIfAADwKkoLYuXziezYYc2PPncK1atXT2rX/t93mOLiYnnooYfk6KOPltzcXOnbt6/puQ2k9/v06SOdOnWSM844Q958801z2n316tVm/XHHHSejR4+W0047TQ477DD59ttvxefzybPPPivHH3+8dOnSRXr37i2zZs0K2u5zzz0nJ5xwgil70G089dRT5veUlj9oj/KRRx5pnvess86S//znPxFP6y9YsEAuueQS6datm9mH2267TTZv3ly5Xrevz3f99deb16mP+fe//y2lpaUJt2XgPmgJwoknnlh5q6/p7LPPlu+++y6utgYAALEhyMZCg9VRR4k0aBDTT63GjSWnVStzG+vvRP05+uiUhFkNbJ999pm89dZbJlT6aeD78ssv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O++84zv44IN9Thdv26iBAwf67rnnnojb9PKxE+qnn34yH6z6Jum3YcMGcyzpOjfQ94xBgwaZD81TTjkl6geu19574mkbL73vJNI+XnvvibdtvPS+s2LFCvNa5s2bV7msvLzcd8IJJ/gef/zxKo/X92r9QrNly5bKZa+++qr5W/J3SGjQ1S9KfiUlJb5jjjnG9/TTT6dknyktqMbPP/8sO3bsMKei/Bo1aiQHHHCAzJ07t8rjtfu9RYsW0rZt28pleoqvRo0a8t1335lTqfPnzw/antLTXeG257b20ceNGzdOsrKyKpfVrFlxGG7bts3c5uXlBbWfU8XbNtW9dq8fO6FGjRol3bt3lz59+gS1n/6t7bPPPuIGP/30k9SpU8ec9u3SpUvUx3rtvSeetvHS+04i7eO1955428ZL7zu77LKLPPPMM9KpU6fKZfra9Mf/txL6vnPggQdK48aNK5cdfvjhsn37dlmyZIls3LhRVqxYEXTs1K5d27Rhqo6d2inZioutWbPG3O66665By1u2bFm5LtDatWurPLZu3brSpEkT+euvv8yBUFBQIK1bt45pe25rnz322MP8BNI/Gv2A0bo+tXTpUiktLZUrrrjChJ1WrVrJpZdeKr179xY3t83WrVvN8aNvDC+//LKpd9R6omHDhpk3SK8fO4E+/fRTWbBggcycOTNouR47DRs2NB82X375pWRnZ8spp5wi1157rfk7dJrjjjvO/MTCa+898bSNl953Emkfr733xNM2XnvfadSokRxzzDFByz744ANZuXKl3H777VUer//+4Y4Lpe87Glojvc/r31kqEGSr4R8oEXow1qtXz/zxh3t8uANXH79z504pKiqKuD1d7/b2CTV58mSZMmWK3HnnndK0adPKQRnaA6CDMfQP5PPPPzdF9SUlJXLuueeKW9tGX7fSkp/777/fHCvjx483hfGzZ882H7KRtue1Y+eFF16Qnj17SseOHat8oGhb6IewDr7QHoEHH3zQDOrRWzfz2ntPMtz8vpMIr733JMqL7zvz5883fwcnnXSSHHvssVXW67Gi4Tf0uFDaJtHe51N17BBkq+E/FVVcXBx0Wkr/AerXrx/28frYUPp4/Zbm/wcOfUyk7bmtffz0DfOJJ54wb5bXXHNN0OjOt99+24x4zMnJMff3339/84bw3HPPOeoDJd620VMtOgpY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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data", + "transient": {} + } + ], + "source": [ + "# Plot the data and the regression line using seaborn\n", + "sns.set(style=\"whitegrid\")\n", + "plt.figure(figsize=(8, 6))\n", + "sns.scatterplot(data=df, x=\"X\", y=\"y\", label=\"Data Points\")\n", + "plt.plot(df[[\"X\"]], model.predict(df[[\"X\"]]), color=\"red\", label=\"Regression Line\")\n", + "plt.title(\"Linear Regression Example\")\n", + "plt.xlabel(\"X\")\n", + "plt.ylabel(\"y\")\n", + "plt.legend()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/documentation/blog/2025-08-04-mcp-jupyter-server/index.md b/documentation/blog/2025-08-04-mcp-jupyter-server/index.md new file mode 100644 index 000000000000..91f082d9e101 --- /dev/null +++ b/documentation/blog/2025-08-04-mcp-jupyter-server/index.md @@ -0,0 +1,160 @@ +--- +title: "MCP Jupyter: AI-Powered Machine Learning and Data Science" +description: Enable AI agents to work directly with your Jupyter notebooks, leveraging persistent memory and stateful collaboration for enhanced ML and data science workflows +date: 2025-08-05 +authors: + - damien + - dean + - harrison +--- + +![MCP Jupyter Server](data-goose.png) + +Machine learning and data science workflows are inherently iterative. You load data, explore patterns, build models, and refine your approach based on results. But traditional AI assistants lose context between interactions, forcing you to reload data and re-establish context repeatedly—making data-heavy development slow and expensive. + +The [**MCP Jupyter Server**](https://github.com/block/mcp-jupyter) solves this by enabling AI agents like Goose to work directly with your Jupyter notebooks, maintaining persistent memory and state across interactions while letting the AI interact with your data through code execution rather than raw data transfer. + + + + + +## The Memory and Context Problem + +Traditional AI coding assistants face a fundamental limitation: they lose context between interactions. This in part stems from their design to accomplish well-described individual tasks like refactoring a piece of code, compiling and running its tests, and commiting the result version control. In contrast, data science workflows are often open-ended and require extensive exploration and interactivity. This creates several challenges for using AI with data-heavy ML workflows: + +- **Constant data reloading**: Each interaction requires re-loading or describing your dataset +- **Expensive iteration**: Large datasets are slow and costly to process repeatedly +- **Context size**: The raw data may be too large to be fit in context +- **Not designed for interactive work**: It is harder to have the assistant do some steps and then transfer control back to the human or vice versa + +To address these challenges, we created the MCP Jupyter Server. + +## A Better Approach: Persistent State + +The MCP Jupyter Server takes a different approach. Instead of losing context between interactions, it maintains persistent memory and lets the AI interact with your data through Jupyter code cell execution. This creates a powerful paradigm: + +- **Persistent memory**: Variables and state are maintained across all interactions +- **Efficient iterations**: No need to reload data or re-establish context +- **Code-based data interaction**: AI explores data through execution, not given the raw data in context +- **True pair programming**: Seamless collaboration within the same notebook context + +## Transforming ML Workflows + +### Exploratory Data Analysis + +Instead of describing your dataset, let the AI explore it directly: + +> User: "Help me understand this customer dataset" +> +> AI: "Let me explore your data structure first" +> +> *[AI executes: df.info(), df.describe(), df.head()]* +> +> AI: "I can see you have 50,000 customers with 12 features. The data includes demographics (age, income), behavioral metrics (purchase_frequency, avg_order_value), and some missing values in the 'phone_number' column. Would you like me to create visualizations for the key relationships, like age vs income or purchase patterns?" +> +> User: "Yes, show me the age and income distributions, and any correlations" +> +> AI: "Perfect! I'll create histograms for age and income, plus a correlation heatmap" +> +> *[AI generates and displays visualizations]* + +The AI can see your actual column names, data types, and distributions—leading to much more relevant suggestions. + +### Interactive Model Development + +The AI becomes a true collaborator in your modeling process: + +> User: "This model isn't performing well" +> +> AI: "Let me check the current metrics and feature importance" +> +> *[AI executes your existing model evaluation code]* +> +> AI: "I see the accuracy is 72% and the most important features are 'price' and 'location'. The model seems to be overfitting - would you like me to try regularization or reduce the feature set?" +> +> User: "Try regularization first" +> +> AI: "I'll add L2 regularization and test different alpha values" +> +> *[AI implements and tests changes iteratively]* +> +> AI: "Great! With alpha=0.1, accuracy improved to 78% and the validation curve looks much better. Should I tune it further or try ensemble methods?" + +### Real-time Debugging + +When errors occur, the assistant has full context: + +> User: "I'm getting a KeyError in cell 5" +> +> AI: "Let me check what columns are available in your dataframe" +> +> *[AI executes: df.columns, df.info()]* +> +> AI: "I see the issue - you're trying to access 'customer_id' but the actual column name is 'CustomerID' with capital letters. Also, I notice you have 'purchase_date' as a string - should I convert that to datetime while I fix the KeyError?" +> +> User: "Yes, fix both issues" +> +> AI: "Done! I've updated the column reference and converted purchase_date to datetime. The cell should run properly now." + +### Continuous Collaboration + +Imagine a scenario where you are working on a new dataset: + +> User: *[Executes: df = pd.read_csv('sales_data.csv')]* +> +> User: "Let me check the data types and look for any anomalies" +> +> AI: "I'll analyze your sales data structure" +> +> *[AI executes: df.info(), df.describe(include='all')]* +> +> AI: "I found a few issues: 'CustomerID' is stored as text but should be numeric, and there are 847 missing values in 'SalesAmount'. Would you like me to convert 'CustomerID' to numeric and fill the missing 'SalesAmount' values with the median?" +> +> User: "Yes, please do that and show me the updated info" +> +> AI: "Done! CustomerID is now numeric and SalesAmount gaps are filled. Your dataset is clean and ready for modeling." + +*[Later in the session, after you've trained a model...]* + +> User: "How is my model performing?" +> +> AI: "Let me generate the key metrics for your trained model" +> +> *[AI accesses the existing model variable and generates evaluation metrics]* +> +> AI: "Your Random Forest achieved 0.84 precision and 0.81 recall. The confusion matrix shows some false positives in the high-value sales category. Would you like me to adjust the decision threshold or try feature engineering?" + +This fluid back-and-forth, where the assistant understands and builds upon the existing notebook state, allows for seamless collaboration without the need for constant context re-establishment or data reloading. + +## Example notebook + +Here you can see an example notebook that was handled by the MCP Jupyter Server. The server + +**[📓 View the Complete Demo Notebook](https://github.com/block/mcp-jupyter/blob/main/demos/demo.ipynb)** + +The demo walks through a typical data science workflow: +- **Install Missing Libraries**: Installing missing libraries for the notebook +- **Data Generation**: Creating synthetic data for analysis +- **Model Training**: Fitting a linear regression model with scikit-learn +- **Results Analysis**: Extracting model coefficients and performance metrics +- **Visualization**: Creating plots with seaborn + +## Getting Started + +The MCP Jupyter Server integrates seamlessly with existing workflows and can also be used with the notebook viewer in VS Code based IDEs. + +For detailed setup and configuration, check out the [complete documentation](https://block.github.io/mcp-jupyter/). + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/blog/authors.yml b/documentation/blog/authors.yml index b4526d0bf97a..37103279aa76 100644 --- a/documentation/blog/authors.yml +++ b/documentation/blog/authors.yml @@ -37,6 +37,32 @@ dalton: socials: github: dalton-turner +damien: + name: Damien Ramunno-Johnson + title: Principal Machine Learning Engineer + image_url: https://avatars.githubusercontent.com/u/2729283?v=4 + page: true + socials: + linkedin: damienrj + github: damienrj + +dean: + name: Dean Wyatte + title: Principal Machine Learning Engineer + image_url: https://avatars.githubusercontent.com/u/2512762?v=4 + page: true + socials: + github: dwyatte + +harrison: + name: Harrison Mamin + title: Senior Machine Learning Engineer + image_url: https://avatars.githubusercontent.com/u/114013937?v=4 + page: true + socials: + github: hdmamin + + tania: name: Tania Chakraborty title: Senior Technical Community Manager