You pass runtime context into a Tool by leveraging the context parameter in RunnableConfig, which propagates through the entire call chain, allowing tools to access values like userId, authToken, or tenantId without coupling them to the tool's input schema.
LangChain's RunnableConfig provides a clean, dependency-injection style way to pass contextual information through your agent's execution chain. By configuring a contextSchema on your agent, you define the shape of the runtime data you expect. This context is then automatically made available in the second argument of any tool's function, allowing the tool to access user-specific information like userId, authentication tokens, or database connections without the LLM needing to know about them or the user having to provide them. This keeps your tool's input schema focused on what the LLM should generate (e.g., query or productId), while sensitive or operational context is injected separately.
Define a Zod object that specifies the shape and types of the context your tools will need. This can include userId, authToken, tenantId, or even a database connection pool. This schema ensures type safety throughout your application.
When defining your tool, the async function receives config as its second parameter. The config.configurable object contains the merged context. You can then use the userId, authToken, or any other context value inside your tool's logic.
When you invoke your agent, you pass the runtime context as a property of the configurable object. This context is then propagated down to the tools.
For more complex scenarios where you need to pass a database connection pool or other non-serializable resources, you should instantiate these as singletons or request-scoped objects and store them directly in the configurable object. If you're using the createAgent factory, you can enforce the context schema by passing it to the contextSchema parameter. This ensures that all tools receive the correctly typed context and will cause a type error if you forget to provide required fields.
A significant benefit of this pattern is testability. You can easily unit-test your tools by passing a mock context directly to their invoke method, without needing to spin up a full agent or mock network requests if you design your tool to use dependency injection.
This pattern is a clean application of dependency injection for LangChain tools. It separates the concerns of what the LLM decides (the input arguments) from what the application provides (the runtime context). This makes your tools more reusable, testable, and secure, as sensitive information like auth tokens never need to be generated by the LLM or passed through the prompt.