File tree Expand file tree Collapse file tree 10 files changed +153
-24
lines changed
agents/chat_with_tools_agent Expand file tree Collapse file tree 10 files changed +153
-24
lines changed Original file line number Diff line number Diff line change @@ -45,14 +45,19 @@ COSMOSDB_CONTAINER_NAME="kabuto"
45
45
COSMOSDB_PARTITION_KEY = " /id"
46
46
47
47
# SQL Database Settings
48
- SQL_DATABASE_URI = " sqlite:///template_langgraph.db"
49
- # SQL_DATABASE_URI="postgresql://user:password@localhost:5432/db"
48
+ SQL_DATABASE_URI = " "
49
+ # SQL_DATABASE_URI="sqlite:///template_langgraph.db" # SQLite
50
+ # SQL_DATABASE_URI="postgresql://user:password@localhost:5432/db" # PostgreSQL
50
51
51
52
# Azure AI Search Settings
52
53
AI_SEARCH_ENDPOINT = " https://xxx.search.windows.net/"
53
54
AI_SEARCH_KEY = " xxx"
54
55
AI_SEARCH_INDEX_NAME = " kabuto"
55
56
57
+ # MCP Settings
58
+ MCP_CONFIG_PATH = " "
59
+ # MCP_CONFIG_PATH="./.vscode/mcp.json" # VS Code
60
+
56
61
# ---------
57
62
# Internals
58
63
# ---------
Original file line number Diff line number Diff line change
1
+ {
2
+ "servers" : {
3
+ "playwright" : {
4
+ "command" : " npx" ,
5
+ "args" : [" -y" , " @playwright/mcp@latest" , " --vision" ]
6
+ },
7
+ "filesystem" : {
8
+ "command" : " npx" ,
9
+ "args" : [" -y" , " @modelcontextprotocol/server-filesystem" , " ./assets" ]
10
+ },
11
+ "everything" : {
12
+ "command" : " npx" ,
13
+ "args" : [" -y" , " @modelcontextprotocol/server-everything" ]
14
+ }
15
+ }
16
+ }
Original file line number Diff line number Diff line change @@ -133,6 +133,10 @@ streamlit: ## run Streamlit
133
133
uv run streamlit run \
134
134
template_langgraph/services/streamlits/main.py
135
135
136
+ .PHONY : mcp-insppector
137
+ mcp-inspector : # # run MCP Inspector server
138
+ npx -y @modelcontextprotocol/inspector
139
+
136
140
# ---
137
141
# Project / Create indices
138
142
# ---
Original file line number Diff line number Diff line change 7
7
- [ 🤖 LangGraph Multi-Agent Supervisor] ( https://github.com/langchain-ai/langgraph-supervisor-py )
8
8
- [ Software Design 誌「実践 LLM アプリケーション開発」第 24 回サンプルコード] ( https://github.com/mahm/softwaredesign-llm-application/tree/main/24 )
9
9
- [ Streamlit] ( https://python.langchain.com/docs/integrations/callbacks/streamlit/ )
10
+ - [ LangChain MCP Adapters] ( https://github.com/langchain-ai/langchain-mcp-adapters )
11
+ - [ Research Agent with MCP Integration.] ( https://github.com/langchain-ai/deep_research_from_scratch/blob/main/src/deep_research_from_scratch/research_agent_mcp.py )
10
12
11
13
### Sample Codes
12
14
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ dependencies = [
13
13
" httpx>=0.28.1" ,
14
14
" langchain-azure-ai>=0.1.4" ,
15
15
" langchain-community>=0.3.27" ,
16
+ " langchain-mcp-adapters>=0.1.9" ,
16
17
" langchain-ollama>=0.3.6" ,
17
18
" langchain-openai>=0.3.28" ,
18
19
" langchain-text-splitters>=0.3.9" ,
Original file line number Diff line number Diff line change
1
+ import asyncio
1
2
import json
2
3
3
4
from langchain_core .messages import ToolMessage
6
7
from template_langgraph .agents .chat_with_tools_agent .models import AgentState
7
8
from template_langgraph .llms .azure_openais import AzureOpenAiWrapper
8
9
from template_langgraph .loggers import get_logger
9
- from template_langgraph .tools .common import get_default_tools
10
+ from template_langgraph .tools .common import get_default_tools , is_async_call_required
10
11
11
12
logger = get_logger (__name__ )
12
13
@@ -25,10 +26,13 @@ def __call__(self, inputs: dict):
25
26
outputs = []
26
27
for tool_call in message .tool_calls :
27
28
try :
28
- tool_result = self .tools_by_name [tool_call ["name" ]].invoke (tool_call ["args" ])
29
+ if is_async_call_required (tool_call ["name" ]):
30
+ observation = asyncio .run (self .tools_by_name [tool_call ["name" ]].ainvoke (tool_call ["args" ]))
31
+ else :
32
+ observation = self .tools_by_name [tool_call ["name" ]].invoke (tool_call ["args" ])
29
33
outputs .append (
30
34
ToolMessage (
31
- content = json .dumps (tool_result .__str__ (), ensure_ascii = False ),
35
+ content = json .dumps (observation .__str__ (), ensure_ascii = False ),
32
36
name = tool_call ["name" ],
33
37
tool_call_id = tool_call ["id" ],
34
38
)
Original file line number Diff line number Diff line change 4
4
from template_langgraph .tools .cosmosdb_tool import search_cosmosdb
5
5
from template_langgraph .tools .dify_tool import run_dify_workflow
6
6
from template_langgraph .tools .elasticsearch_tool import search_elasticsearch
7
+ from template_langgraph .tools .mcp_tool import McpClientWrapper
7
8
from template_langgraph .tools .qdrant_tool import search_qdrant
8
9
from template_langgraph .tools .sql_database_tool import SqlDatabaseClientWrapper
9
10
10
11
logger = get_logger (__name__ )
11
12
12
13
13
14
def get_default_tools ():
14
- try :
15
- sql_database_tools = SqlDatabaseClientWrapper ().get_tools (
15
+ return (
16
+ [
17
+ search_ai_search ,
18
+ search_cosmosdb ,
19
+ run_dify_workflow ,
20
+ search_qdrant ,
21
+ search_elasticsearch ,
22
+ ]
23
+ + SqlDatabaseClientWrapper ().get_tools (
16
24
llm = AzureOpenAiWrapper ().chat_model ,
17
25
)
18
- except Exception as e :
19
- logger .error (f"Error occurred while getting SQL database tools: { e } " )
20
- sql_database_tools = []
21
- return [
22
- search_ai_search ,
23
- search_cosmosdb ,
24
- run_dify_workflow ,
25
- search_qdrant ,
26
- search_elasticsearch ,
27
- ] + sql_database_tools
26
+ + McpClientWrapper ().get_tools ()
27
+ )
28
+
29
+
30
+ def is_async_call_required (tool_name : str ) -> bool :
31
+ # FIXME: adhoc impl
32
+ if tool_name .startswith ("browser_" ):
33
+ return True
34
+ return tool_name in [
35
+ "echo" ,
36
+ "add" ,
37
+ # add async tool names here
38
+ ]
Original file line number Diff line number Diff line change
1
+ import asyncio
2
+ import json
3
+ from functools import lru_cache
4
+
5
+ from langchain_core .tools .base import BaseTool
6
+ from langchain_mcp_adapters .client import MultiServerMCPClient
7
+ from pydantic_settings import BaseSettings , SettingsConfigDict
8
+
9
+
10
+ class Settings (BaseSettings ):
11
+ mcp_config_path : str = ""
12
+
13
+ model_config = SettingsConfigDict (
14
+ env_file = ".env" ,
15
+ env_ignore_empty = True ,
16
+ extra = "ignore" ,
17
+ )
18
+
19
+
20
+ @lru_cache
21
+ def get_mcp_settings () -> Settings :
22
+ """Get mcp settings."""
23
+ return Settings ()
24
+
25
+
26
+ class McpClientWrapper :
27
+ def __init__ (
28
+ self ,
29
+ settings : Settings = None ,
30
+ ):
31
+ if settings is None :
32
+ settings = get_mcp_settings ()
33
+ self .settings = settings
34
+
35
+ def get_tools (self ) -> list [BaseTool ]:
36
+ if self .settings .mcp_config_path == "" :
37
+ return []
38
+ with open (self .settings .mcp_config_path ) as f :
39
+ config = json .load (f )
40
+ for _ , value in config ["servers" ].items ():
41
+ value ["transport" ] = "stdio"
42
+ client = MultiServerMCPClient (config ["servers" ])
43
+ tools = asyncio .run (client .get_tools ())
44
+ return tools
Original file line number Diff line number Diff line change 8
8
9
9
10
10
class Settings (BaseSettings ):
11
- sql_database_uri : str = "sqlite:///template_langgraph.db "
11
+ sql_database_uri : str = ""
12
12
13
13
model_config = SettingsConfigDict (
14
14
env_file = ".env" ,
@@ -30,15 +30,19 @@ def __init__(
30
30
):
31
31
if settings is None :
32
32
settings = get_sql_database_settings ()
33
- self .db = SQLDatabase .from_uri (
34
- database_uri = settings .sql_database_uri ,
35
- )
33
+ self .settings = settings
36
34
37
35
def get_tools (
38
36
self ,
39
37
llm : BaseLanguageModel ,
40
38
) -> list [BaseTool ]:
41
39
"""Get SQL Database tools."""
40
+ if self .settings .sql_database_uri == "" :
41
+ return []
42
+
43
+ self .db = SQLDatabase .from_uri (
44
+ database_uri = self .settings .sql_database_uri ,
45
+ )
42
46
return SQLDatabaseToolkit (
43
47
db = self .db ,
44
48
llm = llm ,
You can’t perform that action at this time.
0 commit comments