Skip to main content

Connector Development Kit for Deep Query — build MCP-emitting connectors with built-in read/action safety classification and provenance.

Project description

DeepQuerySDK — Connector Development Kit

Build connectors for Deep Query. A connector you write with this SDK emits a standard Model Context Protocol (MCP) server — so Deep Query consumes it through the exact same interface as any public MCP server. You never touch JSON-RPC, transport, or schema plumbing.

Status: v1.1.0 — connectors can now emit all three MCP primitives. Beyond tools (reads + gated actions), use @mcp_resource to expose URI-addressable resources (static or templated) and @prompt to offer prompt templates. See the Resources & Prompts guide and CHANGELOG.md. Built on v1.0.0 — all four build phases below remain.

v1.0.0 — all four build phases complete. Core contracts (Phase 1), the gated preview → approve → execute / reject lifecycle + OAuth 2.1 PKCE scaffolding + credential injection (Phase 2), the deepquery CLI and mock-agent harness with the §5/§6/§13 contracts encoded as validate checks (Phase 3), and the semver compatibility contract + packaging (Phase 4). The SDK contract is at major version 1: connectors declaring sdk_major_version = 1 are loadable by this runtime.

What you define

A connector is a subclass of Connector that declares three things:

You define What it is Gated?
Resources read-only data the agent can retrieve and cite no
Actions operations that change external state yes (preview → execute)
Auth how the connector authenticates to the external system n/a

Every read carries a provenance envelope so live data can be cited honestly. Every action is tagged dq.mutates: true in the emitted MCP server so Deep Query's approval gate knows it must be confirmed by a human.

Install (development)

# from the DeepQuerySDK/ folder, using the bundled venv
venv\Scripts\python.exe -m pip install -e .

60-second example

from deepquery_sdk import Connector, OAuth2Auth, resource, action

class JiraConnector(Connector):
    name = "jira"
    version = "0.1.0"
    description = "Read and act on Jira issues."

    # Declare OAuth 2.1 with least-privilege scopes. The gateway runs/stores the
    # grant and injects the token; this connector never stores credentials.
    auth = OAuth2Auth(
        authorize_endpoint="https://auth.atlassian.com/authorize",
        token_endpoint="https://auth.atlassian.com/oauth/token",
        scopes=["read:jira-work", "write:jira-work"],
    )
    requires_network = True

    @resource(description="Search Jira issues by text query.",
              input_schema={"type": "object",
                            "properties": {"query": {"type": "string"}},
                            "required": ["query"]})
    def search_issues(self, query: str):
        # ... call the real Jira API here ...
        return [
            self.cite(
                {"key": "DQ-431", "summary": "Login flow broken", "status": "In Review"},
                source_object_id="DQ-431",
                title_or_label="DQ-431 — Login flow broken",
                deep_link="https://example.atlassian.net/browse/DQ-431",
                mutability_note="live status field",
            )
        ]

    @action(description="Create a new Jira issue.",
            input_schema={"type": "object",
                          "properties": {"project": {"type": "string"},
                                         "summary": {"type": "string"}},
                          "required": ["project", "summary"]})
    def create_issue(self, project: str, summary: str):
        # only ever called after the approval gate confirms the preview.
        auth = self.apply_auth()  # headers built from the injected credential
        return {"created": f"{project}-NEW", "summary": summary}

    @create_issue.preview
    def _(self, project: str, summary: str) -> str:
        return f"Will create a new issue in project '{project}' titled '{summary}'."

Emit and serve it as an MCP server (the gateway injects the credential):

from deepquery_sdk import Credential, static_credential_provider
from deepquery_sdk.mcp_emit import run_stdio

connector = JiraConnector()
connector.set_credential_provider(static_credential_provider(Credential(token="...")))
run_stdio(connector)

The gated action lifecycle

Calling an action does not execute it. It returns a preview and a single-use approval token; the gateway drives the decision through two control tools:

call create_issue(args)        -> { status: "preview", approval_token, preview, arguments }
call dq.execute_action(token)  -> runs execute() for exactly those args  (after human approval)
call dq.reject_action(token)   -> discards the action; it never runs

The token binds the previewed arguments, so execute can never drift from what the human approved, and a rejected/used token can never run.

The deepquery CLI

deepquery scaffold acme-crm           # generate a new connector from the template
deepquery validate connector.py       # enforce the §5/§6/§13 safety contracts
deepquery manifest connector.py       # print/export the connector manifest
deepquery run-dev connector.py        # drive it interactively with the mock agent
deepquery emit connector.py --out dist/   # produce the deployable MCP server artifact

A target can be a path/to/connector.py, a directory containing connector.py, or a module.path:ClassName. validate is the gatekeeper: it statically scans @resource bodies for mutating calls and fails a resource that writes (a misclassified action), plus checks descriptions, manifest, deployment honesty, and least-privilege scopes.

The dev harness (deepquery_sdk.harness.MockAgent) discovers a connector over a real in-memory MCP session and drives reads (inspecting provenance) and the full preview → approve / reject action flow — the same sequence the real Agent Layer uses.

Try it without the test suite

# read path + classification + provenance, over a real stdio MCP server
venv\Scripts\python.exe examples\manual_client.py

# the full preview -> approve -> execute and preview -> reject flow
venv\Scripts\python.exe examples\manual_action_flow.py

See examples/jira_connector/ for the full runnable connector used in the Phase 1 and Phase 2 tests.

Versioning & compatibility

The SDK follows SemVer; see CHANGELOG.md. Every connector manifest declares the SDK major version it targets, and the gateway calls assert_compatible(manifest) before loading — refusing a connector built against an incompatible major with a clear error. Breaking changes ship with a guide in MIGRATIONS.md.

Release / publishing (maintainers)

Distributions are built with python -m build into dist/. To publish to PyPI:

python -m build                       # build sdist + wheel into dist/
python -m twine check dist/*          # validate metadata
python -m twine upload dist/*         # publish (requires PyPI credentials)

Tag the release v<version> and ensure version in pyproject.toml matches SDK_VERSION (a test enforces this against the installed package).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deepquery_sdk-1.1.1.tar.gz (51.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

deepquery_sdk-1.1.1-py3-none-any.whl (48.7 kB view details)

Uploaded Python 3

File details

Details for the file deepquery_sdk-1.1.1.tar.gz.

File metadata

  • Download URL: deepquery_sdk-1.1.1.tar.gz
  • Upload date:
  • Size: 51.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for deepquery_sdk-1.1.1.tar.gz
Algorithm Hash digest
SHA256 f532df203f967284f2f46373a99b23166ec3e3954bac6995f51b937c9f2137d1
MD5 a17d3674664464f5b057fa351d48f4ad
BLAKE2b-256 b23fea700fe71339ebd83fa574b87babc8f86b04150c295d79b25adad58f0007

See more details on using hashes here.

File details

Details for the file deepquery_sdk-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: deepquery_sdk-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 48.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for deepquery_sdk-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2254f9edd78b67a8a444262019606a80c3800972b47603aa1a6ac42dfbf0d432
MD5 dcb90df62fa64d473ef06126b4f705f2
BLAKE2b-256 42891577707bf91d107a432eaa36a27afbd11bfec11524df40d39d6795c37ea2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page