{"id":606514,"date":"2025-07-07T17:30:31","date_gmt":"2025-07-07T22:30:31","guid":{"rendered":"https:\/\/towardsdatascience.com\/?p=606514"},"modified":"2025-07-07T17:31:03","modified_gmt":"2025-07-07T22:31:03","slug":"your-personal-analytics-toolbox","status":"publish","type":"post","link":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/","title":{"rendered":"Your Personal Analytics Toolbox"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><mdspan datatext=\"el1751927291102\" class=\"mdspan-comment\">Models are only <\/mdspan>as good as the context provided to them. Even the most advanced model won\u2019t be very helpful if it doesn\u2019t have access to the data or tools it needs to get more information<strong>. <\/strong>That\u2019s why tools and resources are crucial for any AI agent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ve noticed that I keep repeating the same tasks over and over again: writing similar prompts or developing the same tools repeatedly. There\u2019s a fundamental principle in software engineering called <strong>DRY<\/strong>, which stands for \u201c<em>Don\u2019t Repeat Yourself<\/em>\u201d.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, I started wondering if there\u2019s a way to avoid duplicating all this work. Fortunately, the GenAI industry already has a solution in place. <strong>MCP (Model Context Protocol)<\/strong> is an open-source protocol that enables the connection of AI applications to external tools and data sources. Its main goal is to standardise such interactions, similar to how REST APIs standardised communication between web applications and backend servers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With MCP, you can easily integrate third-party tools like GitHub, Stripe or even LinkedIn into your AI agent without having to build tools yourself.&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><em>You can find the list of MCP servers in <a href=\"https:\/\/github.com\/modelcontextprotocol\/servers\" target=\"_blank\" rel=\"noreferrer noopener\">this curated repository.<\/a> However, it\u2019s important to note that you should only use trusted MCP servers to avoid potential issues.<\/em><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly, if you want to expose your tools to customers (i.e. allow them to access your product through their LLM agents), you can simply build an MCP server. Then customers will be able to integrate with it from their LLM agents, AI assistants, desktop apps or IDEs. It\u2019s really convenient.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">MCP fundamentally solves the problem of repetitive work. Imagine you have M applications and N tools. Without MCP, you would need to build M * N integrations to connect them all.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1SFe1RYLiuEdcXzsYMrlNRQ.png\" alt=\"\" class=\"wp-image-607747\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">With MCP and standardisation, you can reduce this number to just M + N.&nbsp;<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/17E6YIauRVyx0m1pb4SovhQ.png\" alt=\"\" class=\"wp-image-607743\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In this article, I will use MCP to develop a toolkit for analysts. After reading this article, you will&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">learn how MCP actually works under the hood,&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\">build your first MCP server with useful tools,&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\">leverage the capabilities of your own MCP server and reference servers in your local AI IDE (like Cursor or Claude Desktop),&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\">launch a remote MCP server that could be accessible by the community.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In the following article, we will take it a step further and learn how to integrate MCP servers into your AI agents.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s a lot to cover, so let\u2019s get started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MCP architecture<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I think it\u2019s worth understanding the basic principles before jumping into practice, since that will help us use the tools more effectively. So let\u2019s discuss the fundamentals of this protocol.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Components<br>This protocol uses a client-server architecture:&nbsp;<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><strong>Server<\/strong> is an external program that exposes capabilities through the MCP protocol.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><strong>Host<\/strong> is the client-facing application (like Claude Desktop app, AI IDEs such as Cursor or Lovable, or custom LLM agents). The host is responsible for storing MCP clients and maintaining connections to servers.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><strong>Client<\/strong> is a component of the user-facing app that maintains a one-to-one connection with a single MCP server. They communicate through messages defined by the MCP protocol.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1emfHVLZDPjEbOpXV7azkNA.png\" alt=\"\" class=\"wp-image-607740\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">MCP allows LLM to access different capabilities: tools, resources and prompts.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><strong>Tools<\/strong> are functions that LLM can execute, such as getting the current time in a city or converting money from one currency to another.&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\"><strong>Resources<\/strong> are read-only data or context exposed by the server, such as a knowledge base or a change log.&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\"><strong>Prompts<\/strong> are pre-defined templates for AI interactions.&nbsp;<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1TW83vwOnKQ71F2e_PXLG1A.png\" alt=\"\" class=\"wp-image-607739\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">MCP allows you to write servers and tools in <a href=\"https:\/\/huggingface.co\/learn\/mcp-course\/unit1\/sdk#mcp-sdks\" target=\"_blank\" rel=\"noreferrer noopener\">many different languages<\/a>. In this article, we will be using the Python SDK.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lifecycle<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we know the main components defined in MCP, let\u2019s see how the full lifecycle of interaction between the MCP client and server works.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first step is <strong>initialisation<\/strong>. The client connects to the server, they exchange protocol versions and capabilities, and, finally, the client confirms via notification that initialisation has been completed.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1wCaqqlaUBXcYyclF3yR6FA.png\" alt=\"\" class=\"wp-image-607745\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then, we move to<strong> the message exchange phase<\/strong>.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">The client might start the interaction with <strong>discovery<\/strong>. MCP allows dynamic feature discovery, when the client can ask the server for a list of supported tools with requests like <code>tools\/list <\/code>and will get the list of exposed tools in response. This feature allows the client to adapt when working with different MCP servers.&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\">Also, the client can invoke capabilities (call a tool or access a resource). In this case, it can get back from the server not only a response but also progress notifications.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1Zb_KIW6qBicNRxupCfkQSQ.png\" alt=\"\" class=\"wp-image-607741\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, the client initiates <strong>the termination of the connection <\/strong>by<strong> <\/strong>sending a request to the server.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Transport<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If we dive a little bit deeper into the MCP architecture, it\u2019s also worth discussing transport. The transport defines how messages are sent and received between the client and server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At its core, MCP uses <a href=\"https:\/\/en.wikipedia.org\/wiki\/JSON-RPC\" rel=\"noreferrer noopener\" target=\"_blank\">the JSON-RPC protocol<\/a>. There are two transport options:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><strong>stdio<\/strong> (standard input and output) for cases when client and server are running on the same machine,&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\"><strong>HTTP + SSE<\/strong> (Server-Sent Events) or <strong>Streamable HTTP<\/strong> for cases when they need to communicate over a network. The primary difference between these two approaches lies in whether the connection is stateful (HTTP + SSE) or can also be stateless (Streamable HTTP), which can be crucial for certain applications.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">When running our server locally, we will use standard I\/O as transport. The client will launch the server as a subprocess, and they will use standard input and output to communicate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With that, we\u2019ve covered all the theory and are ready to move on to building our first MCP server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating your toolkit as a local MCP&nbsp;server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I would like to build a server with some standard tools I use frequently, and also leverage all the MCP capabilities we discussed above:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><strong>prompt template<\/strong> to query our ClickHouse database that outlines both the data schema and nuances of SQL syntax (<em>it\u2019s tedious to repeat it every time<\/em>),<\/li>\n\n\n\n<li class=\"wp-block-list-item\"><strong>tools<\/strong> to query the database and get some information about recent GitHub PRs,<\/li>\n\n\n\n<li class=\"wp-block-list-item\">our changelog as <strong>resources<\/strong>.<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><em>You can find the full code in <a href=\"https:\/\/github.com\/miptgirl\/mcp-analyst-toolkit\/blob\/main\/src\/mcp_server\/server.py\" target=\"_blank\" rel=\"noreferrer noopener\">repository<\/a>, I will show only the main server code in the snapshot below omitting all the business logic.<\/em><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">We will use the Python SDK for MCP. Creating an MCP server is pretty straightforward. Let\u2019s start with a skeleton. We imported the MCP package, initialised the server object and ran the server when the program is executed directly (not imported).<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">from mcp.server.fastmcp import FastMCP\nfrom mcp_server.prompts import CLICKHOUSE_PROMPT_TEMPLATE\nfrom mcp_server.tools import execute_query, get_databases, get_table_schema, get_recent_prs, get_pr_details\nfrom mcp_server.resources.change_log import get_available_periods, get_period_changelog\nimport os\n\n# Create an MCP server\nmcp = FastMCP(&quot;Analyst Toolkit&quot;)\n\n# Run the server\nif __name__ == &quot;__main__&quot;:\n    mcp.run()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we need to add the capabilities. We will do this by annotating functions. We will also write detailed docstrings and include type annotations to ensure that the LLM has all the necessary information to use them properly.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">@mcp.prompt()\ndef sql_query_prompt(question: str) -&gt; str:\n    &quot;&quot;&quot;Create a SQL query prompt&quot;&quot;&quot;\n    return CLICKHOUSE_PROMPT_TEMPLATE.format(question=question)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we will define tools similarly.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\"># ClickHouse tools\n\n@mcp.tool()\ndef execute_sql_query(query: str) -&gt; str:\n    &quot;&quot;&quot;\n    Execute a SQL query on the ClickHouse database.\n    \n    Args:\n        query: SQL query string to execute against ClickHouse\n        \n    Returns:\n        Query results as tab-separated text if successful, or error message if query fails\n    &quot;&quot;&quot;\n    return execute_query(query)\n\n@mcp.tool()\ndef list_databases() -&gt; str:\n    &quot;&quot;&quot;\n    List all databases in the ClickHouse server.\n    \n    Returns:\n        Tab-separated text containing the list of databases\n    &quot;&quot;&quot;\n    return get_databases()\n\n@mcp.tool()\ndef describe_table(table_name: str) -&gt; str:\n    &quot;&quot;&quot;\n    Get the schema of a specific table in the ClickHouse database.\n    \n    Args:\n        table_name: Name of the table to describe\n        \n    Returns:\n        Tab-separated text containing the table schema information\n    &quot;&quot;&quot;\n    return get_table_schema(table_name)\n\n# GitHub tools\n@mcp.tool()\ndef get_github_prs(repo_url: str, days: int = 7) -&gt; str:\n    &quot;&quot;&quot;\n    Get a list of PRs from the last N days.\n    \n    Args:\n        repo_url: GitHub repository URL or owner\/repo format\n        days: Number of days to look back (default: 7)\n        \n    Returns:\n        JSON string containing list of PR information, or error message\n    &quot;&quot;&quot;\n    import json\n    token = os.getenv(&#039;GITHUB_TOKEN&#039;)\n    result = get_recent_prs(repo_url, days, token)\n    return json.dumps(result, indent=2)\n\n@mcp.tool()\ndef get_github_pr_details(repo_url: str, pr_identifier: str) -&gt; str:\n    &quot;&quot;&quot;\n    Get detailed information about a specific PR.\n    \n    Args:\n        repo_url: GitHub repository URL or owner\/repo format\n        pr_identifier: Either PR number or PR URL\n        \n    Returns:\n        JSON string containing detailed PR information, or error message\n    &quot;&quot;&quot;\n    import json\n    token = os.getenv(&#039;GITHUB_TOKEN&#039;)\n    result = get_pr_details(repo_url, pr_identifier, token)\n    return json.dumps(result, indent=2)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, it\u2019s time to add resources. I\u2019ve added two methods: one to see what changelog periods we have available, and another to extract information for a specific period. Also, as you might have noticed, we used URIs to access resources.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">@mcp.resource(&quot;changelog:\/\/periods&quot;)\ndef changelog_periods() -&gt; str:\n    &quot;&quot;&quot;\n    List all available change log periods.\n    \n    Returns:\n        Markdown formatted list of available time periods\n    &quot;&quot;&quot;\n    return get_available_periods()\n\n@mcp.resource(&quot;changelog:\/\/{period}&quot;)\ndef changelog_for_period(period: str) -&gt; str:\n    &quot;&quot;&quot;\n    Get change log for a specific time period.\n    \n    Args:\n        period: The time period identifier (e.g., &quot;2025_q1&quot; or &quot;2025 Q2&quot;)\n        \n    Returns:\n        Markdown formatted change log for the specified period\n    &quot;&quot;&quot;\n    return get_period_changelog(period)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s it for the code. The last step is setting up the environment. I will use <a href=\"https:\/\/github.com\/astral-sh\/uv\" rel=\"noreferrer noopener\" target=\"_blank\">the uv package manager<\/a>, which is recommended in the MCP documentation.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you don\u2019t have it installed, you can get it from PyPI.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">pip install uv<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, we can initialise a uv project, create and activate the virtual environment and, finally, install all the required packages.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">uv init --name mcp-analyst-toolkit # initialise an uv project\nuv venv # create virtual env \nsource .venv\/bin\/activate # activate environment\nuv add &quot;mcp[cli]&quot; requests pandas typing requests datetime \n# adding dependencies\nuv pip install -e . # installing package mcp_server<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we can run the MCP server locally. I will use the developer model since it also launches MCP Inspector, which is really useful for debugging.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">mcp dev server.py\n\n# Starting MCP inspector...\n# \u2699\ufe0f Proxy server listening on 127.0.0.1:6277\n# \ud83d\udd11 Session token: &lt;...&gt;\n# Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth\n\n# \ud83d\udd17 Open inspector with token pre-filled:\n#   http:\/\/localhost:6274\/?MCP_PROXY_AUTH_TOKEN=&lt;...&gt;\n\n# \ud83d\udd0d MCP Inspector is up and running at http:\/\/127.0.0.1:6274 \ud83d\ude80<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we have our server and MCP Inspector running locally. Essentially, MCP Inspector is a handy implementation of the MCP client designed for debugging. Let\u2019s use the Inspector to test how our server works. The inspector lets us see all the capabilities the server exposes and call its tools. I started with feature discovery, requesting the server to share the list of tools. The client sent the <code>tools\/list<\/code> request we discussed earlier, as you can see in the history log at the bottom of the screen. Then, I executed a simple SQL query <code>select 1<\/code> and got the tool call result back.<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/19E2ruaMzIaMJoSLVitBR0g.png\" alt=\"\" class=\"wp-image-607748\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Great! Our first MCP server is up and running locally. So, it\u2019s time to start using it in practice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using MCP servers in AI&nbsp;tools&nbsp;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">As we discussed, the power of MCP servers lies in standardisation, which allows them to work with different AI tools. I will integrate my tools into Claude Desktop. Since Anthropic developed MCP, I expect their desktop client to have the best support for this protocol. However, you can use other clients like Cursor or Windsurf (<a href=\"https:\/\/modelcontextprotocol.io\/clients\" rel=\"noreferrer noopener\" target=\"_blank\">other example clients<\/a>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I would like not only to utilise my tools, but also to leverage the work of others. There are a <a href=\"https:\/\/github.com\/modelcontextprotocol\/servers\" rel=\"noreferrer noopener\" target=\"_blank\">lot of MCP servers<\/a> developed by the community that we can use instead of reinventing the wheel when we need common functions. However, keep in mind that MCP servers can access your system, so use only trusted implementations. I will use two reference servers (implemented to demonstrate the capabilities of the MCP protocol and official SDKs):&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\"><a href=\"https:\/\/github.com\/modelcontextprotocol\/servers\/tree\/main\/src\/filesystem\" target=\"_blank\" rel=\"noreferrer noopener\">Filesystem<\/a>\u200a\u2014\u200aallows working with local files,&nbsp;<\/li>\n\n\n\n<li class=\"wp-block-list-item\"><a href=\"https:\/\/github.com\/modelcontextprotocol\/servers\/tree\/main\/src\/fetch\" target=\"_blank\" rel=\"noreferrer noopener\">Fetch<\/a>\u200a\u2014\u200ahelps LLMs retrieve the content of webpages and convert it from HTML to markdown for better readability.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let\u2019s move on to the setup. You can follow the detailed instructions on how to set up Claude Desktop <a href=\"https:\/\/modelcontextprotocol.io\/quickstart\/user\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. All these tools have configuration files where you can specify the MCP servers. For the Claude Desktop, this file will be located at:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">macOS: <code>~\/Library\/Application Support\/Claude\/claude_desktop_config.json<\/code>,<\/li>\n\n\n\n<li class=\"wp-block-list-item\">Windows: <code>%APPDATA%\\Claude\\claude_desktop_config.json<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s update the config to include three servers:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">For <code>analyst_toolkit<\/code> (our MCP server implementation), I\u2019ve specified the <code>uv<\/code> command, path to the repository and command to run the server. Also, I\u2019ve added a <code>GITHUB_TOKEN<\/code> environment variable to use for GitHub authentication.<\/li>\n\n\n\n<li class=\"wp-block-list-item\">For the reference servers, I\u2019ve just copied the configs from the documentation. Since they are implemented in different languages (TypeScript and Python), different commands (<code>npx<\/code> and <code>uvx<\/code>) are needed.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\">{\n  &quot;mcpServers&quot;: {\n    &quot;analyst_toolkit&quot;: {\n      &quot;command&quot;: &quot;uv&quot;,\n      &quot;args&quot;: [\n        &quot;--directory&quot;,\n        &quot;\/path\/to\/github\/mcp-analyst-toolkit\/src\/mcp_server&quot;,\n        &quot;run&quot;,\n        &quot;server.py&quot;\n      ],\n      &quot;env&quot;: {\n          &quot;GITHUB_TOKEN&quot;: &quot;your_github_token&quot;\n      }\n    },\n    &quot;filesystem&quot;: {\n      &quot;command&quot;: &quot;npx&quot;,\n      &quot;args&quot;: [\n        &quot;-y&quot;,\n        &quot;@modelcontextprotocol\/server-filesystem&quot;,\n        &quot;\/Users\/marie\/Desktop&quot;,\n        &quot;\/Users\/marie\/Documents\/github&quot;\n      ]\n    },\n    &quot;fetch&quot;: {\n        &quot;command&quot;: &quot;uvx&quot;,\n        &quot;args&quot;: [&quot;mcp-server-fetch&quot;]\n      }\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s it. Now, we just need to restart the Claude Desktop client, and we will have access to all tools and prompt templates.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1YeQhiQjsIiNkOi-ANCMdDQ.png\" alt=\"\" class=\"wp-image-607744\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s try using the prompt template and ask the LLM to visualise high-level KPIs.&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Question<\/strong>: Could you please show the number of active customers and revenue by month since the beginning of 2024? Please, create a visualisation to look at dynamics and save the image in Desktop folder.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">We described the task at a fairly high level without providing much detail about the data schema or ClickHouse dialect. Still, since all this information is captured in our prompt template, the LLM managed to compose a correct SQL query.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-sql\">select \n    toStartOfMonth(s.action_date) as month,\n    uniqExact(s.user_id) as active_customers,\n    sum(s.revenue) as total_revenue\nfrom ecommerce.sessions as s \ninner join ecommerce.users as u on s.user_id = u.user_id\nwhere s.action_date &gt;= &#039;2024-01-01&#039; \n    and u.is_active = 1\ngroup by toStartOfMonth(s.action_date)\norder by month\nformat TabSeparatedWithNames<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, the agent used our <code>execute_sql_query<\/code> tool to get results, composed the HTML page with visualisations, and leveraged the <code>write_file<\/code> tool from the Filesystem MCP server to save the results as an HTML file.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The final report looks really good.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1NDD9ovUcR3yTuX42EzB-xg.png\" alt=\"\" class=\"wp-image-607749\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">One limitation of the current prompt template implementation is that you have to select it manually. The LLM can\u2019t automatically choose to use the template even when it\u2019s appropriate for the task. We\u2019ll try to address this in our AI agent implementation in the upcoming article.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another use case is trying out GitHub tools by asking about recent updates in the llama-cookbook repository from the past month. The agent completed this task successfully and provided us with a detailed summary.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1QAMaw7vubq8xuRm_-U0iwQ.png\" alt=\"\" class=\"wp-image-607750\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">So, we\u2019ve learned how to work with the local MCP servers. Let\u2019s discuss what to do if we want to share our tools more broadly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Working with a remote MCP&nbsp;server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We will use Gradio and HuggingFace Spaces for hosting a public MCP server. Gradio has a built-in integration with MCP, making server creation really simple. This is all the code needed to build the UI and launch the MCP server.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">import gradio as gr\nfrom statsmodels.stats.proportion import confint_proportions_2indep\n\ndef calculate_ci(count1: int, n1: int, count2: int, n2: int):\n    &quot;&quot;&quot;\n    Calculate 95% confidence interval for the difference of two independent proportions.\n    \n    Args:\n        count1 (int): Number of successes in group 1\n        n1 (int): Total sample size in group 1\n        count2 (int): Number of successes in group 2\n        n2 (int): Total sample size in group 2\n    \n    Returns:\n        str: Formatted string containing group proportions, difference, and 95% confidence interval\n    &quot;&quot;&quot;\n    try:\n        p1 = count1 \/ n1\n        p2 = count2 \/ n2\n        diff = p1 - p2\n        \n        ci_low, ci_high = confint_proportions_2indep(count1, n1, count2, n2)\n        \n        return f&quot;&quot;&quot;Group 1: {p1:.3f} | Group 2: {p2:.3f} | Difference: {diff:.3f}\n95% CI: [{ci_low:.3f}, {ci_high:.3f}]&quot;&quot;&quot;\n        \n    except Exception as e:\n        return f&quot;Error: {str(e)}&quot;\n\n# Simple interface\ndemo = gr.Interface(\n    fn=calculate_ci,\n    inputs=[\n        gr.Number(label=&quot;Group 1 successes&quot;, value=85, precision=0),\n        gr.Number(label=&quot;Group 1 total&quot;, value=100, precision=0),\n        gr.Number(label=&quot;Group 2 successes&quot;, value=92, precision=0),\n        gr.Number(label=&quot;Group 2 total&quot;, value=100, precision=0)\n    ],\n    outputs=&quot;text&quot;,\n    title=&quot;A\/B Test Confidence Interval&quot;,\n    description=&quot;Calculate 95% CI for difference of two proportions&quot;\n)\n\n# Launch the Gradio web interface\nif __name__ == &quot;__main__&quot;:\n    demo.launch(mcp_server = True)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I\u2019ve created a single function that calculates the confidence interval for the difference of two independent proportions. It might be helpful when analysing the A\/B test results.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we can push this code to HuggingFace Spaces to get a server running. I\u2019ve covered how to do it step-by-step in <a href=\"https:\/\/towardsdatascience.com\/understanding-retention-with-gradio-c288b48918af\/\" target=\"_blank\" rel=\"noreferrer noopener\">one of my previous articles<\/a>. For this example, I created this Space\u200a\u2014\u200a<a href=\"https:\/\/huggingface.co\/spaces\/miptgirl\/ab_tests\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/huggingface.co\/spaces\/miptgirl\/ab_tests<\/a>. It has a clean UI and exposes MCP tools.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1i00iJV0xOdtFefbBx4yDCQ.png\" alt=\"\" class=\"wp-image-607742\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we can add the server to our Claude Desktop configuration like this. We are using <code>mcp-remote<\/code> as a transport this time since we\u2019re now connecting to a remote server.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\">{\n  &quot;mcpServers&quot;: {\n    &quot;gradio&quot;: {\n      &quot;command&quot;: &quot;npx&quot;,\n      &quot;args&quot;: [\n        &quot;mcp-remote&quot;,\n        &quot;https:\/\/miptgirl-ab-tests.hf.space\/gradio_api\/mcp\/sse&quot;,\n        &quot;--transport&quot;,\n        &quot;sse-only&quot;\n      ]\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s test it with a simple A\/B test analysis question. It works well. The LLM can now make thoughtful judgments based on statistical significance.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/07\/1Mar2KL_xVUzMqkxcimSTBQ.png\" alt=\"\" class=\"wp-image-607746\"\/><figcaption class=\"wp-element-caption\">Image by author<\/figcaption><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><em>You can also use Gradio integration to build an MCP Client\u200a\u2014\u200a<a href=\"https:\/\/huggingface.co\/learn\/mcp-course\/unit2\/gradio-client\" target=\"_blank\" rel=\"noreferrer noopener\">documentation<\/a><\/em><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">And that\u2019s it! We now know how to share our tools with a wider audience.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this article, we\u2019ve explored the MCP protocol and its capabilities. Let\u2019s briefly recap the main points:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">MCP (Model Context Protocol) is a protocol developed by Antropic that aims to standardise communication between AI agents and tools. This approach reduces the number of integrations needed from M * N to M + N. The MCP protocol uses a client-server architecture.<\/li>\n\n\n\n<li class=\"wp-block-list-item\">MCP servers expose capabilities (such as resources, tools and prompt templates). You can easily build your own MCP servers using SDKs or use servers developed by the community.<\/li>\n\n\n\n<li class=\"wp-block-list-item\">MCP clients are part of user-facing apps (hosts) responsible for establishing a one-to-one connection with a server. There are many available apps compatible with MCP, such as Claude Desktop, Cursor or Windsurf.<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><em>Thank you for reading. I hope this article was insightful. Remember Einstein\u2019s advice: \u201cThe important thing is not to stop questioning. Curiosity has its own reason for existing.\u201d May your curiosity lead you to your next great insight.<\/em><\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Reference<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This article is inspired by the <a href=\"https:\/\/www.deeplearning.ai\/short-courses\/ai-agents-in-langgraph\/\" rel=\"noreferrer noopener\" target=\"_blank\"><em>\u201c<\/em><\/a><a href=\"https:\/\/www.deeplearning.ai\/short-courses\/mcp-build-rich-context-ai-apps-with-anthropic\/\" rel=\"noreferrer noopener\" target=\"_blank\"><em>MCP: Build Rich-Context AI Apps with Anthropic<\/em><\/a><a href=\"https:\/\/www.deeplearning.ai\/short-courses\/ai-agents-in-langgraph\/\" rel=\"noreferrer noopener\" target=\"_blank\"><em>\u201d<\/em><\/a> short course from <em>DeepLearning.AI<\/em> and <a href=\"https:\/\/huggingface.co\/learn\/mcp-course\/unit0\/introduction\" rel=\"noreferrer noopener\" target=\"_blank\"><em>the MCP course by Hugging Face<\/em><\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Leveraging MCP for automating your daily\u00a0routine<\/p>\n","protected":false},"author":18,"featured_media":606515,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"is_member_only":false,"sub_heading":"Leveraging MCP for automating your daily\u00a0routine","footnotes":""},"categories":[17],"tags":[453,465,446,32614,14585],"sponsor":[],"coauthors":[30132],"class_list":["post-606514","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artificial-intelligence","tag-editors-pick","tag-llm","tag-machine-learning","tag-mcp","tag-producitivity"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Your Personal Analytics Toolbox | Towards Data Science<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Your Personal Analytics Toolbox | Towards Data Science\" \/>\n<meta property=\"og:description\" content=\"Leveraging MCP for automating your daily\u00a0routine\" \/>\n<meta property=\"og:url\" content=\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\" \/>\n<meta property=\"og:site_name\" content=\"Towards Data Science\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-07T22:30:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-07T22:31:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1-1024x582.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"582\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Mariya Mansurova\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@TDataScience\" \/>\n<meta name=\"twitter:site\" content=\"@TDataScience\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mariya Mansurova\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\"},\"author\":{\"name\":\"TDS Editors\",\"@id\":\"https:\/\/towardsdatascience.com\/#\/schema\/person\/f9925d336b6fe962b03ad8281d90b8ee\"},\"headline\":\"Your Personal Analytics Toolbox\",\"datePublished\":\"2025-07-07T22:30:31+00:00\",\"dateModified\":\"2025-07-07T22:31:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\"},\"wordCount\":2370,\"publisher\":{\"@id\":\"https:\/\/towardsdatascience.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png\",\"keywords\":[\"Editors Pick\",\"Llm\",\"Machine Learning\",\"mcp\",\"producitivity\"],\"articleSection\":[\"Artificial Intelligence\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\",\"url\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\",\"name\":\"Your Personal Analytics Toolbox | Towards Data Science\",\"isPartOf\":{\"@id\":\"https:\/\/towardsdatascience.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png\",\"datePublished\":\"2025-07-07T22:30:31+00:00\",\"dateModified\":\"2025-07-07T22:31:03+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage\",\"url\":\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png\",\"contentUrl\":\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png\",\"width\":2560,\"height\":1456,\"caption\":\"Image generated by the author with DALL-E 3\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/towardsdatascience.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Your Personal Analytics Toolbox\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/towardsdatascience.com\/#website\",\"url\":\"https:\/\/towardsdatascience.com\/\",\"name\":\"Towards Data Science\",\"description\":\"Publish AI, ML &amp; data-science insights to a global community of data professionals.\",\"publisher\":{\"@id\":\"https:\/\/towardsdatascience.com\/#organization\"},\"alternateName\":\"TDS\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/towardsdatascience.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/towardsdatascience.com\/#organization\",\"name\":\"Towards Data Science\",\"alternateName\":\"TDS\",\"url\":\"https:\/\/towardsdatascience.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/towardsdatascience.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/02\/tds-logo.jpg\",\"contentUrl\":\"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/02\/tds-logo.jpg\",\"width\":696,\"height\":696,\"caption\":\"Towards Data Science\"},\"image\":{\"@id\":\"https:\/\/towardsdatascience.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/TDataScience\",\"https:\/\/www.youtube.com\/c\/TowardsDataScience\",\"https:\/\/www.linkedin.com\/company\/towards-data-science\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/towardsdatascience.com\/#\/schema\/person\/f9925d336b6fe962b03ad8281d90b8ee\",\"name\":\"TDS Editors\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/towardsdatascience.com\/#\/schema\/person\/image\/23494c9101089ad44ae88ce9d2f56aac\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"caption\":\"TDS Editors\"},\"description\":\"Building a vibrant data science and machine learning community. Share your insights and projects with our global audience: bit.ly\/write-for-tds\",\"url\":\"https:\/\/towardsdatascience.com\/author\/towardsdatascience\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Your Personal Analytics Toolbox | Towards Data Science","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/","og_locale":"en_US","og_type":"article","og_title":"Your Personal Analytics Toolbox | Towards Data Science","og_description":"Leveraging MCP for automating your daily\u00a0routine","og_url":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/","og_site_name":"Towards Data Science","article_published_time":"2025-07-07T22:30:31+00:00","article_modified_time":"2025-07-07T22:31:03+00:00","og_image":[{"width":1024,"height":582,"url":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1-1024x582.png","type":"image\/png"}],"author":"Mariya Mansurova","twitter_card":"summary_large_image","twitter_creator":"@TDataScience","twitter_site":"@TDataScience","twitter_misc":{"Written by":"Mariya Mansurova","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#article","isPartOf":{"@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/"},"author":{"name":"TDS Editors","@id":"https:\/\/towardsdatascience.com\/#\/schema\/person\/f9925d336b6fe962b03ad8281d90b8ee"},"headline":"Your Personal Analytics Toolbox","datePublished":"2025-07-07T22:30:31+00:00","dateModified":"2025-07-07T22:31:03+00:00","mainEntityOfPage":{"@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/"},"wordCount":2370,"publisher":{"@id":"https:\/\/towardsdatascience.com\/#organization"},"image":{"@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage"},"thumbnailUrl":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png","keywords":["Editors Pick","Llm","Machine Learning","mcp","producitivity"],"articleSection":["Artificial Intelligence"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/","url":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/","name":"Your Personal Analytics Toolbox | Towards Data Science","isPartOf":{"@id":"https:\/\/towardsdatascience.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage"},"image":{"@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage"},"thumbnailUrl":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png","datePublished":"2025-07-07T22:30:31+00:00","dateModified":"2025-07-07T22:31:03+00:00","breadcrumb":{"@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#primaryimage","url":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png","contentUrl":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/07\/Screenshot-2025-07-04-at-23.15.30-scaled-1.png","width":2560,"height":1456,"caption":"Image generated by the author with DALL-E 3"},{"@type":"BreadcrumbList","@id":"https:\/\/towardsdatascience.com\/your-personal-analytics-toolbox\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/towardsdatascience.com\/"},{"@type":"ListItem","position":2,"name":"Your Personal Analytics Toolbox"}]},{"@type":"WebSite","@id":"https:\/\/towardsdatascience.com\/#website","url":"https:\/\/towardsdatascience.com\/","name":"Towards Data Science","description":"Publish AI, ML &amp; data-science insights to a global community of data professionals.","publisher":{"@id":"https:\/\/towardsdatascience.com\/#organization"},"alternateName":"TDS","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/towardsdatascience.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/towardsdatascience.com\/#organization","name":"Towards Data Science","alternateName":"TDS","url":"https:\/\/towardsdatascience.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/towardsdatascience.com\/#\/schema\/logo\/image\/","url":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/02\/tds-logo.jpg","contentUrl":"https:\/\/towardsdatascience.com\/wp-content\/uploads\/2025\/02\/tds-logo.jpg","width":696,"height":696,"caption":"Towards Data Science"},"image":{"@id":"https:\/\/towardsdatascience.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/TDataScience","https:\/\/www.youtube.com\/c\/TowardsDataScience","https:\/\/www.linkedin.com\/company\/towards-data-science\/"]},{"@type":"Person","@id":"https:\/\/towardsdatascience.com\/#\/schema\/person\/f9925d336b6fe962b03ad8281d90b8ee","name":"TDS Editors","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/towardsdatascience.com\/#\/schema\/person\/image\/23494c9101089ad44ae88ce9d2f56aac","url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","caption":"TDS Editors"},"description":"Building a vibrant data science and machine learning community. Share your insights and projects with our global audience: bit.ly\/write-for-tds","url":"https:\/\/towardsdatascience.com\/author\/towardsdatascience\/"}]}},"distributor_meta":false,"distributor_terms":false,"distributor_media":false,"distributor_original_site_name":"TDS Contributor Portal","distributor_original_site_url":"https:\/\/contributor.insightmediagroup.io","push-errors":false,"_links":{"self":[{"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/posts\/606514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/comments?post=606514"}],"version-history":[{"count":0,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/posts\/606514\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/media\/606515"}],"wp:attachment":[{"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/media?parent=606514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/categories?post=606514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/tags?post=606514"},{"taxonomy":"sponsor","embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/sponsor?post=606514"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/towardsdatascience.com\/wp-json\/wp\/v2\/coauthors?post=606514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}