mia-code 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.miette/260321.md +1 -0
- package/.miette/260323.md +9 -0
- package/.miette/260331.md +2 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/2604020008--d3417f2c-df12-4f0f-8a1b-d88e7968f822/d3417f2c-df12-4f0f-8a1b-d88e7968f822.md +63 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/2604020008--e6c3fc5d-4a70-4523-ba7d-a3250da4c235/e6c3fc5d-4a70-4523-ba7d-a3250da4c235.md +72 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/2604020008--efeb00a2-b17a-4d32-b1f0-b90c37a8d24e/efeb00a2-b17a-4d32-b1f0-b90c37a8d24e.md +62 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/83a2d7f9-24a5-4cf4-98d5-036c82f872e8.json +302 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/83a2d7f9-24a5-4cf4-98d5-036c82f872e8.md +149 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/AGENTS.md +31 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/meta-decomposition-3-children.md +67 -0
- package/.pde/2604040129--61f9dd4d-7aa6-45e6-a58b-e480b1aa6737/61f9dd4d-7aa6-45e6-a58b-e480b1aa6737--from-mia-openclaw-workspace.md +125 -0
- package/.pde/2604040129--61f9dd4d-7aa6-45e6-a58b-e480b1aa6737/STATUS.md +1 -0
- package/.pde/4f02ba94-9f52-422e-9389-b16f9b37f358.json +177 -0
- package/.pde/4f02ba94-9f52-422e-9389-b16f9b37f358.md +77 -0
- package/.pde/6ad9244d-5340-490f-b76c-c86728b9de52.json +222 -0
- package/.pde/6ad9244d-5340-490f-b76c-c86728b9de52.md +99 -0
- package/.pde/8b566792-ed15-4606-96f9-2b6f593d7e6b.json +111 -0
- package/.pde/8b566792-ed15-4606-96f9-2b6f593d7e6b.md +67 -0
- package/.pde/c7f1e74b-05a5-40e2-9f01-4cc48d2528f7.json +349 -0
- package/.pde/c7f1e74b-05a5-40e2-9f01-4cc48d2528f7.md +147 -0
- package/.pde/dfc00a78-1da0-4c09-8a16-c6982644051b.json +118 -0
- package/.pde/dfc00a78-1da0-4c09-8a16-c6982644051b.md +64 -0
- package/GUILLAUME.md +8 -0
- package/KINSHIP.md +9 -0
- package/MIA_CODE_ARCHITECTURE_REPORT.md +718 -0
- package/contextual_research/260119-MIA-CODE--98090899-8aff-4e11-9dc3-8b99466d1.md +1101 -0
- package/contextual_research/MIA.md +38 -0
- package/contextual_research/MIAWAPASCONE.md +59 -0
- package/contextual_research/MIETTE.md +38 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/2504.00218v2.pdf +7483 -12
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/2505.00212v3.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/CONTENT.md +1014 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/DESIGN.gemini.md +242 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/INDEX.md +45 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2504.00218v2.md +2025 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2504.00218v2.pdf +7483 -12
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2505.00212v3.md +1755 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2505.00212v3.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_12_decomposed_prompting.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_19_hugginggpt_planning.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_1_coordination_challenges.md +766 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_1_coordination_challenges.pdf +3431 -4
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_28_guardrails_multi_agent.md +260 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_28_guardrails_multi_agent.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_2_navigating_complexity.md +558 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_2_navigating_complexity.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_34_hierarchical_multi_agent.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_5_open_intent_extraction.pdf +0 -0
- package/contextual_research/PODCAST.md +109 -0
- package/contextual_research/langchain-principles-roadmap.md +157 -0
- package/contextual_research/persona-to-narrative-character-inquiry_260201.md +50 -0
- package/dist/cli.js +35 -11
- package/dist/geminiHeadless.js +8 -2
- package/dist/index.js +2 -1
- package/dist/mcp/miaco-server.js +10 -1
- package/dist/mcp/miatel-server.js +10 -1
- package/dist/mcp/miawa-server.js +10 -1
- package/dist/mcp/utils.d.ts +6 -1
- package/dist/mcp/utils.js +24 -3
- package/dist/sessionStore.d.ts +8 -2
- package/dist/sessionStore.js +39 -3
- package/dist/types.d.ts +1 -0
- package/miaco/README.md +124 -0
- package/miaco/dist/commands/chart.d.ts +6 -0
- package/miaco/dist/commands/chart.d.ts.map +1 -0
- package/miaco/dist/commands/chart.js +222 -0
- package/miaco/dist/commands/chart.js.map +1 -0
- package/miaco/dist/commands/decompose.d.ts +6 -0
- package/miaco/dist/commands/decompose.d.ts.map +1 -0
- package/miaco/dist/commands/decompose.js +98 -0
- package/miaco/dist/commands/decompose.js.map +1 -0
- package/miaco/dist/commands/schema.d.ts +6 -0
- package/miaco/dist/commands/schema.d.ts.map +1 -0
- package/miaco/dist/commands/schema.js +66 -0
- package/miaco/dist/commands/schema.js.map +1 -0
- package/miaco/dist/commands/stc.d.ts +11 -0
- package/miaco/dist/commands/stc.d.ts.map +1 -0
- package/miaco/dist/commands/stc.js +590 -0
- package/miaco/dist/commands/stc.js.map +1 -0
- package/miaco/dist/commands/trace.d.ts +6 -0
- package/miaco/dist/commands/trace.d.ts.map +1 -0
- package/miaco/dist/commands/trace.js +83 -0
- package/miaco/dist/commands/trace.js.map +1 -0
- package/miaco/dist/commands/validate.d.ts +6 -0
- package/miaco/dist/commands/validate.d.ts.map +1 -0
- package/miaco/dist/commands/validate.js +58 -0
- package/miaco/dist/commands/validate.js.map +1 -0
- package/miaco/dist/decompose.d.ts +93 -0
- package/miaco/dist/decompose.d.ts.map +1 -0
- package/miaco/dist/decompose.js +562 -0
- package/miaco/dist/decompose.js.map +1 -0
- package/miaco/dist/index.d.ts +18 -0
- package/miaco/dist/index.d.ts.map +1 -0
- package/miaco/dist/index.js +83 -0
- package/miaco/dist/index.js.map +1 -0
- package/miaco/dist/storage.d.ts +60 -0
- package/miaco/dist/storage.d.ts.map +1 -0
- package/miaco/dist/storage.js +100 -0
- package/miaco/dist/storage.js.map +1 -0
- package/miaco/package-lock.json +4103 -0
- package/miaco/package.json +40 -0
- package/miaco/tsconfig.json +18 -0
- package/miaco/version-patch-commit-and-publish.sh +1 -0
- package/miatel/MISSION_251231.md +3 -0
- package/miatel/README.md +107 -0
- package/miatel/dist/commands/analyze.d.ts +6 -0
- package/miatel/dist/commands/analyze.d.ts.map +1 -0
- package/miatel/dist/commands/analyze.js +100 -0
- package/miatel/dist/commands/analyze.js.map +1 -0
- package/miatel/dist/commands/arc.d.ts +6 -0
- package/miatel/dist/commands/arc.d.ts.map +1 -0
- package/miatel/dist/commands/arc.js +71 -0
- package/miatel/dist/commands/arc.js.map +1 -0
- package/miatel/dist/commands/beat.d.ts +6 -0
- package/miatel/dist/commands/beat.d.ts.map +1 -0
- package/miatel/dist/commands/beat.js +165 -0
- package/miatel/dist/commands/beat.js.map +1 -0
- package/miatel/dist/commands/theme.d.ts +6 -0
- package/miatel/dist/commands/theme.d.ts.map +1 -0
- package/miatel/dist/commands/theme.js +54 -0
- package/miatel/dist/commands/theme.js.map +1 -0
- package/miatel/dist/index.d.ts +18 -0
- package/miatel/dist/index.d.ts.map +1 -0
- package/miatel/dist/index.js +80 -0
- package/miatel/dist/index.js.map +1 -0
- package/miatel/dist/storage.d.ts +55 -0
- package/miatel/dist/storage.d.ts.map +1 -0
- package/miatel/dist/storage.js +100 -0
- package/miatel/dist/storage.js.map +1 -0
- package/miatel/package-lock.json +4103 -0
- package/miatel/package.json +35 -0
- package/miatel/src/commands/analyze.ts +109 -0
- package/miatel/src/commands/arc.ts +78 -0
- package/miatel/src/commands/beat.ts +176 -0
- package/miatel/src/commands/theme.ts +60 -0
- package/miatel/src/index.ts +94 -0
- package/miatel/src/storage.ts +156 -0
- package/miatel/tsconfig.json +18 -0
- package/miawa/MISSION_251231.md +144 -0
- package/miawa/README.md +133 -0
- package/miawa/dist/commands/beat.d.ts +6 -0
- package/miawa/dist/commands/beat.d.ts.map +1 -0
- package/miawa/dist/commands/beat.js +69 -0
- package/miawa/dist/commands/beat.js.map +1 -0
- package/miawa/dist/commands/ceremony.d.ts +6 -0
- package/miawa/dist/commands/ceremony.d.ts.map +1 -0
- package/miawa/dist/commands/ceremony.js +239 -0
- package/miawa/dist/commands/ceremony.js.map +1 -0
- package/miawa/dist/commands/circle.d.ts +6 -0
- package/miawa/dist/commands/circle.d.ts.map +1 -0
- package/miawa/dist/commands/circle.js +75 -0
- package/miawa/dist/commands/circle.js.map +1 -0
- package/miawa/dist/commands/eva.d.ts +6 -0
- package/miawa/dist/commands/eva.d.ts.map +1 -0
- package/miawa/dist/commands/eva.js +73 -0
- package/miawa/dist/commands/eva.js.map +1 -0
- package/miawa/dist/commands/wound.d.ts +6 -0
- package/miawa/dist/commands/wound.d.ts.map +1 -0
- package/miawa/dist/commands/wound.js +74 -0
- package/miawa/dist/commands/wound.js.map +1 -0
- package/miawa/dist/index.d.ts +19 -0
- package/miawa/dist/index.d.ts.map +1 -0
- package/miawa/dist/index.js +91 -0
- package/miawa/dist/index.js.map +1 -0
- package/miawa/dist/storage.d.ts +73 -0
- package/miawa/dist/storage.d.ts.map +1 -0
- package/miawa/dist/storage.js +100 -0
- package/miawa/dist/storage.js.map +1 -0
- package/miawa/package-lock.json +4103 -0
- package/miawa/package.json +36 -0
- package/miawa/src/commands/beat.ts +74 -0
- package/miawa/src/commands/ceremony.ts +256 -0
- package/miawa/src/commands/circle.ts +83 -0
- package/miawa/src/commands/eva.ts +84 -0
- package/miawa/src/commands/wound.ts +79 -0
- package/miawa/src/index.ts +108 -0
- package/miawa/src/storage.ts +179 -0
- package/miawa/tsconfig.json +18 -0
- package/package.json +7 -5
- package/references/acp/CLAUDE.md +7 -0
- package/references/acp/agent-plan.md +84 -0
- package/references/acp/clients.md +31 -0
- package/references/acp/extensibility.md +137 -0
- package/references/acp/initialization.md +225 -0
- package/references/acp/prompt-turn.md +321 -0
- package/references/acp/proxy-chains.md +562 -0
- package/references/acp/schema.md +3171 -0
- package/references/acp/session-list.md +334 -0
- package/references/acp/session-modes.md +170 -0
- package/references/acp/slash-commands.md +99 -0
- package/references/acp/terminals.md +281 -0
- package/references/acp/tool-calls.md +311 -0
- package/references/acp/typescript.md +29 -0
- package/references/claude/agent-teams.md +399 -0
- package/references/claude/chrome.md +231 -0
- package/references/claude/headless.md +158 -0
- package/references/claude/hooks-guide.md +708 -0
- package/references/claude/output-styles.md +112 -0
- package/references/claude/plugins.md +432 -0
- package/references/claude/skills.md +693 -0
- package/references/claude/sub-agents.md +816 -0
- package/references/copilot/acp/agents.md +32 -0
- package/references/copilot/acp/architecture.md +37 -0
- package/references/copilot/acp/clients.md +31 -0
- package/references/copilot/acp/introduction.md +42 -0
- package/references/copilot/acp/registry.md +339 -0
- package/references/copilot/acp-server.md +117 -0
- package/references/copilot/create-copilot-instructions.md +840 -0
- package/references/langchain/llms.txt +833 -0
- package/references/langchain/python/agents.md +677 -0
- package/references/langchain/python/context-engineering.md +1195 -0
- package/references/langchain/python/human-in-the-loop.md +326 -0
- package/references/langchain/python/long-term-memory.md +168 -0
- package/references/langchain/python/mcp.md +949 -0
- package/references/langchain/python/multi-agents/custom-workflow.md +187 -0
- package/references/langchain/python/multi-agents/handoffs.md +436 -0
- package/references/langchain/python/multi-agents/overview.md +295 -0
- package/references/langchain/python/multi-agents/router.md +150 -0
- package/references/langchain/python/multi-agents/skills.md +92 -0
- package/references/langchain/python/multi-agents/subagents.md +486 -0
- package/references/langchain/python/retrieval.md +320 -0
- package/references/langchain/python/runtime.md +141 -0
- package/references/langchain/python/short-term-memory.md +658 -0
- package/references/langchain/python/structured-output.md +712 -0
- package/references/langfuse/llms.txt +148 -0
- package/references/langgraph/javascript/llms.txt +275 -0
- package/references/skills/home.md +259 -0
- package/references/skills/integrate-skills.md +103 -0
- package/references/skills/specification.md +254 -0
- package/references/skills/what-are-skills.md +74 -0
- package/rispecs/README.md +164 -0
- package/rispecs/_sync_/miadi-code/SPEC.md +313 -0
- package/rispecs/_sync_/miadi-code/STATUS.md +177 -0
- package/rispecs/_sync_/miadi-code/dashboard/SPEC.md +465 -0
- package/rispecs/_sync_/miadi-code/dashboard/STATUS.md +212 -0
- package/rispecs/_sync_/miadi-code/multiline-input/SPEC.md +232 -0
- package/rispecs/_sync_/miadi-code/multiline-input/STATUS.md +108 -0
- package/rispecs/_sync_/miadi-code/pde/SPEC.md +253 -0
- package/rispecs/_sync_/miadi-code/pde/STATUS.md +56 -0
- package/rispecs/_sync_/miadi-code/stc/SPEC.md +397 -0
- package/rispecs/_sync_/miadi-code/stc/STATUS.md +70 -0
- package/rispecs/ava-langstack/inquiry-routing-upgrade.spec.md +119 -0
- package/rispecs/borrowed_from_opencode/001-client-server-architecture.rispec.md +98 -0
- package/rispecs/borrowed_from_opencode/002-event-bus-system.rispec.md +125 -0
- package/rispecs/borrowed_from_opencode/003-instance-state-pattern.rispec.md +136 -0
- package/rispecs/borrowed_from_opencode/004-namespace-module-pattern.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/005-zod-schema-validation.rispec.md +139 -0
- package/rispecs/borrowed_from_opencode/006-named-error-system.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/007-structured-logging.rispec.md +138 -0
- package/rispecs/borrowed_from_opencode/008-lazy-initialization.rispec.md +127 -0
- package/rispecs/borrowed_from_opencode/009-multi-agent-system.rispec.md +97 -0
- package/rispecs/borrowed_from_opencode/010-agent-definition-config.rispec.md +135 -0
- package/rispecs/borrowed_from_opencode/011-agent-permission-rulesets.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/012-agent-prompt-templates.rispec.md +141 -0
- package/rispecs/borrowed_from_opencode/013-agent-generation.rispec.md +142 -0
- package/rispecs/borrowed_from_opencode/014-plan-build-mode-toggle.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/015-subagent-task-delegation.rispec.md +146 -0
- package/rispecs/borrowed_from_opencode/016-agent-model-selection.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/017-compaction-agent.rispec.md +150 -0
- package/rispecs/borrowed_from_opencode/018-session-persistence.rispec.md +125 -0
- package/rispecs/borrowed_from_opencode/019-session-compaction.rispec.md +132 -0
- package/rispecs/borrowed_from_opencode/020-session-forking.rispec.md +134 -0
- package/rispecs/borrowed_from_opencode/021-session-revert-snapshot.rispec.md +135 -0
- package/rispecs/borrowed_from_opencode/022-session-sharing.rispec.md +165 -0
- package/rispecs/borrowed_from_opencode/023-session-summary-diffs.rispec.md +165 -0
- package/rispecs/borrowed_from_opencode/024-child-sessions.rispec.md +164 -0
- package/rispecs/borrowed_from_opencode/025-session-title-generation.rispec.md +162 -0
- package/rispecs/borrowed_from_opencode/026-message-parts-model.rispec.md +201 -0
- package/rispecs/borrowed_from_opencode/027-streaming-message-deltas.rispec.md +212 -0
- package/rispecs/borrowed_from_opencode/028-multi-provider-architecture.rispec.md +184 -0
- package/rispecs/borrowed_from_opencode/029-provider-authentication.rispec.md +225 -0
- package/rispecs/borrowed_from_opencode/030-model-registry.rispec.md +222 -0
- package/rispecs/borrowed_from_opencode/031-cost-tracking.rispec.md +243 -0
- package/rispecs/borrowed_from_opencode/032-provider-transform-pipeline.rispec.md +282 -0
- package/rispecs/borrowed_from_opencode/033-provider-sdk-abstraction.rispec.md +338 -0
- package/rispecs/borrowed_from_opencode/034-tool-registry.rispec.md +110 -0
- package/rispecs/borrowed_from_opencode/035-tool-context-injection.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/036-tool-output-truncation.rispec.md +138 -0
- package/rispecs/borrowed_from_opencode/037-batch-tool.rispec.md +129 -0
- package/rispecs/borrowed_from_opencode/038-multi-edit-tool.rispec.md +167 -0
- package/rispecs/borrowed_from_opencode/039-apply-patch-tool.rispec.md +161 -0
- package/rispecs/borrowed_from_opencode/040-code-search-tool.rispec.md +143 -0
- package/rispecs/borrowed_from_opencode/041-web-fetch-tool.rispec.md +131 -0
- package/rispecs/borrowed_from_opencode/042-web-search-tool.rispec.md +159 -0
- package/rispecs/borrowed_from_opencode/043-todo-tool.rispec.md +156 -0
- package/rispecs/borrowed_from_opencode/044-plan-mode-tool.rispec.md +139 -0
- package/rispecs/borrowed_from_opencode/045-task-tool.rispec.md +146 -0
- package/rispecs/borrowed_from_opencode/046-question-tool.rispec.md +170 -0
- package/rispecs/borrowed_from_opencode/047-external-directory-tool.rispec.md +166 -0
- package/rispecs/borrowed_from_opencode/048-file-read-write-tools.rispec.md +205 -0
- package/rispecs/borrowed_from_opencode/049-lsp-server-management.rispec.md +104 -0
- package/rispecs/borrowed_from_opencode/050-lsp-hover-completion.rispec.md +102 -0
- package/rispecs/borrowed_from_opencode/051-lsp-diagnostics.rispec.md +86 -0
- package/rispecs/borrowed_from_opencode/052-lsp-root-detection.rispec.md +109 -0
- package/rispecs/borrowed_from_opencode/053-remote-mcp-servers.rispec.md +119 -0
- package/rispecs/borrowed_from_opencode/054-mcp-oauth-flow.rispec.md +107 -0
- package/rispecs/borrowed_from_opencode/055-mcp-tool-conversion.rispec.md +118 -0
- package/rispecs/borrowed_from_opencode/056-mcp-connection-monitoring.rispec.md +106 -0
- package/rispecs/borrowed_from_opencode/057-local-mcp-servers.rispec.md +116 -0
- package/rispecs/borrowed_from_opencode/058-rich-tui.rispec.md +108 -0
- package/rispecs/borrowed_from_opencode/059-streaming-display.rispec.md +116 -0
- package/rispecs/borrowed_from_opencode/060-permission-prompts.rispec.md +130 -0
- package/rispecs/borrowed_from_opencode/061-session-navigation.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/062-syntax-highlighting.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/063-keybinding-system.rispec.md +181 -0
- package/rispecs/borrowed_from_opencode/064-multi-level-config.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/065-jsonc-config.rispec.md +190 -0
- package/rispecs/borrowed_from_opencode/066-config-env-variables.rispec.md +153 -0
- package/rispecs/borrowed_from_opencode/067-config-deep-merging.rispec.md +178 -0
- package/rispecs/borrowed_from_opencode/068-remote-org-config.rispec.md +183 -0
- package/rispecs/borrowed_from_opencode/069-config-markdown-frontmatter.rispec.md +206 -0
- package/rispecs/borrowed_from_opencode/070-managed-config-directory.rispec.md +232 -0
- package/rispecs/borrowed_from_opencode/071-plugin-architecture.rispec.md +104 -0
- package/rispecs/borrowed_from_opencode/072-plugin-hooks.rispec.md +123 -0
- package/rispecs/borrowed_from_opencode/073-plugin-auto-install.rispec.md +115 -0
- package/rispecs/borrowed_from_opencode/074-permission-system.rispec.md +133 -0
- package/rispecs/borrowed_from_opencode/075-git-worktree-management.rispec.md +126 -0
- package/rispecs/borrowed_from_opencode/076-snapshot-system.rispec.md +124 -0
- package/rispecs/borrowed_from_opencode/077-snapshot-diff.rispec.md +117 -0
- package/rispecs/borrowed_from_opencode/078-snapshot-restore.rispec.md +128 -0
- package/rispecs/borrowed_from_opencode/079-worktree-branch-naming.rispec.md +122 -0
- package/rispecs/borrowed_from_opencode/080-sqlite-storage.rispec.md +134 -0
- package/rispecs/borrowed_from_opencode/081-database-migrations.rispec.md +148 -0
- package/rispecs/borrowed_from_opencode/082-database-transactions.rispec.md +138 -0
- package/rispecs/borrowed_from_opencode/083-deferred-effects.rispec.md +148 -0
- package/rispecs/borrowed_from_opencode/084-permission-rules.rispec.md +123 -0
- package/rispecs/borrowed_from_opencode/085-permission-glob-patterns.rispec.md +113 -0
- package/rispecs/borrowed_from_opencode/086-permission-merging.rispec.md +134 -0
- package/rispecs/borrowed_from_opencode/087-permission-modes.rispec.md +145 -0
- package/rispecs/borrowed_from_opencode/088-http-api-server.rispec.md +165 -0
- package/rispecs/borrowed_from_opencode/089-openapi-spec-generation.rispec.md +164 -0
- package/rispecs/borrowed_from_opencode/090-websocket-support.rispec.md +136 -0
- package/rispecs/borrowed_from_opencode/091-sse-streaming.rispec.md +168 -0
- package/rispecs/borrowed_from_opencode/092-mdns-discovery.rispec.md +145 -0
- package/rispecs/borrowed_from_opencode/093-javascript-sdk.rispec.md +200 -0
- package/rispecs/borrowed_from_opencode/094-skill-system.rispec.md +187 -0
- package/rispecs/borrowed_from_opencode/095-skill-discovery.rispec.md +182 -0
- package/rispecs/borrowed_from_opencode/096-desktop-remote-driving.rispec.md +175 -0
- package/rispecs/borrowed_from_opencode/INDEX.md +255 -0
- package/rispecs/core.rispecs.md +261 -0
- package/rispecs/engines.rispecs.md +241 -0
- package/rispecs/formatting.rispecs.md +252 -0
- package/rispecs/living-specifications.rispecs.md +361 -0
- package/rispecs/mcp.rispecs.md +197 -0
- package/rispecs/pde.rispecs.md +399 -0
- package/rispecs/pi-mono-envisionning/ENVISIONING.md +366 -0
- package/rispecs/pi-mono-envisionning/storytelling-horizon.rispecs.md +76 -0
- package/rispecs/pi-mono-envisionning/widget.rispecs.md +2 -0
- package/rispecs/relation-to-mcp-structural-thinking.kin.md +72 -0
- package/rispecs/research-for-better-framework/CLAUDE.md +7 -0
- package/rispecs/research-for-better-framework/survey-pi-openclaw-opencode-openhands.md +210 -0
- package/rispecs/session.rispecs.md +277 -0
- package/rispecs/stc.rispecs.md +138 -0
- package/rispecs/unifier.rispecs.md +317 -0
- package/scripts/LAUNCH--mcp-mia-code--testing--2603141315--ac705a66-2c15-4a1c-a26d-9491018c5ba8.sh +2 -0
- package/scripts/RESUME--mia-code--mcps--260313--ac705a66-2c15-4a1c-a26d-9491018c5ba8.sh +1 -0
- package/scripts/install-widget-in-home-pi-agent-extensions.sh +4 -0
- package/scripts/sample-decompose--2604011535-prompt.sh +1 -0
- package/skills/deep-search/AGENTS.md +17 -0
- package/skills/deep-search/SKILL.md +281 -0
- package/skills/deep-search/agent-templates.md +224 -0
- package/skills/deep-search/orchestration-patterns.md +95 -0
- package/skills/miaco-pde-inquiry-routing-deep-search/AGENTS.md +13 -0
- package/skills/miaco-pde-inquiry-routing-deep-search/SKILL.md +136 -0
- package/skills/miaco-pde-inquiry-routing-internal-external-relationship/AGENTS.md +4 -0
- package/skills/miaco-pde-inquiry-routing-internal-external-relationship/SKILL.md +157 -0
- package/skills/miaco-pde-inquiry-routing-local-qmd/AGENTS.md +42 -0
- package/skills/miaco-pde-inquiry-routing-local-qmd/SKILL.md +135 -0
- package/skills/qmd/AGENTS.md +3 -0
- package/skills/qmd/SKILL.md +144 -0
- package/skills/qmd/references/mcp-setup.md +102 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/SKILL.md +234 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/agent-templates.md +436 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/orchestration-patterns.md +197 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/ceremonial-technology.md +102 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/creative-orientation.md +99 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/prompt-decomposition.md +73 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/rise-framework.md +74 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/structural-tension.md +82 -0
- package/src/cli.ts +35 -11
- package/src/geminiHeadless.ts +7 -2
- package/src/index.ts +2 -1
- package/src/mcp/miaco-server.ts +13 -1
- package/src/mcp/miatel-server.ts +13 -1
- package/src/mcp/miawa-server.ts +13 -1
- package/src/mcp/utils.ts +41 -8
- package/src/sessionStore.ts +44 -4
- package/src/types.ts +2 -1
- package/widget/mia-ceremony/README.md +36 -0
- package/widget/mia-ceremony/index.ts +143 -0
- package/widget/mia-interceptor/README.md +39 -0
- package/widget/mia-interceptor/index.ts +221 -0
- package/widget/mia-tools/README.md +37 -0
- package/widget/mia-tools/index.ts +569 -0
- package/widget/miette-echo/README.md +44 -0
- package/widget/miette-echo/index.ts +164 -0
- package/.claude/settings.local.json +0 -9
- package/.hch/issue_.env +0 -4
- package/.hch/issue_add__2601211715.json +0 -77
- package/.hch/issue_add__2601211715.md +0 -4
- package/.hch/issue_add__2602242020.json +0 -78
- package/.hch/issue_add__2602242020.md +0 -7
- package/.hch/issues.json +0 -2312
- package/.hch/issues.md +0 -30
- package/WS__mia-code__260214__IAIP_PDE.code-workspace +0 -29
- package/WS__mia-code__src332__260122.code-workspace +0 -23
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/checkpoints/index.md +0 -6
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/events.jsonl +0 -213
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/plan.md +0 -243
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/workspace.yaml +0 -5
|
@@ -0,0 +1,949 @@
|
|
|
1
|
+
> ## Documentation Index
|
|
2
|
+
> Fetch the complete documentation index at: https://docs.langchain.com/llms.txt
|
|
3
|
+
> Use this file to discover all available pages before exploring further.
|
|
4
|
+
|
|
5
|
+
# Model Context Protocol (MCP)
|
|
6
|
+
|
|
7
|
+
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how applications provide tools and context to LLMs. LangChain agents can use tools defined on MCP servers using the [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters) library.
|
|
8
|
+
|
|
9
|
+
## Quickstart
|
|
10
|
+
|
|
11
|
+
Install the `langchain-mcp-adapters` library:
|
|
12
|
+
|
|
13
|
+
<CodeGroup>
|
|
14
|
+
```bash pip theme={null}
|
|
15
|
+
pip install langchain-mcp-adapters
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```bash uv theme={null}
|
|
19
|
+
uv add langchain-mcp-adapters
|
|
20
|
+
```
|
|
21
|
+
</CodeGroup>
|
|
22
|
+
|
|
23
|
+
`langchain-mcp-adapters` enables agents to use tools defined across one or more MCP servers.
|
|
24
|
+
|
|
25
|
+
<Note>
|
|
26
|
+
`MultiServerMCPClient` is **stateless by default**. Each tool invocation creates a fresh MCP `ClientSession`, executes the tool, and then cleans up. See the [stateful sessions](#stateful-sessions) section for more details.
|
|
27
|
+
</Note>
|
|
28
|
+
|
|
29
|
+
```python Accessing multiple MCP servers icon="server" theme={null}
|
|
30
|
+
import asyncio
|
|
31
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient # [!code highlight]
|
|
32
|
+
from langchain.agents import create_agent
|
|
33
|
+
|
|
34
|
+
async def main():
|
|
35
|
+
client = MultiServerMCPClient( # [!code highlight]
|
|
36
|
+
{
|
|
37
|
+
"math": {
|
|
38
|
+
"transport": "stdio", # Local subprocess communication
|
|
39
|
+
"command": "python",
|
|
40
|
+
# Absolute path to your math_server.py file
|
|
41
|
+
"args": ["/path/to/math_server.py"],
|
|
42
|
+
},
|
|
43
|
+
"weather": {
|
|
44
|
+
"transport": "http", # HTTP-based remote server
|
|
45
|
+
# Ensure you start your weather server on port 8000
|
|
46
|
+
"url": "http://localhost:8000/mcp",
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
tools = await client.get_tools() # [!code highlight]
|
|
52
|
+
agent = create_agent(
|
|
53
|
+
"claude-sonnet-4-5-20250929",
|
|
54
|
+
tools # [!code highlight]
|
|
55
|
+
)
|
|
56
|
+
math_response = await agent.ainvoke(
|
|
57
|
+
{"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
|
|
58
|
+
)
|
|
59
|
+
weather_response = await agent.ainvoke(
|
|
60
|
+
{"messages": [{"role": "user", "content": "what is the weather in nyc?"}]}
|
|
61
|
+
)
|
|
62
|
+
print(math_response)
|
|
63
|
+
print(weather_response)
|
|
64
|
+
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
asyncio.run(main())
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Custom servers
|
|
70
|
+
|
|
71
|
+
To create a custom MCP server, use the [FastMCP](https://gofastmcp.com/getting-started/welcome) library:
|
|
72
|
+
|
|
73
|
+
<CodeGroup>
|
|
74
|
+
```bash pip theme={null}
|
|
75
|
+
pip install fastmcp
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```bash uv theme={null}
|
|
79
|
+
uv add fastmcp
|
|
80
|
+
```
|
|
81
|
+
</CodeGroup>
|
|
82
|
+
|
|
83
|
+
To test your agent with MCP tool servers, use the following examples:
|
|
84
|
+
|
|
85
|
+
<CodeGroup>
|
|
86
|
+
```python title="Math server (stdio transport)" icon="floppy-disk" theme={null}
|
|
87
|
+
from fastmcp import FastMCP
|
|
88
|
+
|
|
89
|
+
mcp = FastMCP("Math")
|
|
90
|
+
|
|
91
|
+
@mcp.tool()
|
|
92
|
+
def add(a: int, b: int) -> int:
|
|
93
|
+
"""Add two numbers"""
|
|
94
|
+
return a + b
|
|
95
|
+
|
|
96
|
+
@mcp.tool()
|
|
97
|
+
def multiply(a: int, b: int) -> int:
|
|
98
|
+
"""Multiply two numbers"""
|
|
99
|
+
return a * b
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
mcp.run(transport="stdio")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```python title="Weather server (streamable HTTP transport)" icon="wifi" theme={null}
|
|
106
|
+
from fastmcp import FastMCP
|
|
107
|
+
|
|
108
|
+
mcp = FastMCP("Weather")
|
|
109
|
+
|
|
110
|
+
@mcp.tool()
|
|
111
|
+
async def get_weather(location: str) -> str:
|
|
112
|
+
"""Get weather for location."""
|
|
113
|
+
return "It's always sunny in New York"
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
mcp.run(transport="streamable-http")
|
|
117
|
+
```
|
|
118
|
+
</CodeGroup>
|
|
119
|
+
|
|
120
|
+
## Transports
|
|
121
|
+
|
|
122
|
+
MCP supports different transport mechanisms for client-server communication.
|
|
123
|
+
|
|
124
|
+
### HTTP
|
|
125
|
+
|
|
126
|
+
The `http` transport (also referred to as `streamable-http`) uses HTTP requests for client-server communication. See the [MCP HTTP transport specification](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) for more details.
|
|
127
|
+
|
|
128
|
+
```python theme={null}
|
|
129
|
+
client = MultiServerMCPClient(
|
|
130
|
+
{
|
|
131
|
+
"weather": {
|
|
132
|
+
"transport": "http",
|
|
133
|
+
"url": "http://localhost:8000/mcp",
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Passing headers
|
|
140
|
+
|
|
141
|
+
When connecting to MCP servers over HTTP, you can include custom headers (e.g., for authentication or tracing) using the `headers` field in the connection configuration. This is supported for `sse` (deprecated by MCP spec) and `streamable_http` transports.
|
|
142
|
+
|
|
143
|
+
```python Passing headers with MultiServerMCPClient theme={null}
|
|
144
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
145
|
+
from langchain.agents import create_agent
|
|
146
|
+
|
|
147
|
+
client = MultiServerMCPClient(
|
|
148
|
+
{
|
|
149
|
+
"weather": {
|
|
150
|
+
"transport": "http",
|
|
151
|
+
"url": "http://localhost:8000/mcp",
|
|
152
|
+
"headers": { # [!code highlight]
|
|
153
|
+
"Authorization": "Bearer YOUR_TOKEN", # [!code highlight]
|
|
154
|
+
"X-Custom-Header": "custom-value" # [!code highlight]
|
|
155
|
+
}, # [!code highlight]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
tools = await client.get_tools()
|
|
160
|
+
agent = create_agent("openai:gpt-4.1", tools)
|
|
161
|
+
response = await agent.ainvoke({"messages": "what is the weather in nyc?"})
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### Authentication
|
|
165
|
+
|
|
166
|
+
The `langchain-mcp-adapters` library uses the official [MCP SDK](https://github.com/modelcontextprotocol/python-sdk) under the hood, which allows you to provide a custom authentication mechanism by implementing the `httpx.Auth` interface.
|
|
167
|
+
|
|
168
|
+
```python theme={null}
|
|
169
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
170
|
+
|
|
171
|
+
client = MultiServerMCPClient(
|
|
172
|
+
{
|
|
173
|
+
"weather": {
|
|
174
|
+
"transport": "http",
|
|
175
|
+
"url": "http://localhost:8000/mcp",
|
|
176
|
+
"auth": auth, # [!code highlight]
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
* [Example custom auth implementation](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-auth-client/mcp_simple_auth_client/main.py)
|
|
183
|
+
* [Built-in OAuth flow](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/client/auth/oauth2.py#L216)
|
|
184
|
+
|
|
185
|
+
### stdio
|
|
186
|
+
|
|
187
|
+
Client launches server as a subprocess and communicates via standard input/output. Best for local tools and simple setups.
|
|
188
|
+
|
|
189
|
+
<Note>
|
|
190
|
+
Unlike HTTP transports, `stdio` connections are inherently **stateful**—the subprocess persists for the lifetime of the client connection. However, when using `MultiServerMCPClient` without explicit session management, each tool call still creates a new session. See [stateful sessions](#stateful-sessions) for managing persistent connections.
|
|
191
|
+
</Note>
|
|
192
|
+
|
|
193
|
+
```python theme={null}
|
|
194
|
+
client = MultiServerMCPClient(
|
|
195
|
+
{
|
|
196
|
+
"math": {
|
|
197
|
+
"transport": "stdio",
|
|
198
|
+
"command": "python",
|
|
199
|
+
"args": ["/path/to/math_server.py"],
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Stateful sessions
|
|
206
|
+
|
|
207
|
+
By default, `MultiServerMCPClient` is **stateless**—each tool invocation creates a fresh MCP session, executes the tool, and then cleans up.
|
|
208
|
+
|
|
209
|
+
If you need to control the [lifecycle](https://modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle) of an MCP session (for example, when working with a stateful server that maintains context across tool calls), you can create a persistent `ClientSession` using `client.session()`.
|
|
210
|
+
|
|
211
|
+
```python Using MCP ClientSession for stateful tool usage theme={null}
|
|
212
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
213
|
+
from langchain_mcp_adapters.tools import load_mcp_tools
|
|
214
|
+
from langchain.agents import create_agent
|
|
215
|
+
|
|
216
|
+
client = MultiServerMCPClient({...})
|
|
217
|
+
|
|
218
|
+
# Create a session explicitly
|
|
219
|
+
async with client.session("server_name") as session: # [!code highlight]
|
|
220
|
+
# Pass the session to load tools, resources, or prompts
|
|
221
|
+
tools = await load_mcp_tools(session) # [!code highlight]
|
|
222
|
+
agent = create_agent(
|
|
223
|
+
"anthropic:claude-3-7-sonnet-latest",
|
|
224
|
+
tools
|
|
225
|
+
)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Core features
|
|
229
|
+
|
|
230
|
+
### Tools
|
|
231
|
+
|
|
232
|
+
[Tools](https://modelcontextprotocol.io/docs/concepts/tools) allow MCP servers to expose executable functions that LLMs can invoke to perform actions—such as querying databases, calling APIs, or interacting with external systems. LangChain converts MCP tools into LangChain [tools](/oss/python/langchain/tools), making them directly usable in any LangChain agent or workflow.
|
|
233
|
+
|
|
234
|
+
#### Loading tools
|
|
235
|
+
|
|
236
|
+
Use `client.get_tools()` to retrieve tools from MCP servers and pass them to your agent:
|
|
237
|
+
|
|
238
|
+
```python theme={null}
|
|
239
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
240
|
+
from langchain.agents import create_agent
|
|
241
|
+
|
|
242
|
+
client = MultiServerMCPClient({...})
|
|
243
|
+
tools = await client.get_tools() # [!code highlight]
|
|
244
|
+
agent = create_agent("claude-sonnet-4-5-20250929", tools)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### Structured content
|
|
248
|
+
|
|
249
|
+
MCP tools can return [structured content](https://modelcontextprotocol.io/specification/2025-03-26/server/tools#structured-content) alongside the human-readable text response. This is useful when a tool needs to return machine-parseable data (like JSON) in addition to text that gets shown to the model.
|
|
250
|
+
|
|
251
|
+
When an MCP tool returns `structuredContent`, the adapter wraps it in an [`MCPToolArtifact`](https://reference.langchain.com/python/langchain_mcp_adapters/#langchain_mcp_adapters.tools.MCPToolArtifact) and returns it as the tool's artifact. You can access this using the `artifact` field on the `ToolMessage`. You can also use [interceptors](#tool-interceptors) to process or transform structured content automatically.
|
|
252
|
+
|
|
253
|
+
**Extracting structured content from artifact**
|
|
254
|
+
|
|
255
|
+
After invoking your agent, you can access the structured content from tool messages in the response:
|
|
256
|
+
|
|
257
|
+
```python theme={null}
|
|
258
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
259
|
+
from langchain.agents import create_agent
|
|
260
|
+
from langchain.messages import ToolMessage
|
|
261
|
+
|
|
262
|
+
client = MultiServerMCPClient({...})
|
|
263
|
+
tools = await client.get_tools()
|
|
264
|
+
agent = create_agent("claude-sonnet-4-5-20250929", tools)
|
|
265
|
+
|
|
266
|
+
result = await agent.ainvoke(
|
|
267
|
+
{"messages": [{"role": "user", "content": "Get data from the server"}]}
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
# Extract structured content from tool messages
|
|
271
|
+
for message in result["messages"]:
|
|
272
|
+
if isinstance(message, ToolMessage) and message.artifact:
|
|
273
|
+
structured_content = message.artifact["structured_content"]
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Appending structured content via interceptor**
|
|
277
|
+
|
|
278
|
+
If you want structured content to be visible in the conversation history (visible to the model), you can use an [interceptor](#tool-interceptors) to automatically append structured content to the tool result:
|
|
279
|
+
|
|
280
|
+
```python theme={null}
|
|
281
|
+
import json
|
|
282
|
+
|
|
283
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
284
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
285
|
+
from mcp.types import TextContent
|
|
286
|
+
|
|
287
|
+
async def append_structured_content(request: MCPToolCallRequest, handler):
|
|
288
|
+
"""Append structured content from artifact to tool message."""
|
|
289
|
+
result = await handler(request)
|
|
290
|
+
if result.structuredContent:
|
|
291
|
+
result.content += [
|
|
292
|
+
TextContent(type="text", text=json.dumps(result.structuredContent)),
|
|
293
|
+
]
|
|
294
|
+
return result
|
|
295
|
+
|
|
296
|
+
client = MultiServerMCPClient({...}, tool_interceptors=[append_structured_content])
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### Multimodal tool content
|
|
300
|
+
|
|
301
|
+
MCP tools can return [multimodal content](https://modelcontextprotocol.io/specification/2025-03-26/server/tools#tool-result) (images, text, etc.) in their responses. When an MCP server returns content with multiple parts (e.g., text and images), the adapter converts them to LangChain's [standard content blocks](/oss/python/langchain/messages#standard-content-blocks). You can access the standardized representation via the `content_blocks` property on the `ToolMessage`:
|
|
302
|
+
|
|
303
|
+
```python theme={null}
|
|
304
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
305
|
+
from langchain.agents import create_agent
|
|
306
|
+
|
|
307
|
+
client = MultiServerMCPClient({...})
|
|
308
|
+
tools = await client.get_tools()
|
|
309
|
+
agent = create_agent("claude-sonnet-4-5-20250929", tools)
|
|
310
|
+
|
|
311
|
+
result = await agent.ainvoke(
|
|
312
|
+
{"messages": [{"role": "user", "content": "Take a screenshot of the current page"}]}
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
# Access multimodal content from tool messages
|
|
316
|
+
for message in result["messages"]:
|
|
317
|
+
if message.type == "tool":
|
|
318
|
+
# Raw content in provider-native format
|
|
319
|
+
print(f"Raw content: {message.content}")
|
|
320
|
+
|
|
321
|
+
# Standardized content blocks # [!code highlight]
|
|
322
|
+
for block in message.content_blocks: # [!code highlight]
|
|
323
|
+
if block["type"] == "text": # [!code highlight]
|
|
324
|
+
print(f"Text: {block['text']}") # [!code highlight]
|
|
325
|
+
elif block["type"] == "image": # [!code highlight]
|
|
326
|
+
print(f"Image URL: {block.get('url')}") # [!code highlight]
|
|
327
|
+
print(f"Image base64: {block.get('base64', '')[:50]}...") # [!code highlight]
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
This allows you to handle multimodal tool responses in a provider-agnostic way, regardless of how the underlying MCP server formats its content.
|
|
331
|
+
|
|
332
|
+
### Resources
|
|
333
|
+
|
|
334
|
+
[Resources](https://modelcontextprotocol.io/docs/concepts/resources) allow MCP servers to expose data—such as files, database records, or API responses—that can be read by clients. LangChain converts MCP resources into [Blob](https://reference.langchain.com/python/langchain_core/documents/#langchain_core.documents.base.Blob) objects, which provide a unified interface for handling both text and binary content.
|
|
335
|
+
|
|
336
|
+
#### Loading resources
|
|
337
|
+
|
|
338
|
+
Use `client.get_resources()` to load resources from an MCP server:
|
|
339
|
+
|
|
340
|
+
```python theme={null}
|
|
341
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
342
|
+
|
|
343
|
+
client = MultiServerMCPClient({...})
|
|
344
|
+
|
|
345
|
+
# Load all resources from a server
|
|
346
|
+
blobs = await client.get_resources("server_name") # [!code highlight]
|
|
347
|
+
|
|
348
|
+
# Or load specific resources by URI
|
|
349
|
+
blobs = await client.get_resources("server_name", uris=["file:///path/to/file.txt"]) # [!code highlight]
|
|
350
|
+
|
|
351
|
+
for blob in blobs:
|
|
352
|
+
print(f"URI: {blob.metadata['uri']}, MIME type: {blob.mimetype}")
|
|
353
|
+
print(blob.as_string()) # For text content
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
You can also use [`load_mcp_resources`](https://reference.langchain.com/python/langchain_mcp_adapters/#langchain_mcp_adapters.resources.load_mcp_resources) directly with a session for more control:
|
|
357
|
+
|
|
358
|
+
```python theme={null}
|
|
359
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
360
|
+
from langchain_mcp_adapters.resources import load_mcp_resources
|
|
361
|
+
|
|
362
|
+
client = MultiServerMCPClient({...})
|
|
363
|
+
|
|
364
|
+
async with client.session("server_name") as session:
|
|
365
|
+
# Load all resources
|
|
366
|
+
blobs = await load_mcp_resources(session)
|
|
367
|
+
|
|
368
|
+
# Or load specific resources by URI
|
|
369
|
+
blobs = await load_mcp_resources(session, uris=["file:///path/to/file.txt"])
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Prompts
|
|
373
|
+
|
|
374
|
+
[Prompts](https://modelcontextprotocol.io/docs/concepts/prompts) allow MCP servers to expose reusable prompt templates that can be retrieved and used by clients. LangChain converts MCP prompts into [messages](/oss/python/langchain/messages), making them easy to integrate into chat-based workflows.
|
|
375
|
+
|
|
376
|
+
#### Loading prompts
|
|
377
|
+
|
|
378
|
+
Use `client.get_prompt()` to load a prompt from an MCP server:
|
|
379
|
+
|
|
380
|
+
```python theme={null}
|
|
381
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
382
|
+
|
|
383
|
+
client = MultiServerMCPClient({...})
|
|
384
|
+
|
|
385
|
+
# Load a prompt by name
|
|
386
|
+
messages = await client.get_prompt("server_name", "summarize") # [!code highlight]
|
|
387
|
+
|
|
388
|
+
# Load a prompt with arguments
|
|
389
|
+
messages = await client.get_prompt( # [!code highlight]
|
|
390
|
+
"server_name", # [!code highlight]
|
|
391
|
+
"code_review", # [!code highlight]
|
|
392
|
+
arguments={"language": "python", "focus": "security"} # [!code highlight]
|
|
393
|
+
) # [!code highlight]
|
|
394
|
+
|
|
395
|
+
# Use the messages in your workflow
|
|
396
|
+
for message in messages:
|
|
397
|
+
print(f"{message.type}: {message.content}")
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
You can also use [`load_mcp_prompt`](https://reference.langchain.com/python/langchain_mcp_adapters/#langchain_mcp_adapters.prompts.load_mcp_prompt) directly with a session for more control:
|
|
401
|
+
|
|
402
|
+
```python theme={null}
|
|
403
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
404
|
+
from langchain_mcp_adapters.prompts import load_mcp_prompt
|
|
405
|
+
|
|
406
|
+
client = MultiServerMCPClient({...})
|
|
407
|
+
|
|
408
|
+
async with client.session("server_name") as session:
|
|
409
|
+
# Load a prompt by name
|
|
410
|
+
messages = await load_mcp_prompt(session, "summarize")
|
|
411
|
+
|
|
412
|
+
# Load a prompt with arguments
|
|
413
|
+
messages = await load_mcp_prompt(
|
|
414
|
+
session,
|
|
415
|
+
"code_review",
|
|
416
|
+
arguments={"language": "python", "focus": "security"}
|
|
417
|
+
)
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Advanced features
|
|
421
|
+
|
|
422
|
+
### Tool interceptors
|
|
423
|
+
|
|
424
|
+
MCP servers run as separate processes—they can't access LangGraph runtime information like the [store](/oss/python/langgraph/persistence#memory-store), [context](/oss/python/langchain/context-engineering), or agent state. **Interceptors bridge this gap** by giving you access to this runtime context during MCP tool execution.
|
|
425
|
+
|
|
426
|
+
Interceptors also provide middleware-like control over tool calls: you can modify requests, implement retries, add headers dynamically, or short-circuit execution entirely.
|
|
427
|
+
|
|
428
|
+
| Section | Description |
|
|
429
|
+
| --------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
430
|
+
| [Accessing runtime context](#accessing-runtime-context) | Read user IDs, API keys, store data, and agent state |
|
|
431
|
+
| [State updates and commands](#state-updates-and-commands) | Update agent state or control graph flow with `Command` |
|
|
432
|
+
| [Writing interceptors](#writing-interceptors) | Patterns for modifying requests, composing interceptors, and error handling |
|
|
433
|
+
|
|
434
|
+
#### Accessing runtime context
|
|
435
|
+
|
|
436
|
+
When MCP tools are used within a LangChain agent (via `create_agent`), interceptors receive access to the `ToolRuntime` context. This provides access to the tool call ID, state, config, and store—enabling powerful patterns for accessing user data, persisting information, and controlling agent behavior.
|
|
437
|
+
|
|
438
|
+
<Tabs>
|
|
439
|
+
<Tab title="Runtime context">
|
|
440
|
+
Access user-specific configuration like user IDs, API keys, or permissions that are passed at invocation time:
|
|
441
|
+
|
|
442
|
+
```python Inject user context into MCP tool calls theme={null}
|
|
443
|
+
from dataclasses import dataclass
|
|
444
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
445
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
446
|
+
from langchain.agents import create_agent
|
|
447
|
+
|
|
448
|
+
@dataclass
|
|
449
|
+
class Context:
|
|
450
|
+
user_id: str
|
|
451
|
+
api_key: str
|
|
452
|
+
|
|
453
|
+
async def inject_user_context(
|
|
454
|
+
request: MCPToolCallRequest,
|
|
455
|
+
handler,
|
|
456
|
+
):
|
|
457
|
+
"""Inject user credentials into MCP tool calls."""
|
|
458
|
+
runtime = request.runtime
|
|
459
|
+
user_id = runtime.context.user_id # [!code highlight]
|
|
460
|
+
api_key = runtime.context.api_key # [!code highlight]
|
|
461
|
+
|
|
462
|
+
# Add user context to tool arguments
|
|
463
|
+
modified_request = request.override(
|
|
464
|
+
args={**request.args, "user_id": user_id}
|
|
465
|
+
)
|
|
466
|
+
return await handler(modified_request)
|
|
467
|
+
|
|
468
|
+
client = MultiServerMCPClient(
|
|
469
|
+
{...},
|
|
470
|
+
tool_interceptors=[inject_user_context],
|
|
471
|
+
)
|
|
472
|
+
tools = await client.get_tools()
|
|
473
|
+
agent = create_agent("gpt-4.1", tools, context_schema=Context)
|
|
474
|
+
|
|
475
|
+
# Invoke with user context
|
|
476
|
+
result = await agent.ainvoke(
|
|
477
|
+
{"messages": [{"role": "user", "content": "Search my orders"}]},
|
|
478
|
+
context={"user_id": "user_123", "api_key": "sk-..."}
|
|
479
|
+
)
|
|
480
|
+
```
|
|
481
|
+
</Tab>
|
|
482
|
+
|
|
483
|
+
<Tab title="Store">
|
|
484
|
+
Access long-term memory to retrieve user preferences or persist data across conversations:
|
|
485
|
+
|
|
486
|
+
```python Access user preferences from store theme={null}
|
|
487
|
+
from dataclasses import dataclass
|
|
488
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
489
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
490
|
+
from langchain.agents import create_agent
|
|
491
|
+
from langgraph.store.memory import InMemoryStore
|
|
492
|
+
|
|
493
|
+
@dataclass
|
|
494
|
+
class Context:
|
|
495
|
+
user_id: str
|
|
496
|
+
|
|
497
|
+
async def personalize_search(
|
|
498
|
+
request: MCPToolCallRequest,
|
|
499
|
+
handler,
|
|
500
|
+
):
|
|
501
|
+
"""Personalize MCP tool calls using stored preferences."""
|
|
502
|
+
runtime = request.runtime
|
|
503
|
+
user_id = runtime.context.user_id
|
|
504
|
+
store = runtime.store # [!code highlight]
|
|
505
|
+
|
|
506
|
+
# Read user preferences from store
|
|
507
|
+
prefs = store.get(("preferences",), user_id) # [!code highlight]
|
|
508
|
+
|
|
509
|
+
if prefs and request.name == "search":
|
|
510
|
+
# Apply user's preferred language and result limit
|
|
511
|
+
modified_args = {
|
|
512
|
+
**request.args,
|
|
513
|
+
"language": prefs.value.get("language", "en"),
|
|
514
|
+
"limit": prefs.value.get("result_limit", 10),
|
|
515
|
+
}
|
|
516
|
+
request = request.override(args=modified_args)
|
|
517
|
+
|
|
518
|
+
return await handler(request)
|
|
519
|
+
|
|
520
|
+
client = MultiServerMCPClient(
|
|
521
|
+
{...},
|
|
522
|
+
tool_interceptors=[personalize_search],
|
|
523
|
+
)
|
|
524
|
+
tools = await client.get_tools()
|
|
525
|
+
agent = create_agent(
|
|
526
|
+
"gpt-4.1",
|
|
527
|
+
tools,
|
|
528
|
+
context_schema=Context,
|
|
529
|
+
store=InMemoryStore()
|
|
530
|
+
)
|
|
531
|
+
```
|
|
532
|
+
</Tab>
|
|
533
|
+
|
|
534
|
+
<Tab title="State">
|
|
535
|
+
Access conversation state to make decisions based on the current session:
|
|
536
|
+
|
|
537
|
+
```python Filter tools based on authentication state theme={null}
|
|
538
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
539
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
540
|
+
from langchain.messages import ToolMessage
|
|
541
|
+
|
|
542
|
+
async def require_authentication(
|
|
543
|
+
request: MCPToolCallRequest,
|
|
544
|
+
handler,
|
|
545
|
+
):
|
|
546
|
+
"""Block sensitive MCP tools if user is not authenticated."""
|
|
547
|
+
runtime = request.runtime
|
|
548
|
+
state = runtime.state # [!code highlight]
|
|
549
|
+
is_authenticated = state.get("authenticated", False) # [!code highlight]
|
|
550
|
+
|
|
551
|
+
sensitive_tools = ["delete_file", "update_settings", "export_data"]
|
|
552
|
+
|
|
553
|
+
if request.name in sensitive_tools and not is_authenticated:
|
|
554
|
+
# Return error instead of calling tool
|
|
555
|
+
return ToolMessage(
|
|
556
|
+
content="Authentication required. Please log in first.",
|
|
557
|
+
tool_call_id=runtime.tool_call_id,
|
|
558
|
+
)
|
|
559
|
+
|
|
560
|
+
return await handler(request)
|
|
561
|
+
|
|
562
|
+
client = MultiServerMCPClient(
|
|
563
|
+
{...},
|
|
564
|
+
tool_interceptors=[require_authentication],
|
|
565
|
+
)
|
|
566
|
+
```
|
|
567
|
+
</Tab>
|
|
568
|
+
|
|
569
|
+
<Tab title="Tool call ID">
|
|
570
|
+
Access the tool call ID to return properly formatted responses or track tool executions:
|
|
571
|
+
|
|
572
|
+
```python Return custom responses with tool call ID theme={null}
|
|
573
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
574
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
575
|
+
from langchain.messages import ToolMessage
|
|
576
|
+
|
|
577
|
+
async def rate_limit_interceptor(
|
|
578
|
+
request: MCPToolCallRequest,
|
|
579
|
+
handler,
|
|
580
|
+
):
|
|
581
|
+
"""Rate limit expensive MCP tool calls."""
|
|
582
|
+
runtime = request.runtime
|
|
583
|
+
tool_call_id = runtime.tool_call_id # [!code highlight]
|
|
584
|
+
|
|
585
|
+
# Check rate limit (simplified example)
|
|
586
|
+
if is_rate_limited(request.name):
|
|
587
|
+
return ToolMessage(
|
|
588
|
+
content="Rate limit exceeded. Please try again later.",
|
|
589
|
+
tool_call_id=tool_call_id, # [!code highlight]
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
result = await handler(request)
|
|
593
|
+
|
|
594
|
+
# Log successful tool call
|
|
595
|
+
log_tool_execution(tool_call_id, request.name, success=True)
|
|
596
|
+
|
|
597
|
+
return result
|
|
598
|
+
|
|
599
|
+
client = MultiServerMCPClient(
|
|
600
|
+
{...},
|
|
601
|
+
tool_interceptors=[rate_limit_interceptor],
|
|
602
|
+
)
|
|
603
|
+
```
|
|
604
|
+
</Tab>
|
|
605
|
+
</Tabs>
|
|
606
|
+
|
|
607
|
+
For more context engineering patterns, see [Context engineering](/oss/python/langchain/context-engineering) and [Tools](/oss/python/langchain/tools).
|
|
608
|
+
|
|
609
|
+
#### State updates and commands
|
|
610
|
+
|
|
611
|
+
Interceptors can return `Command` objects to update agent state or control graph execution flow. This is useful for tracking task progress, switching between agents, or ending execution early.
|
|
612
|
+
|
|
613
|
+
```python Mark task complete and switch agents theme={null}
|
|
614
|
+
from langchain.agents import AgentState, create_agent
|
|
615
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
616
|
+
from langchain.messages import ToolMessage
|
|
617
|
+
from langgraph.types import Command
|
|
618
|
+
|
|
619
|
+
async def handle_task_completion(
|
|
620
|
+
request: MCPToolCallRequest,
|
|
621
|
+
handler,
|
|
622
|
+
):
|
|
623
|
+
"""Mark task complete and hand off to summary agent."""
|
|
624
|
+
result = await handler(request)
|
|
625
|
+
|
|
626
|
+
if request.name == "submit_order":
|
|
627
|
+
return Command(
|
|
628
|
+
update={
|
|
629
|
+
"messages": [result] if isinstance(result, ToolMessage) else [],
|
|
630
|
+
"task_status": "completed", # [!code highlight]
|
|
631
|
+
},
|
|
632
|
+
goto="summary_agent", # [!code highlight]
|
|
633
|
+
)
|
|
634
|
+
|
|
635
|
+
return result
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Use `Command` with `goto="__end__"` to end execution early:
|
|
639
|
+
|
|
640
|
+
```python End agent run on completion theme={null}
|
|
641
|
+
async def end_on_success(
|
|
642
|
+
request: MCPToolCallRequest,
|
|
643
|
+
handler,
|
|
644
|
+
):
|
|
645
|
+
"""End agent run when task is marked complete."""
|
|
646
|
+
result = await handler(request)
|
|
647
|
+
|
|
648
|
+
if request.name == "mark_complete":
|
|
649
|
+
return Command(
|
|
650
|
+
update={"messages": [result], "status": "done"},
|
|
651
|
+
goto="__end__", # [!code highlight]
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
return result
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
#### Custom interceptors
|
|
658
|
+
|
|
659
|
+
Interceptors are async functions that wrap tool execution, enabling request/response modification, retry logic, and other cross-cutting concerns. They follow an "onion" pattern where the first interceptor in the list is the outermost layer.
|
|
660
|
+
|
|
661
|
+
**Basic pattern**
|
|
662
|
+
|
|
663
|
+
An interceptor is an async function that receives a request and a handler. You can modify the request before calling the handler, modify the response after, or skip the handler entirely.
|
|
664
|
+
|
|
665
|
+
```python Basic interceptor pattern theme={null}
|
|
666
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
667
|
+
from langchain_mcp_adapters.interceptors import MCPToolCallRequest
|
|
668
|
+
|
|
669
|
+
async def logging_interceptor(
|
|
670
|
+
request: MCPToolCallRequest,
|
|
671
|
+
handler,
|
|
672
|
+
):
|
|
673
|
+
"""Log tool calls before and after execution."""
|
|
674
|
+
print(f"Calling tool: {request.name} with args: {request.args}")
|
|
675
|
+
result = await handler(request)
|
|
676
|
+
print(f"Tool {request.name} returned: {result}")
|
|
677
|
+
return result
|
|
678
|
+
|
|
679
|
+
client = MultiServerMCPClient(
|
|
680
|
+
{"math": {"transport": "stdio", "command": "python", "args": ["/path/to/server.py"]}},
|
|
681
|
+
tool_interceptors=[logging_interceptor], # [!code highlight]
|
|
682
|
+
)
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
**Modifying requests**
|
|
686
|
+
|
|
687
|
+
Use `request.override()` to create a modified request. This follows an immutable pattern, leaving the original request unchanged.
|
|
688
|
+
|
|
689
|
+
```python Modifying tool arguments theme={null}
|
|
690
|
+
async def double_args_interceptor(
|
|
691
|
+
request: MCPToolCallRequest,
|
|
692
|
+
handler,
|
|
693
|
+
):
|
|
694
|
+
"""Double all numeric arguments before execution."""
|
|
695
|
+
modified_args = {k: v * 2 for k, v in request.args.items()}
|
|
696
|
+
modified_request = request.override(args=modified_args) # [!code highlight]
|
|
697
|
+
return await handler(modified_request)
|
|
698
|
+
|
|
699
|
+
# Original call: add(a=2, b=3) becomes add(a=4, b=6)
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**Modifying headers at runtime**
|
|
703
|
+
|
|
704
|
+
Interceptors can modify HTTP headers dynamically based on the request context:
|
|
705
|
+
|
|
706
|
+
```python Dynamic header modification theme={null}
|
|
707
|
+
async def auth_header_interceptor(
|
|
708
|
+
request: MCPToolCallRequest,
|
|
709
|
+
handler,
|
|
710
|
+
):
|
|
711
|
+
"""Add authentication headers based on the tool being called."""
|
|
712
|
+
token = get_token_for_tool(request.name)
|
|
713
|
+
modified_request = request.override(
|
|
714
|
+
headers={"Authorization": f"Bearer {token}"} # [!code highlight]
|
|
715
|
+
)
|
|
716
|
+
return await handler(modified_request)
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Composing interceptors**
|
|
720
|
+
|
|
721
|
+
Multiple interceptors compose in "onion" order — the first interceptor in the list is the outermost layer:
|
|
722
|
+
|
|
723
|
+
```python Composing multiple interceptors theme={null}
|
|
724
|
+
async def outer_interceptor(request, handler):
|
|
725
|
+
print("outer: before")
|
|
726
|
+
result = await handler(request)
|
|
727
|
+
print("outer: after")
|
|
728
|
+
return result
|
|
729
|
+
|
|
730
|
+
async def inner_interceptor(request, handler):
|
|
731
|
+
print("inner: before")
|
|
732
|
+
result = await handler(request)
|
|
733
|
+
print("inner: after")
|
|
734
|
+
return result
|
|
735
|
+
|
|
736
|
+
client = MultiServerMCPClient(
|
|
737
|
+
{...},
|
|
738
|
+
tool_interceptors=[outer_interceptor, inner_interceptor], # [!code highlight]
|
|
739
|
+
)
|
|
740
|
+
|
|
741
|
+
# Execution order:
|
|
742
|
+
# outer: before -> inner: before -> tool execution -> inner: after -> outer: after
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
**Error handling**
|
|
746
|
+
|
|
747
|
+
Use interceptors to catch tool execution errors and implement retry logic:
|
|
748
|
+
|
|
749
|
+
```python Retry on error theme={null}
|
|
750
|
+
import asyncio
|
|
751
|
+
|
|
752
|
+
async def retry_interceptor(
|
|
753
|
+
request: MCPToolCallRequest,
|
|
754
|
+
handler,
|
|
755
|
+
max_retries: int = 3,
|
|
756
|
+
delay: float = 1.0,
|
|
757
|
+
):
|
|
758
|
+
"""Retry failed tool calls with exponential backoff."""
|
|
759
|
+
last_error = None
|
|
760
|
+
for attempt in range(max_retries):
|
|
761
|
+
try:
|
|
762
|
+
return await handler(request)
|
|
763
|
+
except Exception as e:
|
|
764
|
+
last_error = e
|
|
765
|
+
if attempt < max_retries - 1:
|
|
766
|
+
wait_time = delay * (2 ** attempt) # Exponential backoff
|
|
767
|
+
print(f"Tool {request.name} failed (attempt {attempt + 1}), retrying in {wait_time}s...")
|
|
768
|
+
await asyncio.sleep(wait_time)
|
|
769
|
+
raise last_error
|
|
770
|
+
|
|
771
|
+
client = MultiServerMCPClient(
|
|
772
|
+
{...},
|
|
773
|
+
tool_interceptors=[retry_interceptor], # [!code highlight]
|
|
774
|
+
)
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
You can also catch specific error types and return fallback values:
|
|
778
|
+
|
|
779
|
+
```python Error handling with fallback theme={null}
|
|
780
|
+
async def fallback_interceptor(
|
|
781
|
+
request: MCPToolCallRequest,
|
|
782
|
+
handler,
|
|
783
|
+
):
|
|
784
|
+
"""Return a fallback value if tool execution fails."""
|
|
785
|
+
try:
|
|
786
|
+
return await handler(request)
|
|
787
|
+
except TimeoutError:
|
|
788
|
+
return f"Tool {request.name} timed out. Please try again later."
|
|
789
|
+
except ConnectionError:
|
|
790
|
+
return f"Could not connect to {request.name} service. Using cached data."
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
### Progress notifications
|
|
794
|
+
|
|
795
|
+
Subscribe to progress updates for long-running tool executions:
|
|
796
|
+
|
|
797
|
+
```python Progress callback theme={null}
|
|
798
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
799
|
+
from langchain_mcp_adapters.callbacks import Callbacks, CallbackContext
|
|
800
|
+
|
|
801
|
+
async def on_progress(
|
|
802
|
+
progress: float,
|
|
803
|
+
total: float | None,
|
|
804
|
+
message: str | None,
|
|
805
|
+
context: CallbackContext,
|
|
806
|
+
):
|
|
807
|
+
"""Handle progress updates from MCP servers."""
|
|
808
|
+
percent = (progress / total * 100) if total else progress
|
|
809
|
+
tool_info = f" ({context.tool_name})" if context.tool_name else ""
|
|
810
|
+
print(f"[{context.server_name}{tool_info}] Progress: {percent:.1f}% - {message}")
|
|
811
|
+
|
|
812
|
+
client = MultiServerMCPClient(
|
|
813
|
+
{...},
|
|
814
|
+
callbacks=Callbacks(on_progress=on_progress), # [!code highlight]
|
|
815
|
+
)
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
The `CallbackContext` provides:
|
|
819
|
+
|
|
820
|
+
* `server_name`: Name of the MCP server
|
|
821
|
+
* `tool_name`: Name of the tool being executed (available during tool calls)
|
|
822
|
+
|
|
823
|
+
### Logging
|
|
824
|
+
|
|
825
|
+
The MCP protocol supports [logging](https://modelcontextprotocol.io/specification/2025-03-26/server/utilities/logging#log-levels) notifications from servers. Use the `Callbacks` class to subscribe to these events.
|
|
826
|
+
|
|
827
|
+
```python Logging callback theme={null}
|
|
828
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
829
|
+
from langchain_mcp_adapters.callbacks import Callbacks, CallbackContext
|
|
830
|
+
from mcp.types import LoggingMessageNotificationParams
|
|
831
|
+
|
|
832
|
+
async def on_logging_message(
|
|
833
|
+
params: LoggingMessageNotificationParams,
|
|
834
|
+
context: CallbackContext,
|
|
835
|
+
):
|
|
836
|
+
"""Handle log messages from MCP servers."""
|
|
837
|
+
print(f"[{context.server_name}] {params.level}: {params.data}")
|
|
838
|
+
|
|
839
|
+
client = MultiServerMCPClient(
|
|
840
|
+
{...},
|
|
841
|
+
callbacks=Callbacks(on_logging_message=on_logging_message), # [!code highlight]
|
|
842
|
+
)
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
### Elicitation
|
|
846
|
+
|
|
847
|
+
[Elicitation](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation#elicitation) allows MCP servers to request additional input from users during tool execution. Instead of requiring all inputs upfront, servers can interactively ask for information as needed.
|
|
848
|
+
|
|
849
|
+
#### Server setup
|
|
850
|
+
|
|
851
|
+
Define a tool that uses `ctx.elicit()` to request user input with a schema:
|
|
852
|
+
|
|
853
|
+
```python MCP server with elicitation theme={null}
|
|
854
|
+
from pydantic import BaseModel
|
|
855
|
+
from mcp.server.fastmcp import Context, FastMCP
|
|
856
|
+
|
|
857
|
+
server = FastMCP("Profile")
|
|
858
|
+
|
|
859
|
+
class UserDetails(BaseModel):
|
|
860
|
+
email: str
|
|
861
|
+
age: int
|
|
862
|
+
|
|
863
|
+
@server.tool()
|
|
864
|
+
async def create_profile(name: str, ctx: Context) -> str:
|
|
865
|
+
"""Create a user profile, requesting details via elicitation."""
|
|
866
|
+
result = await ctx.elicit( # [!code highlight]
|
|
867
|
+
message=f"Please provide details for {name}'s profile:", # [!code highlight]
|
|
868
|
+
schema=UserDetails, # [!code highlight]
|
|
869
|
+
) # [!code highlight]
|
|
870
|
+
if result.action == "accept" and result.data:
|
|
871
|
+
return f"Created profile for {name}: email={result.data.email}, age={result.data.age}"
|
|
872
|
+
if result.action == "decline":
|
|
873
|
+
return f"User declined. Created minimal profile for {name}."
|
|
874
|
+
return "Profile creation cancelled."
|
|
875
|
+
|
|
876
|
+
if __name__ == "__main__":
|
|
877
|
+
server.run(transport="http")
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
#### Client setup
|
|
881
|
+
|
|
882
|
+
Handle elicitation requests by providing a callback to `MultiServerMCPClient`:
|
|
883
|
+
|
|
884
|
+
```python Handling elicitation requests theme={null}
|
|
885
|
+
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
886
|
+
from langchain_mcp_adapters.callbacks import Callbacks, CallbackContext
|
|
887
|
+
from mcp.shared.context import RequestContext
|
|
888
|
+
from mcp.types import ElicitRequestParams, ElicitResult
|
|
889
|
+
|
|
890
|
+
async def on_elicitation(
|
|
891
|
+
mcp_context: RequestContext,
|
|
892
|
+
params: ElicitRequestParams,
|
|
893
|
+
context: CallbackContext,
|
|
894
|
+
) -> ElicitResult:
|
|
895
|
+
"""Handle elicitation requests from MCP servers."""
|
|
896
|
+
# In a real application, you would prompt the user for input
|
|
897
|
+
# based on params.message and params.requestedSchema
|
|
898
|
+
return ElicitResult( # [!code highlight]
|
|
899
|
+
action="accept", # [!code highlight]
|
|
900
|
+
content={"email": "user@example.com", "age": 25}, # [!code highlight]
|
|
901
|
+
) # [!code highlight]
|
|
902
|
+
|
|
903
|
+
client = MultiServerMCPClient(
|
|
904
|
+
{
|
|
905
|
+
"profile": {
|
|
906
|
+
"url": "http://localhost:8000/mcp",
|
|
907
|
+
"transport": "http",
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
callbacks=Callbacks(on_elicitation=on_elicitation), # [!code highlight]
|
|
911
|
+
)
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
#### Response actions
|
|
915
|
+
|
|
916
|
+
The elicitation callback can return one of three actions:
|
|
917
|
+
|
|
918
|
+
| Action | Description |
|
|
919
|
+
| --------- | ------------------------------------------------------------------- |
|
|
920
|
+
| `accept` | User provided valid input. Include the data in the `content` field. |
|
|
921
|
+
| `decline` | User chose not to provide the requested information. |
|
|
922
|
+
| `cancel` | User cancelled the operation entirely. |
|
|
923
|
+
|
|
924
|
+
```python Response action examples theme={null}
|
|
925
|
+
# Accept with data
|
|
926
|
+
ElicitResult(action="accept", content={"email": "user@example.com", "age": 25})
|
|
927
|
+
|
|
928
|
+
# Decline (user doesn't want to provide info)
|
|
929
|
+
ElicitResult(action="decline")
|
|
930
|
+
|
|
931
|
+
# Cancel (abort the operation)
|
|
932
|
+
ElicitResult(action="cancel")
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
## Additional resources
|
|
936
|
+
|
|
937
|
+
* [MCP documentation](https://modelcontextprotocol.io/introduction)
|
|
938
|
+
* [MCP Transport documentation](https://modelcontextprotocol.io/docs/concepts/transports)
|
|
939
|
+
* [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters)
|
|
940
|
+
|
|
941
|
+
***
|
|
942
|
+
|
|
943
|
+
<Callout icon="pen-to-square" iconType="regular">
|
|
944
|
+
[Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/oss/langchain/mcp.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
|
|
945
|
+
</Callout>
|
|
946
|
+
|
|
947
|
+
<Tip icon="terminal" iconType="regular">
|
|
948
|
+
[Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
|
|
949
|
+
</Tip>
|