Skip to content

formatted#64

Open
GokulVGAot wants to merge 74 commits into
AOT-Technologies:mainfrom
GokulVGAot:H-4.-SMTP-connector-lets-the-caller-choose-the-destination-server
Open

formatted#64
GokulVGAot wants to merge 74 commits into
AOT-Technologies:mainfrom
GokulVGAot:H-4.-SMTP-connector-lets-the-caller-choose-the-destination-server

Conversation

@GokulVGAot

Copy link
Copy Markdown
Collaborator

fix(smtp): pin relay to server env and block caller-controlled host/port (H-4)

smtp.send_email no longer accepts host, port, or use_tls in the request
payload. Relay settings are loaded from SMTP_HOST, SMTP_PORT, and
SMTP_USE_TLS only, with optional NW_SMTP_ALLOWED_HOSTS allowlist, so
platform SMTP credentials are never sent to a caller-chosen server.

vinaayakh-aot and others added 30 commits March 31, 2026 09:49
Expand MCP server entrypoints to dynamically register and expose all connector actions for fhir_epic and fhir_cerner, and to expose full Google Drive operations and improved SMTP behavior. Added multiple new MCP tools: patient search, encounter search, create/search DocumentReference for both Epic and Cerner; several Google Drive tools (files.create/list/get/update/upload/delete, permissions.create); and SMTP now accepts multiple recipients and improved logging. Refactored per-server helpers (e.g. _get_connector), standardized input handling/parsing and return shapes, and updated docs/mcp-servers.md to list the exposed tools. Also adds a service_account.json for Google Drive usage (contains service account credentials — treat as sensitive and consider moving to secrets management).
…d-in-connectors-to-mcp

Register full MCP tools for FHIR, Drive, SMTP
- Merged SDKConnector and BaseConnector
- Updated Tests
- Updated Docs
* Temporary commit

* Added connector package

* Fixed MCPs with packages

* Updated docs
* Updated Cerner and FHIR connection

* cleanup and update mcp

* SDK connector added

* Updated architecture

* Update Playground to work with the new architecture

* Register full MCP tools for FHIR, Drive, SMTP

Expand MCP server entrypoints to dynamically register and expose all connector actions for fhir_epic and fhir_cerner, and to expose full Google Drive operations and improved SMTP behavior. Added multiple new MCP tools: patient search, encounter search, create/search DocumentReference for both Epic and Cerner; several Google Drive tools (files.create/list/get/update/upload/delete, permissions.create); and SMTP now accepts multiple recipients and improved logging. Refactored per-server helpers (e.g. _get_connector), standardized input handling/parsing and return shapes, and updated docs/mcp-servers.md to list the exposed tools. Also adds a service_account.json for Google Drive usage (contains service account credentials — treat as sensitive and consider moving to secrets management).

* Google drive connector has

* Added Test coverage

* Add Documentation

* Updated Connector Class

- Merged SDKConnector and BaseConnector
- Updated Tests
- Updated Docs

* Temporary commit

* Fix inconsistency in MCP server responses

* Added connector package

* Fixed MCPs with packages

* Updated docs

* Remove credentials and artifacts from tracking, update .gitignore

- Untrack GCP service account key (connectorplatform-180d995a1c96.json)
- Untrack Grafana dashboard export (auto-generated artifact)
- Add patterns for credentials, grafana exports, uv.lock, temp files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Added workflows and packages

* Updated docs and comments

* Updated docs

* Deleted unnecessary commit

---------

Co-authored-by: kesav-aot <kesav.gopan@aot-technologies.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add pluggable AuthProvider system

Introduce a pluggable authentication layer for connectors.

- Add new node_wire_runtime.auth package with AuthProvider base class and implementations: NoAuthProvider, StaticTokenAuthProvider, OAuth2AuthProvider (client_credentials with private_key_jwt and client_secret_post, caching + asyncio.Lock), and ServiceAccountAuthProvider.
- Wire auth into runtime: export providers in src/node_wire_runtime/__init__.py and update BaseConnector to accept an auth_provider, expose auth_provider property and async get_auth_headers() helper (defaults to NoAuthProvider).
- Update ConnectorFactory to construct and inject AuthProvider instances from connectors.yaml auth: blocks (static_token, oauth2, service_account, static_credentials wrapper for SMTP); unknown types fall back to NoAuthProvider.
- Replace Epic/Cerner connector in-file JWT/token logic with delegation to the runtime auth provider; add Cerner token_url sanity check.
- Update Google Drive connector to obtain SDK credentials via the ServiceAccountAuthProvider (with sync fallbacks and legacy secret fallback for backwards compatibility).
- Extend connectors.yaml and sample with auth configuration examples and a security note advising secrets stay out of YAML.
- Update docs/connectors.md with guidance for using self.get_auth_headers() and auth provider types.
- Add tests for auth providers and adjust FHIR tests accordingly.

