Skip to content

Commit e13191a

Browse files
Fixing formatting issue in notebook (#512)
1 parent 5a139be commit e13191a

File tree

1 file changed

+70
-71
lines changed

1 file changed

+70
-71
lines changed

supporting-blog-content/elasticsearch-chatgpt-connector/elasticsearch-mcp-server-for-chatgpt.ipynb

Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,20 @@
139139
"metadata": {},
140140
"outputs": [],
141141
"source": [
142-
"os.environ[\"ELASTICSEARCH_URL\"] = os.environ.get(\"ELASTICSEARCH_URL\") or getpass(\"Enter your Elasticsearch URL: \")\n",
143-
"os.environ[\"ELASTICSEARCH_API_KEY\"] = os.environ.get(\"ELASTICSEARCH_API_KEY\") or getpass(\"Enter your Elasticsearch API key: \")\n",
144-
"os.environ[\"NGROK_TOKEN\"] = os.environ.get(\"NGROK_TOKEN\") or getpass(\"Enter your Ngrok Token: \")\n",
145-
"os.environ[\"ELASTICSEARCH_INDEX\"] = os.environ.get(\"ELASTICSEARCH_INDEX\") or getpass(\"Enter your Elasticsearch Index name (default: github_internal): \") or \"github_internal\"\n",
142+
"os.environ[\"ELASTICSEARCH_URL\"] = os.environ.get(\"ELASTICSEARCH_URL\") or getpass(\n",
143+
" \"Enter your Elasticsearch URL: \"\n",
144+
")\n",
145+
"os.environ[\"ELASTICSEARCH_API_KEY\"] = os.environ.get(\n",
146+
" \"ELASTICSEARCH_API_KEY\"\n",
147+
") or getpass(\"Enter your Elasticsearch API key: \")\n",
148+
"os.environ[\"NGROK_TOKEN\"] = os.environ.get(\"NGROK_TOKEN\") or getpass(\n",
149+
" \"Enter your Ngrok Token: \"\n",
150+
")\n",
151+
"os.environ[\"ELASTICSEARCH_INDEX\"] = (\n",
152+
" os.environ.get(\"ELASTICSEARCH_INDEX\")\n",
153+
" or getpass(\"Enter your Elasticsearch Index name (default: github_internal): \")\n",
154+
" or \"github_internal\"\n",
155+
")\n",
146156
"\n",
147157
"ELASTICSEARCH_URL = os.environ[\"ELASTICSEARCH_URL\"]\n",
148158
"ELASTICSEARCH_API_KEY = os.environ[\"ELASTICSEARCH_API_KEY\"]\n",
@@ -177,10 +187,7 @@
177187
},
178188
"outputs": [],
179189
"source": [
180-
"es_client = Elasticsearch(\n",
181-
" ELASTICSEARCH_URL,\n",
182-
" api_key=ELASTICSEARCH_API_KEY\n",
183-
")\n",
190+
"es_client = Elasticsearch(ELASTICSEARCH_URL, api_key=ELASTICSEARCH_API_KEY)\n",
184191
"\n",
185192
"if es_client.ping():\n",
186193
" print(\"Elasticsearch connection successful\")\n",
@@ -225,7 +232,7 @@
225232
" \"text\": {\"type\": \"text\"},\n",
226233
" \"text_semantic\": {\n",
227234
" \"type\": \"semantic_text\",\n",
228-
" \"inference_id\": \".elser-2-elasticsearch\"\n",
235+
" \"inference_id\": \".elser-2-elasticsearch\",\n",
229236
" },\n",
230237
" \"url\": {\"type\": \"keyword\"},\n",
231238
" \"type\": {\"type\": \"keyword\"},\n",
@@ -235,14 +242,14 @@
235242
" \"created_date\": {\"type\": \"date\", \"format\": \"iso8601\"},\n",
236243
" \"resolved_date\": {\"type\": \"date\", \"format\": \"iso8601\"},\n",
237244
" \"labels\": {\"type\": \"keyword\"},\n",
238-
" \"related_pr\": {\"type\": \"keyword\"}\n",
245+
" \"related_pr\": {\"type\": \"keyword\"},\n",
239246
" }\n",
240247
" }\n",
241-
" }\n",
248+
" },\n",
242249
" )\n",
243250
" print(f\"Index '{INDEX_NAME}' created successfully\")\n",
244251
"except Exception as e:\n",
245-
" if 'resource_already_exists_exception' in str(e):\n",
252+
" if \"resource_already_exists_exception\" in str(e):\n",
246253
" print(f\"Index '{INDEX_NAME}' already exists\")\n",
247254
" else:\n",
248255
" print(f\"Error creating index: {e}\")"
@@ -629,10 +636,10 @@
629636
}
630637
],
631638
"source": [
632-
"file_path = 'github_internal_dataset.json'\n",
639+
"file_path = \"github_internal_dataset.json\"\n",
633640
"df = pd.read_json(file_path)\n",
634641
"\n",
635-
"documents = df.to_dict('records')\n",
642+
"documents = df.to_dict(\"records\")\n",
636643
"print(f\"Loaded {len(documents)} documents from dataset\")\n",
637644
"\n",
638645
"df"
@@ -663,11 +670,9 @@
663670
"source": [
664671
"def generate_actions():\n",
665672
" for doc in documents:\n",
666-
" doc['text_semantic'] = doc['text']\n",
667-
" yield {\n",
668-
" '_index': INDEX_NAME,\n",
669-
" '_source': doc\n",
670-
" }\n",
673+
" doc[\"text_semantic\"] = doc[\"text\"]\n",
674+
" yield {\"_index\": INDEX_NAME, \"_source\": doc}\n",
675+
"\n",
671676
"\n",
672677
"try:\n",
673678
" success, errors = bulk(es_client, generate_actions())\n",
@@ -679,7 +684,7 @@
679684
" print(\"Waiting 15 seconds for ELSER to process documents...\")\n",
680685
" time.sleep(15)\n",
681686
"\n",
682-
" count = es_client.count(index=INDEX_NAME)['count']\n",
687+
" count = es_client.count(index=INDEX_NAME)[\"count\"]\n",
683688
" print(f\"Total documents in index: {count}\")\n",
684689
"\n",
685690
"except Exception as e:\n",
@@ -725,10 +730,10 @@
725730
"Use search to find relevant issues/PRs, then fetch to get complete details.\n",
726731
"\"\"\"\n",
727732
"\n",
733+
"\n",
728734
"def create_server():\n",
729735
" mcp = FastMCP(\n",
730-
" name=\"Elasticsearch GitHub Issues MCP\",\n",
731-
" instructions=server_instructions\n",
736+
" name=\"Elasticsearch GitHub Issues MCP\", instructions=server_instructions\n",
732737
" )\n",
733738
"\n",
734739
" @mcp.tool()\n",
@@ -757,7 +762,7 @@
757762
" \"query\": {\n",
758763
" \"semantic\": {\n",
759764
" \"field\": \"text_semantic\",\n",
760-
" \"query\": query\n",
765+
" \"query\": query,\n",
761766
" }\n",
762767
" }\n",
763768
" }\n",
@@ -774,31 +779,33 @@
774779
" \"assignee^2\",\n",
775780
" \"type\",\n",
776781
" \"labels\",\n",
777-
" \"priority\"\n",
782+
" \"priority\",\n",
778783
" ],\n",
779784
" \"type\": \"best_fields\",\n",
780-
" \"fuzziness\": \"AUTO\"\n",
785+
" \"fuzziness\": \"AUTO\",\n",
781786
" }\n",
782787
" }\n",
783788
" }\n",
784-
" }\n",
789+
" },\n",
785790
" ],\n",
786791
" \"rank_window_size\": 50,\n",
787-
" \"rank_constant\": 60\n",
792+
" \"rank_constant\": 60,\n",
788793
" }\n",
789-
" }\n",
794+
" },\n",
790795
" )\n",
791796
"\n",
792797
" # Extract and format search results\n",
793798
" results = []\n",
794-
" if response and 'hits' in response:\n",
795-
" for hit in response['hits']['hits']:\n",
796-
" source = hit['_source']\n",
797-
" results.append({\n",
798-
" \"id\": source.get('id', hit['_id']),\n",
799-
" \"title\": source.get('title', 'Unknown'),\n",
800-
" \"url\": source.get('url', '')\n",
801-
" })\n",
799+
" if response and \"hits\" in response:\n",
800+
" for hit in response[\"hits\"][\"hits\"]:\n",
801+
" source = hit[\"_source\"]\n",
802+
" results.append(\n",
803+
" {\n",
804+
" \"id\": source.get(\"id\", hit[\"_id\"]),\n",
805+
" \"title\": source.get(\"title\", \"Unknown\"),\n",
806+
" \"url\": source.get(\"url\", \"\"),\n",
807+
" }\n",
808+
" )\n",
802809
"\n",
803810
" logger.info(f\"Found {len(results)} results\")\n",
804811
" return {\"results\": results}\n",
@@ -821,37 +828,29 @@
821828
" try:\n",
822829
" # Query by ID to get full document\n",
823830
" response = es_client.search(\n",
824-
" index=INDEX_NAME,\n",
825-
" body={\n",
826-
" \"query\": {\n",
827-
" \"term\": {\n",
828-
" \"id\": id\n",
829-
" }\n",
830-
" },\n",
831-
" \"size\": 1\n",
832-
" }\n",
831+
" index=INDEX_NAME, body={\"query\": {\"term\": {\"id\": id}}, \"size\": 1}\n",
833832
" )\n",
834833
"\n",
835-
" if not response or not response['hits']['hits']:\n",
834+
" if not response or not response[\"hits\"][\"hits\"]:\n",
836835
" raise ValueError(f\"Document with id '{id}' not found\")\n",
837836
"\n",
838-
" hit = response['hits']['hits'][0]\n",
839-
" source = hit['_source']\n",
837+
" hit = response[\"hits\"][\"hits\"][0]\n",
838+
" source = hit[\"_source\"]\n",
840839
"\n",
841840
" # Return all document fields\n",
842841
" result = {\n",
843-
" \"id\": source.get('id', id),\n",
844-
" \"title\": source.get('title', 'Unknown'),\n",
845-
" \"text\": source.get('text', ''),\n",
846-
" \"url\": source.get('url', ''),\n",
847-
" \"type\": source.get('type', ''),\n",
848-
" \"status\": source.get('status', ''),\n",
849-
" \"priority\": source.get('priority', ''),\n",
850-
" \"assignee\": source.get('assignee', ''),\n",
851-
" \"created_date\": source.get('created_date', ''),\n",
852-
" \"resolved_date\": source.get('resolved_date', ''),\n",
853-
" \"labels\": source.get('labels', ''),\n",
854-
" \"related_pr\": source.get('related_pr', '')\n",
842+
" \"id\": source.get(\"id\", id),\n",
843+
" \"title\": source.get(\"title\", \"Unknown\"),\n",
844+
" \"text\": source.get(\"text\", \"\"),\n",
845+
" \"url\": source.get(\"url\", \"\"),\n",
846+
" \"type\": source.get(\"type\", \"\"),\n",
847+
" \"status\": source.get(\"status\", \"\"),\n",
848+
" \"priority\": source.get(\"priority\", \"\"),\n",
849+
" \"assignee\": source.get(\"assignee\", \"\"),\n",
850+
" \"created_date\": source.get(\"created_date\", \"\"),\n",
851+
" \"resolved_date\": source.get(\"resolved_date\", \"\"),\n",
852+
" \"labels\": source.get(\"labels\", \"\"),\n",
853+
" \"related_pr\": source.get(\"related_pr\", \"\"),\n",
855854
" }\n",
856855
"\n",
857856
" logger.info(f\"Fetched: {result['title']}\")\n",
@@ -863,6 +862,7 @@
863862
"\n",
864863
" return mcp\n",
865864
"\n",
865+
"\n",
866866
"print(\"MCP server defined successfully\")"
867867
]
868868
},
@@ -892,16 +892,11 @@
892892
"ngrok.set_auth_token(NGROK_TOKEN)\n",
893893
"\n",
894894
"pyngrok_config = PyngrokConfig(region=\"us\")\n",
895-
"public_url = ngrok.connect(\n",
896-
" 8000,\n",
897-
" \"http\",\n",
898-
" pyngrok_config=pyngrok_config,\n",
899-
" bind_tls=True\n",
900-
")\n",
895+
"public_url = ngrok.connect(8000, \"http\", pyngrok_config=pyngrok_config, bind_tls=True)\n",
901896
"\n",
902-
"print(\"=\"*70)\n",
897+
"print(\"=\" * 70)\n",
903898
"print(\"MCP SERVER IS READY!\")\n",
904-
"print(\"=\"*70)\n",
899+
"print(\"=\" * 70)\n",
905900
"print(f\"\\nPublic URL (use in ChatGPT): {public_url}/sse\")\n",
906901
"print(\"\\nIMPORTANT: Copy the URL above (including /sse at the end)\")\n",
907902
"print(\"\\nTo connect in ChatGPT:\")\n",
@@ -910,7 +905,7 @@
910905
"print(\"3. Paste the URL above\")\n",
911906
"print(\"4. Save and start using!\")\n",
912907
"print(\"\\nKeep this notebook running while using the connector\")\n",
913-
"print(\"=\"*70)"
908+
"print(\"=\" * 70)"
914909
]
915910
},
916911
{
@@ -1089,9 +1084,11 @@
10891084
"print(\"Server is running. To stop: Runtime > Interrupt execution\")\n",
10901085
"print()\n",
10911086
"\n",
1087+
"\n",
10921088
"def run_server():\n",
10931089
" server.run(transport=\"sse\", host=\"0.0.0.0\", port=8000)\n",
10941090
"\n",
1091+
"\n",
10951092
"server_thread = threading.Thread(target=run_server, daemon=True)\n",
10961093
"server_thread.start()\n",
10971094
"\n",
@@ -1143,8 +1140,10 @@
11431140
"outputs": [],
11441141
"source": [
11451142
"try:\n",
1146-
" result = es_client.options(ignore_status=[400, 404]).indices.delete(index=INDEX_NAME)\n",
1147-
" if result.get('acknowledged', False):\n",
1143+
" result = es_client.options(ignore_status=[400, 404]).indices.delete(\n",
1144+
" index=INDEX_NAME\n",
1145+
" )\n",
1146+
" if result.get(\"acknowledged\", False):\n",
11481147
" print(f\"Index '{INDEX_NAME}' deleted successfully\")\n",
11491148
" else:\n",
11501149
" print(f\"Error deleting index: {result}\")\n",

0 commit comments

Comments
 (0)