This centralises token acquisition, caching and secret resolution so connector logic no longer handles raw credentials or IdP-specific handshakes.

* Use error_message key for error payloads

Rename the error payload field from "message" to "error_message" in HttpGenericConnector and StripeConnector to standardize error reporting. Updated src/node_wire_http_generic/logic.py and src/node_wire_stripe/logic.py to send "error_message": str(exc) in the logged/returned error context.

* Update connectors.md
Prevent leaking SMTP sender/recipient PII into logs by scrubbing email addresses. Added _redact_tool_args_for_log to agents/toolhive.py to replace email values in known SMTP fields with "[REDACTED]" and used it when logging tool calls. Updated node_wire_smtp/logic.py to log a domain-only sender hint (sender_domain) instead of the full from_email in prepare and response records. Added test test_smtp_send_email_does_not_log_sender_address to assert the full sender address never appears in log records and the domain hint is present.
Co-authored-by: My Name <my.name@rdbrck.com>
* Implement native Streamable-HTTP transport support

Integrated a first-class HTTP/SSE transport mode for MCP servers, allowing
Node Wire to operate as a native web citizen alongside legacy stdio mode.
Key Changes:
- McpServer: Refactored to support dynamic transport selection via
  `NW_MCP_TRANSPORT` (stdio vs streamable-http).
- HTTP Server: Implemented Starlette/Uvicorn-based ASGI server for
  Streamable-HTTP, resolving 307 redirect issues via direct ASGI Routing.
- Transport Headers: Updated ToolHiveMcpClient to satisfy strict MCP
  protocol requirements by including mandatory 'Accept' headers.
- Entrypoints: Updated all MCP entrypoints (entrypoint, google_drive,
  fhir, smtp) to support environment-driven transport selection.
- Playground: Refined proxy fallback logic in scenarios.py to prevent
  unnecessary stdio switches on non-tool-calling turns.
- Docs: Updated README.md, Setup.md, and mcp-servers.md with
  NW_MCP_TRANSPORT, NW_MCP_PORT, and NW_MCP_HOST configuration details.
This enables seamless integration with both ToolHive proxies and direct
HTTP-based MCP clients.Integrated a first-class HTTP/SSE transport mode for MCP servers, allowing
Node Wire to operate as a native web citizen alongside legacy stdio mode.
Key Changes:
- McpServer: Refactored to support dynamic transport selection via
  `NW_MCP_TRANSPORT` (stdio vs streamable-http).
- HTTP Server: Implemented Starlette/Uvicorn-based ASGI server for
  Streamable-HTTP, resolving 307 redirect issues via direct ASGI Routing.
- Transport Headers: Updated ToolHiveMcpClient to satisfy strict MCP
  protocol requirements by including mandatory 'Accept' headers.
- Entrypoints: Updated all MCP entrypoints (entrypoint, google_drive,
  fhir, smtp) to support environment-driven transport selection.
- Playground: Refined proxy fallback logic in scenarios.py to prevent
  unnecessary stdio switches on non-tool-calling turns.
- Docs: Updated README.md, Setup.md, and mcp-servers.md with
  NW_MCP_TRANSPORT, NW_MCP_PORT, and NW_MCP_HOST configuration details.
This enables seamless integration with both ToolHive proxies and direct
HTTP-based MCP clients.

* fix regressions and align tests with Streamable-HTTP transport

Updated the test suite to support the new unified transport dispatcher
and satisfy strict HTTP protocol requirements.
Key Changes:
- entrypoints: Updated mocks to assert calls to the unified `run()`
  method instead of legacy `run_stdio()`.
- transport: Added an `_ASGIApp` wrapper in tests to satisfy Starlette's
  request handler signature.
- protocol: Updated manual HTTP test requests to include mandatory
  'Accept' and 'Mcp-Session-Id' headers for spec compliance.
- lifecycle: Wrapped asynchronous test clients in `session_manager.run()`
  to properly initialize the MCP TaskGroup.
- isolation: Introduced `monkeypatch` fixtures to skip the broken `slack`
  connector during auto-registration tests, preventing `ModuleNotFoundError`.
Introduce a native streamable-http MCP transport and end-to-end streaming support for agents and the playground UI. Changes include:

- Backend: add /scenarios/agent-transport and a new /scenarios/agent-chat-stream endpoint that returns newline-delimited JSON (NDJSON) via StreamingResponse. Implement ToolHiveAgent.run_events to emit progress events (meta, status, step, final_chunk, error, done) and _chunk_agent_text to split assistant text into UI-friendly chunks. Adjust agent-chat to choose transport and resolve MCP URLs only for streamable-http.

- Frontend/playground: show transport status pill, load transport from /scenarios/agent-transport, support stream consumption with readNdjsonStream, render streaming assistant bubbles, step cards, and trace badges, and handle both stdio (buffered) and streamable-http modes.

- Docs and setup: update README.md, Setup.md, docs/mcp-servers.md, and playground/README.md to document using python -m uv run node-wire, configuring NW_MCP_TRANSPORT/NW_MCP_HOST/NW_MCP_PORT/NW_MCP_PATH, and testing with MCP Inspector.

- Styling: add CSS for transport status pill and streaming bubble behavior.

- Tests: add unit tests validating the /scenarios/agent-transport endpoint behavior.

These changes enable progressive tool-step rendering and chunked final answers for better UX when running agents over HTTP streams.
* mcp-auth-scenario-tested

* auth verification tested successfully and verified

* identity propagated to runtime and MCP scope policy is global issue resolved

---------

Co-authored-by: My Name <my.name@rdbrck.com>
* Add Stripe connector with payment and subscription functionalities

* Refactor error handling and response structure in StripeConnector methods

* Implement Stripe payment and subscription management features in the playground

* Add idempotency_key to ChargeInput, CancelSubscriptionInput, CreatePaymentIntentInput, CreateSubscriptionInput, and IssueRefundInput for duplicate operation prevention

* Fix StripeConnector to handle optional price_id and update tests for charge action and REST exposure

* Refactor StripeConnector to use asyncio for retrieving SetupIntent, Invoice, and PaymentIntent, improving performance and responsiveness.

* Replace Stripe connector icon with SVG for improved visual consistency
* Add configurable timeouts, breakers, and sanitizers

Make connector timeouts and resilience configurable and sanitize telemetry. Replace hardcoded httpx/aiosmtplib 30s timeouts with AOT_CONNECTOR_TIMEOUT (default 30.0) across Cerner, Epic, HTTP generic, and SMTP connectors and add needed os imports. Update BaseConnector to use per-tenant CircuitBreaker instances with AOT_CIRCUIT_BREAKER_FAIL_MAX and AOT_CIRCUIT_BREAKER_RESET_TIMEOUT (defaults: 5 and 30) and add audit metadata on policy denials. Add sanitizing wrappers for span and log exporters to redact sensitive attributes before exporting. Also add commented sample.env entries documenting the new environment variables.

* Manage tenant circuit breakers; FHIR connector fixes

Initialize and use a per-tenant circuit breaker cache in BaseConnector (self._breakers) and guard against a missing attribute by creating it on demand. Use a local breaker_cache reference when creating/looking up tenant-specific CircuitBreaker instances and wrap execution with resilience. Add two tests to verify that tenant breakers are cached and that a missing cache is rebuilt. In FHIR Cerner logic, add FHIR JSON headers and read Cerner-specific secrets (private key, kid, client_id) to prepare for token/JWT construction. In FHIR Epic logic, add a codecs import and ensure the returned headers include the Bearer access token.

* Delegate FHIR auth to AuthProvider

Replace in-file JWT/token exchange logic for Cerner and Epic connectors with calls to the injected AuthProvider (get_auth_headers()). This removes duplicated client_assertion/JWT construction and HTTP token exchange code and lets providers handle token acquisition, scope resolution and caching. Also ensure FHIR Content-Type/Accept headers are present when providers omit them. Cerner-specific: guard retrieval of cerner_token_url and raise a clear ValueError if the URL contains the known malformed '/hosts/' sandbox path.
* feat: add Salesforce connector for managing CRM records

- Introduced a new Salesforce connector to handle CRUD operations for Leads and Contacts.
- Implemented OAuth2 authentication with refresh token support.
- Added Dockerfile for the Salesforce connector.
- Updated pyproject.toml and sample.env to include Salesforce configuration.
- Enhanced build scripts to include Salesforce image building.
- Created comprehensive tests for Salesforce connector actions.
- Documented the Salesforce connector capabilities and usage in salesforce_connector.md.

* feat: update Salesforce connector to use model_dump and ConfigDict for field population

* feat: add public access to global connector registry and update test for Salesforce connector
* Propagate HTTP headers via ContextVar

Introduce a ContextVar (_http_request_headers) to capture ASGI request headers and pass them into authenticate_mcp_request. The McpServer now retrieves headers from the context when authenticating, and the ASGI wrapper sets/resets the ContextVar around request handling. Tests updated to set the context var in the test ASGI app and new tests verify authentication accepts Authorization and X-API-Key headers (tools/list flow).

* Add streamable agent chat support

Implement streaming agent chat over a 'streamable-http' transport and UI improvements. Frontend: add transport status UI, NDJSON stream reader, streaming chat bubble/loader/tracing UI, and logic to fetch /scenarios/agent-transport and /scenarios/agent-chat-stream. Backend (playground/scenarios.py): add /agent-transport endpoint, refactor task builder and transport detection, and add /agent-chat-stream StreamingResponse that proxies ToolHiveAgent events. Agent core (src/agents/toolhive.py): add helpers to chunk text and emit stream events via ToolHiveAgent.run_events (meta/status/step/final_chunk/error/done). Tests: add test to verify run_events emits final done event with trace_id. Styles: add CSS for transport pill, streaming bubble, and end messages.

* Add streaming utilities and buffered iterator

Introduce a new streaming helper module (node_wire_runtime.streaming) that provides StreamSignal, stream_completion_log, resolve_stream_buffer_ms, and an async BufferedStreamIterator to optionally buffer streamed events. Wire these helpers into ToolHive and MCP server: ToolHive now emits completion logs and supports configurable buffering for run_events, and the MCP server logs stream completion on success/failure. Documentation and samples updated to document NW_STREAM_BUFFER_MS, completion signals, and playground fallback handling. The buffering default is 0 (disabled) and values are clamped (0–30000 ms).

* Update test_scope_policy_transport.py
kesav-aot and others added 29 commits May 20, 2026 23:33
* Add Connector Apps view and streaming timers

Introduce a Connector Apps marketplace and app cards, plus improved navigation and streaming UI.

- index.html: add a new Connector Apps selection card and a connector-apps-selection-view with an app-card for an External Patient Viewer and an apps back button.
- app.js: include .app-card in selection handling and implement new views (connector-apps-menu, ext-patient-viewer), refined back-button logic (apps-back-btn, backSelectionBtn behavior, backToConnectorsBtn behavior), and setMode adjustments for mode-specific back labels. Insert step cards before active streaming bubbles when present.
- Streaming: add an inline running timer to streaming bubbles, start/clear a timer interval during stream lifecycle, pass final elapsed time to appendStreamEndMessage, and ensure proper cleanup on errors/interrupts.
- style.css: add styles for .app-card, responsive selection layout, visual tweaks for selection cards, and styling for the .stream-running-timer and apps selection view.

These changes improve UX for browsing connector apps and provide visible timing/cleanup for streaming agent responses.

* Update Slack scopes and bump Gemini model

Remove the `conversations:open` scope from the Slack connector docs (it's no longer listed as required). Also update sample.env to use `GEMINI_MODEL=gemini-2.5-flash` instead of `gemini-2.0-flash` to reflect the newer model.

* Update style.css
…-for-playground-home-page

Add integration tests for Google Drive connector and enhance playgrou…
…-for-playground-home-page

streamline environment variable retrieval for test recipient email
…-for-playground-home-page

Add Connector Apps card and navigation to Playground Home integration…
…-for-stripe-connector

Add integration tests for Stripe connector in Playground
Updated NW_ALLOWED_CONNECTORS to include 'stripe'.
…-for-salesforce-connector

Add integration tests for Salesforce connector in Playground
…ironment variables, and refactor utility functions
…-for-slack-connector

Cnp 80 create integration tests for slack connector
…onnector; update environment variables and implement necessary fixtures
Document how to start the Grafana stack for telemetry and add a Build Packages (Wheels) section to the README that points to scripts/build-packages.sh and docs/packaging.md. Also add a link to the Grafana telemetry docs in the docs list and clean up heading order. In docs/packaging.md move the pip prerequisites up into the Python package build lifecycle and call out using bash scripts/build-packages.sh --help for usage.
Update docker-compose.mcp.yml to add build context/dockerfile for each MCP service and set NW_ALLOWED_CONNECTORS per service. Update README.md and docs/mcp-servers.md to recommend running docker compose with --build and to note that each service pins its allowed connector so a broad .env value won't cause per-connector images to import optional dependencies they don't contain. This ensures local wheels are built and images are constrained to their connector-specific deps for local validation.
Add integration tests for multiple connectors and playground flows
To fix the Docker compose issue, add per-service build and NW_ALLOWED_CONNECTORS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants