connectkit 0.1.0__tar.gz → 0.1.2__tar.gz
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.
- {connectkit-0.1.0 → connectkit-0.1.2}/.gitignore +1 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/PKG-INFO +2 -1
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/bridge.py +6 -2
- connectkit-0.1.2/connectkit/runtime.py +302 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/vault.py +53 -7
- {connectkit-0.1.0 → connectkit-0.1.2}/pyproject.toml +2 -1
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_runtime.py +23 -23
- {connectkit-0.1.0 → connectkit-0.1.2}/uv.lock +330 -1
- connectkit-0.1.0/.env +0 -1
- connectkit-0.1.0/connectkit/runtime.py +0 -189
- {connectkit-0.1.0 → connectkit-0.1.2}/LICENSE +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/README.md +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/STRATEGY.md +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/__init__.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/backends/__init__.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/backends/cli.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/backends/mcp.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/meta_tools.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/oauth.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/sdk_adapter.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/spec.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectkit/utils.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/accelo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/active-campaign.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/acuity-scheduling.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/addepar.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/adobe-commerce.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/adobe-workfront.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/adobe.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/adyen.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/affinity-v2.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/affinity.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/aimfox.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/aircall.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/airtable.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/algolia.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/amazon-selling-partner.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/amazon.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/amplitude.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/anrok.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/anthropic.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/apaleo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/apify.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/apollo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/apple-app-store.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/appstle-subscriptions.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/asana.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ashby.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/atlas-so.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/atlassian-service-account-api-token.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/atlassian.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/attention.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/attio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/auth0.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/autodesk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/autotask.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/auvik.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/avalara.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/avoma.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/aws-iam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/aws-inspector2.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/aws-multi-service.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/aws.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/axiom.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/azure-devops.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bamboohr.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/basecamp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/battlenet.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/beehiiv.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bettercontact.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bigcommerce.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bill.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bing-webmasters.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bird.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bitbucket.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bitdefender.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bitly.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/blackbaud.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/blandai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/boldsign.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/booking-com.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/box.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/braintree.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/braze.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/brevo-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/brex-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/brex-staging.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/brex.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/builder-io-private.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/builder-io-public.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/buildium.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/builtwith.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/bullhorn.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cal-com-v1.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cal-com-v2.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/calendly.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/callrail.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/candis.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/canny.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/canva.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/canvas-lms.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/certn.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/chargebee.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/chattermill.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/checkhq.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/checkr-partner-staging.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/checkr-partner.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/chorus.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cin7-core.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/circle-so.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clari-copilot.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clay.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clearbit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clerk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cleverreach.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clickhouse.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clicksend.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clickup.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/close.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cloudbeds.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cloudflare.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cloudtalk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/clover.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/coda.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/codeclimate.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/codegen.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/companycam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/connectwise-psa-staging.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/connectwise-psa.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/constant-contact.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/conta-azul.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/contactout.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/contentful.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/contentstack.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/convertkit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/copper-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/copper.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/coros.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/crisp-plugin-install.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/crisp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/crunchbase.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cursor.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/customerio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/cyberimpact.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/databricks.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/datacandy.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/datadog.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/datev.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/datto-rmm.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/deel.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/deepl.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/demodesk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/devin.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/dialpad.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/digitalocean.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/discord.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/discourse.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/dixa.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/document360.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/docusign.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/drata.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/drchrono.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/dropbox-sign.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/dropbox.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/e-conomic.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ebay.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/egnyte.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/elasticsearch.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/elevenlabs.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/elevio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/emarsys.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/employment-hero.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/entrata.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/envoy.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/epic-games.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/evaluagent.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/eventbrite.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/exa.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/exact-online.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/exist.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/expensify.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/facebook.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/factorial.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fairing.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/falai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fanvue.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fathom.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fellow.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fiber-ai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/figma.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fillout-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fillout.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/findymail.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/firecrawl.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fireflies.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/firstbase.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fiserv-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fitbit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/float.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/folk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fortnox.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freeagent.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freepik.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freshbooks.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freshdesk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freshsales.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freshservice.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/freshteam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/front-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/front.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ftp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/fullenrich.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gamma.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/garmin.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gebruder-weiss.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gem.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gerrit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/getresponse.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ghost-content.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/github-app.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/github.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gitlab.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/glyphic.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gong.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google-ads.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google-analytics.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google-gemini.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google-maps.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google-play.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google-workspace.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/google.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gorgias.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/grafana.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/grain-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/grain.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/granola.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse-assessment.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse-harvest-partner.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse-harvest.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse-ingestion.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse-job-board.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse-onboarding.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/greenhouse.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/grist.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gumroad.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/guru.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gusto-demo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/gusto.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/hackerrank-work.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/harvest.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/health-gorilla.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/helpscout-docs.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/helpscout-mailbox.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/hex.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/heygen.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/heymarket.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/heyreach.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/hibob-service-user.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/highlevel-white-label.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/highlevel.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/holded.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/hover.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/hubspot.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/icypeas.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/incident-io.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/insightly.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/instagram.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/instantly.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/intercom.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/intuit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ironclad.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/itglue.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jazzhr.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jira-data-center-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jira-data-center.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jira.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jobadder.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jobber.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jobvite.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jotform.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/jumpcloud.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/juniper-mist.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/justworks.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/kafka.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/kandji.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/keap.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/kintone-user-api.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/kintone.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/klaviyo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/klicktipp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/klipfolio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/knowbe4.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/kustomer.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lagrowthmachine.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lastpass.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lattice.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/leadmagic.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lemlist.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lessonly.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lever.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lightspeed-retail.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/linear.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/linkedin.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/linkhut.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/listmonk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lob.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lokalise.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/loop-returns.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/loops-so.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/luma.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/lumos.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mailchimp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mailerlite.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mailgun.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mailjet.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/make.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/manatal.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/maximizer-on-premise.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/maximizer.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/maxio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mcp-generic.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mercury.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/metabase.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/microsoft-365.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/microsoft-dynamics.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/microsoft-entra-id.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/microsoft-teams-bot.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/microsoft-tenant-specific.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/microsoft.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mindbody.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/minimax.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/miro.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/missive.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mixpanel.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mollie.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/momentum-io.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/monday.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mongodb.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mural.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/mysql.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/namely.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/nationbuilder.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/netlify.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/netsuite-tba.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/netsuite.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/next-cloud-ocs.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/nocrm.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/northbeam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/notion.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/nyne-ai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ocean-io.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/odoo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/okta-preview.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/okta.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/one-drive-personal.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/onlogist.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/oomnitza.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/open-hands.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/openai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/oracle-hcm.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ordinal.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/osu.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/oura.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/outreach.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pagerduty.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/paligo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pandadoc-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pandadoc.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/paycom.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/paycor.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/payfit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/paypal.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pendo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pennylane-company-api.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pennylane.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/peopledatalabs.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/perdoo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/perk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/perplexity.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/personio-recruiting.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pingone.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pinterest.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pipedream.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pipedrive.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pivotaltracker.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/plain.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pleo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/podium.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/postgres.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/posthog.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/postman.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/practicefusion.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/precisefp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/printful.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/private-api-bearer.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/prive.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/procore.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/productboard.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/prospeo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/provenexpert.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/prtg-classic.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/pylon.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/qualia.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/qualtrics.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/quentn.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/quickbase.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/quickbooks.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/quipteams.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rabbitmq.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ragieai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ramp.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rapidapi.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/razorpay.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/readwise-reader.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/readwise.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/reapit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/recall-ai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/recharge.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/recruitcrm.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/recruitee.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/recruiterflow.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/reddit.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/redis.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/refiner.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/replicate.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/reply-io.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/resend.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/retell-ai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ring-central.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ringover.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rippling-shop-app.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rippling.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rock-gym-pro.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rocketlane.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rocketreach.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/rootly.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sage-hr.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sage-people.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sage.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/salesforce-experience-cloud.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/salesforce.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/salesloft.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/schwab.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/scrapedo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/segment.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sellsy.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/semrush.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sendgrid.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sentinelone.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/sentry.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/servicem8.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/servicenow.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/shipstation-v2.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/shipstation.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/shopify-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/shopify-partner.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/shopify.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/shortcut.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/signnow.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/simpro.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/skio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/slab.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/slack.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/smartlead-ai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/smartrecruiters-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/smartsheet.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/smugmug.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/snapchat.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/snipe-it.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/snowflake-jwt.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/snowflake.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/splitwise.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/spotify.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/squarespace.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/squareup.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/stackexchange.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/statista.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/stay-ai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/store-leads.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/strava-web.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/strava.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/streak.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/stripe-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/stripe-app.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/stripe-express.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/stripe.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/supabase.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/survey-monkey.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tailscale-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tally.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/teamleader.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/teamtailor.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/teamwork.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/telegram.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/terraform.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/thrivecart-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ticktick.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tiktok-accounts.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tiktok-ads.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tiktok-personal.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/timely.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tldv.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/todoist.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/toggl.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/torii.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/trakstar-hire.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/trello.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tremendous.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/triple-whale.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tsheetsteam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/tumblr.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twenty-crm-self-hosted.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twenty-crm.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twilio.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twinfield.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twitch.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twitter-v2.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/twitter.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/typeform.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/typefully-v2.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/typefully.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/uber.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ukg-pro-wfm.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/ukg-pro.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/unanet.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/unauthenticated.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/unipile.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/upsales.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/valley-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/vercel.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/vimeo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/vtex.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wakatime.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wave-accounting.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wealthbox.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/webex.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/webflow.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/webinarjam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wejam.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/whatsapp-business.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/whoop.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wildix-pbx.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wise-api-key.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wiseagent.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wiza.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/woocommerce.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wordpress.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/workable.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/workday.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/workos.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/workpath.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/wrike.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/xai.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/xero.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/yahoo.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/yandex.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/youtube.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zapier-nla.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zapier.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zendesk-sell.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zendesk.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zenefits.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zoho.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zoom.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/connectors/zorus.yaml +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/__init__.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_bridge.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_cli_adapter.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_connector_specs.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_mcp_adapter.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_oauth.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_spec.py +0 -0
- {connectkit-0.1.0 → connectkit-0.1.2}/tests/test_vault.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: connectkit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Connect AI agents to SaaS — one YAML file per service. OAuth, token vault, tool discovery.
|
|
5
5
|
Author: Eddy Xu
|
|
6
6
|
License: MIT
|
|
@@ -19,6 +19,7 @@ Requires-Python: >=3.11
|
|
|
19
19
|
Requires-Dist: cryptography>=41.0
|
|
20
20
|
Requires-Dist: fastapi>=0.129
|
|
21
21
|
Requires-Dist: httpx>=0.28
|
|
22
|
+
Requires-Dist: mcp>=1.0.0
|
|
22
23
|
Requires-Dist: pydantic>=2.0
|
|
23
24
|
Requires-Dist: pyyaml>=6.0
|
|
24
25
|
Provides-Extra: dev
|
|
@@ -85,11 +85,16 @@ class ConnectKitBridge:
|
|
|
85
85
|
return self._vault
|
|
86
86
|
|
|
87
87
|
async def discover(self) -> None:
|
|
88
|
-
|
|
88
|
+
await self._runtime.refresh_all()
|
|
89
|
+
self._tools = await self._runtime.get_tools()
|
|
89
90
|
logger.info(
|
|
90
91
|
f"connectkit.discover user={self.user_id} tools={len(self._tools)}"
|
|
91
92
|
)
|
|
92
93
|
|
|
94
|
+
async def refresh_all(self) -> None:
|
|
95
|
+
"""Refresh all expired OAuth tokens."""
|
|
96
|
+
await self._runtime.refresh_all()
|
|
97
|
+
|
|
93
98
|
def get_tool_definitions(self) -> list[dict[str, Any]]:
|
|
94
99
|
return self._tools
|
|
95
100
|
|
|
@@ -97,7 +102,6 @@ class ConnectKitBridge:
|
|
|
97
102
|
return self._runtime.list_available()
|
|
98
103
|
|
|
99
104
|
def list_available_specs(self) -> list[ConnectorSpec]:
|
|
100
|
-
"""Return full ConnectorSpec objects for all known connectors."""
|
|
101
105
|
return self._runtime.get_specs()
|
|
102
106
|
|
|
103
107
|
def health(self) -> dict[str, Any]:
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"""ConnectorRuntime — load specs, check connections, discover tools, refresh tokens."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
from datetime import UTC, datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import httpx
|
|
12
|
+
|
|
13
|
+
from connectkit.backends.cli import CLIAdapter
|
|
14
|
+
from connectkit.backends.mcp import MCPAdapter
|
|
15
|
+
from connectkit.spec import AuthType, ConnectorSpec, ToolSourceType
|
|
16
|
+
from connectkit.vault import CredentialVault
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger("connectkit")
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger("connectkit")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConnectorRuntime:
|
|
24
|
+
"""Orchestrates: YAML specs → auth check → backend → tool dicts.
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
runtime = ConnectorRuntime(
|
|
28
|
+
spec_dir="./connectors",
|
|
29
|
+
vault=CredentialVault("./data/users/alice"),
|
|
30
|
+
user_id="alice",
|
|
31
|
+
)
|
|
32
|
+
tools = await runtime.get_tools() # async for MCP discovery
|
|
33
|
+
available = runtime.list_available()
|
|
34
|
+
health = runtime.health()
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
spec_dir: str | Path,
|
|
40
|
+
vault: CredentialVault,
|
|
41
|
+
user_id: str,
|
|
42
|
+
):
|
|
43
|
+
self.spec_dir = Path(spec_dir)
|
|
44
|
+
self.vault = vault
|
|
45
|
+
self.user_id = user_id
|
|
46
|
+
self._specs: list[ConnectorSpec] = []
|
|
47
|
+
self._load_specs()
|
|
48
|
+
|
|
49
|
+
def _load_specs(self) -> None:
|
|
50
|
+
if self.spec_dir.exists():
|
|
51
|
+
self._specs = ConnectorSpec.from_yaml_dir(self.spec_dir)
|
|
52
|
+
|
|
53
|
+
def get_specs(self) -> list[ConnectorSpec]:
|
|
54
|
+
return list(self._specs)
|
|
55
|
+
|
|
56
|
+
def reload(self) -> None:
|
|
57
|
+
self._load_specs()
|
|
58
|
+
|
|
59
|
+
async def try_refresh_token(self, spec: ConnectorSpec) -> None:
|
|
60
|
+
"""Refresh an OAuth2 token if it has a refresh_token and has expired."""
|
|
61
|
+
if spec.auth.type != AuthType.OAUTH2:
|
|
62
|
+
return
|
|
63
|
+
if not self.vault.is_expired(spec.name):
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
token = self.vault.get_token(spec.name)
|
|
67
|
+
if not token:
|
|
68
|
+
return
|
|
69
|
+
refresh_token = token.get("refresh_token")
|
|
70
|
+
if not refresh_token:
|
|
71
|
+
logger.warning(
|
|
72
|
+
f"Token for '{spec.name}' is expired and has no refresh_token. "
|
|
73
|
+
f"Reconnect required."
|
|
74
|
+
)
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
oauth2 = spec.auth.oauth2
|
|
78
|
+
if not oauth2:
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
client_id = token.get("client_id", "")
|
|
82
|
+
client_secret = token.get("client_secret", "")
|
|
83
|
+
logger.info(f"Refreshing token for '{spec.name}'...")
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
async with httpx.AsyncClient(timeout=15) as client:
|
|
87
|
+
body = {
|
|
88
|
+
"grant_type": "refresh_token",
|
|
89
|
+
"refresh_token": refresh_token,
|
|
90
|
+
"client_id": client_id,
|
|
91
|
+
}
|
|
92
|
+
if client_secret:
|
|
93
|
+
body["client_secret"] = client_secret
|
|
94
|
+
|
|
95
|
+
resp = await client.post(oauth2.token_url, data=body)
|
|
96
|
+
resp.raise_for_status()
|
|
97
|
+
new_token = resp.json()
|
|
98
|
+
|
|
99
|
+
# Preserve the refresh_token if the provider didn't issue a new one
|
|
100
|
+
if "refresh_token" not in new_token:
|
|
101
|
+
new_token["refresh_token"] = refresh_token
|
|
102
|
+
new_token["client_id"] = client_id
|
|
103
|
+
new_token["client_secret"] = client_secret
|
|
104
|
+
|
|
105
|
+
self.vault.store_token(spec.name, "oauth2", new_token)
|
|
106
|
+
logger.info(f"Token refreshed for '{spec.name}'")
|
|
107
|
+
except Exception as e:
|
|
108
|
+
logger.warning(
|
|
109
|
+
f"Failed to refresh token for '{spec.name}': {e}. "
|
|
110
|
+
f"Reconnect required."
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
async def refresh_all(self) -> None:
|
|
114
|
+
"""Refresh all connected OAuth2 tokens that are expired."""
|
|
115
|
+
for spec in self._specs:
|
|
116
|
+
if self.vault.is_connected(spec.name):
|
|
117
|
+
await self.try_refresh_token(spec)
|
|
118
|
+
|
|
119
|
+
def list_available(self) -> list[dict[str, Any]]:
|
|
120
|
+
connected = set(self.vault.list_connected())
|
|
121
|
+
return [
|
|
122
|
+
{
|
|
123
|
+
"name": s.name,
|
|
124
|
+
"display": s.display,
|
|
125
|
+
"icon": s.icon,
|
|
126
|
+
"category": s.category,
|
|
127
|
+
"description": s.description,
|
|
128
|
+
"setup_guide_url": s.setup_guide_url,
|
|
129
|
+
"connected": s.name in connected,
|
|
130
|
+
"auth_type": s.auth.type.value,
|
|
131
|
+
"required_fields": [
|
|
132
|
+
f.model_dump() for f in s.auth.required_fields
|
|
133
|
+
],
|
|
134
|
+
}
|
|
135
|
+
for s in self._specs
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
async def get_tools(self) -> list[dict[str, Any]]:
|
|
139
|
+
"""Discover tools for all connected connectors. Async — MCP servers are spawned per-spec."""
|
|
140
|
+
tools: list[dict[str, Any]] = []
|
|
141
|
+
|
|
142
|
+
for spec in self._specs:
|
|
143
|
+
if not self.vault.is_connected(spec.name):
|
|
144
|
+
continue
|
|
145
|
+
|
|
146
|
+
mcp_sources = spec.get_mcp_sources()
|
|
147
|
+
if mcp_sources:
|
|
148
|
+
try:
|
|
149
|
+
adapter_tools = await _discover_mcp_tools(spec, self.vault, self.user_id)
|
|
150
|
+
tools.extend(adapter_tools)
|
|
151
|
+
except Exception:
|
|
152
|
+
logger.warning(f"Failed to load MCP connector '{spec.name}'", exc_info=True)
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
adapter_tools = self._load_cli_connector(spec)
|
|
157
|
+
tools.extend(adapter_tools)
|
|
158
|
+
except Exception:
|
|
159
|
+
logger.warning(f"Failed to load connector '{spec.name}'", exc_info=True)
|
|
160
|
+
continue
|
|
161
|
+
|
|
162
|
+
return tools
|
|
163
|
+
|
|
164
|
+
def get_tools_sync(self) -> list[dict[str, Any]]:
|
|
165
|
+
"""Sync fallback — only discovers CLI tools. MCP sources are skipped."""
|
|
166
|
+
tools: list[dict[str, Any]] = []
|
|
167
|
+
for spec in self._specs:
|
|
168
|
+
if not self.vault.is_connected(spec.name):
|
|
169
|
+
continue
|
|
170
|
+
if spec.get_mcp_sources():
|
|
171
|
+
continue
|
|
172
|
+
try:
|
|
173
|
+
adapter_tools = self._load_cli_connector(spec)
|
|
174
|
+
tools.extend(adapter_tools)
|
|
175
|
+
except Exception:
|
|
176
|
+
continue
|
|
177
|
+
return tools
|
|
178
|
+
|
|
179
|
+
def _load_cli_connector(self, spec: ConnectorSpec) -> list[dict[str, Any]]:
|
|
180
|
+
namespace = spec.name.replace("-", "_")
|
|
181
|
+
all_tools: list[dict[str, Any]] = []
|
|
182
|
+
|
|
183
|
+
for source in spec.get_tool_sources():
|
|
184
|
+
try:
|
|
185
|
+
if source.type == ToolSourceType.CLI:
|
|
186
|
+
adapter = CLIAdapter(spec, self.vault, self.user_id)
|
|
187
|
+
if not adapter.is_available():
|
|
188
|
+
logger.warning(
|
|
189
|
+
f"CLI not available for {spec.name}. "
|
|
190
|
+
f"Install: {source.install}"
|
|
191
|
+
)
|
|
192
|
+
continue
|
|
193
|
+
all_tools.extend(adapter.discover_tools(namespace))
|
|
194
|
+
except Exception:
|
|
195
|
+
logger.warning(
|
|
196
|
+
f"Failed to load tool source '{source.type}' for '{spec.name}'",
|
|
197
|
+
exc_info=True,
|
|
198
|
+
)
|
|
199
|
+
continue
|
|
200
|
+
|
|
201
|
+
return all_tools
|
|
202
|
+
|
|
203
|
+
async def health(self) -> dict[str, Any]:
|
|
204
|
+
result: dict[str, Any] = {"status": "ok", "connectors": {}}
|
|
205
|
+
connected_count = 0
|
|
206
|
+
error_count = 0
|
|
207
|
+
|
|
208
|
+
for spec in self._specs:
|
|
209
|
+
if not self.vault.is_connected(spec.name):
|
|
210
|
+
result["connectors"][spec.name] = {"status": "not_connected"}
|
|
211
|
+
continue
|
|
212
|
+
|
|
213
|
+
connected_count += 1
|
|
214
|
+
try:
|
|
215
|
+
if spec.get_mcp_sources():
|
|
216
|
+
mcp_tools = await _discover_mcp_tools(spec, self.vault, self.user_id)
|
|
217
|
+
tools = mcp_tools
|
|
218
|
+
else:
|
|
219
|
+
tools = self._load_cli_connector(spec)
|
|
220
|
+
result["connectors"][spec.name] = {
|
|
221
|
+
"status": "ok",
|
|
222
|
+
"tools": len(tools),
|
|
223
|
+
}
|
|
224
|
+
except Exception as e:
|
|
225
|
+
error_count += 1
|
|
226
|
+
result["connectors"][spec.name] = {
|
|
227
|
+
"status": "error",
|
|
228
|
+
"error": str(e),
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if error_count > 0:
|
|
232
|
+
result["status"] = "broken" if error_count == connected_count else "partial"
|
|
233
|
+
|
|
234
|
+
return result
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _make_mcp_invoker(command: str, env: dict[str, str], tool_name: str):
|
|
238
|
+
"""Factory: returns async function that spawns MCP server, calls tool, returns result."""
|
|
239
|
+
async def ainvoke(**kwargs: Any) -> str:
|
|
240
|
+
from mcp import ClientSession, StdioServerParameters
|
|
241
|
+
from mcp.client.stdio import stdio_client
|
|
242
|
+
|
|
243
|
+
parts = command.split()
|
|
244
|
+
sp = StdioServerParameters(command=parts[0], args=parts[1:], env=env)
|
|
245
|
+
async with stdio_client(sp) as (read, write):
|
|
246
|
+
async with ClientSession(read, write) as session:
|
|
247
|
+
await session.initialize()
|
|
248
|
+
result = await session.call_tool(tool_name, arguments=kwargs)
|
|
249
|
+
return json.dumps(
|
|
250
|
+
{c.type: c.text for c in result.content}
|
|
251
|
+
)
|
|
252
|
+
return ainvoke
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
async def _discover_mcp_tools(
|
|
256
|
+
spec: ConnectorSpec, vault: CredentialVault, user_id: str
|
|
257
|
+
) -> list[dict[str, Any]]:
|
|
258
|
+
"""Spawn MCP server, list_tools(), convert to ConnectKit tool dicts."""
|
|
259
|
+
from mcp import ClientSession, StdioServerParameters
|
|
260
|
+
from mcp.client.stdio import stdio_client
|
|
261
|
+
|
|
262
|
+
adapter = MCPAdapter(spec, vault, user_id)
|
|
263
|
+
env = adapter.build_server_env()
|
|
264
|
+
namespace = spec.name.replace("-", "_")
|
|
265
|
+
parts = adapter.command.split()
|
|
266
|
+
server_params = StdioServerParameters(
|
|
267
|
+
command=parts[0], args=parts[1:], env=env
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
async with stdio_client(server_params) as (read, write):
|
|
271
|
+
async with ClientSession(read, write) as session:
|
|
272
|
+
await session.initialize()
|
|
273
|
+
result = await session.list_tools()
|
|
274
|
+
|
|
275
|
+
tools: list[dict[str, Any]] = []
|
|
276
|
+
for mcp_tool in result.tools:
|
|
277
|
+
input_schema = mcp_tool.inputSchema or {
|
|
278
|
+
"type": "object",
|
|
279
|
+
"properties": {},
|
|
280
|
+
}
|
|
281
|
+
tool_name = f"{namespace}__{mcp_tool.name}"
|
|
282
|
+
tools.append(
|
|
283
|
+
{
|
|
284
|
+
"name": tool_name,
|
|
285
|
+
"description": mcp_tool.description or "",
|
|
286
|
+
"parameters": input_schema,
|
|
287
|
+
"function": None,
|
|
288
|
+
"ainvoke": _make_mcp_invoker(
|
|
289
|
+
adapter.command, env, mcp_tool.name
|
|
290
|
+
),
|
|
291
|
+
"annotations": {
|
|
292
|
+
"read_only": False,
|
|
293
|
+
"destructive": False,
|
|
294
|
+
"idempotent": False,
|
|
295
|
+
"title": tool_name,
|
|
296
|
+
"mcp_server": adapter.server_name,
|
|
297
|
+
"_mcp_connector": spec.name,
|
|
298
|
+
},
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
return tools
|
|
302
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""CredentialVault — encrypted per-user token storage.
|
|
1
|
+
"""CredentialVault — encrypted per-user token storage with OAuth2 refresh.
|
|
2
2
|
|
|
3
3
|
Schema:
|
|
4
4
|
CREATE TABLE credentials (
|
|
@@ -6,7 +6,8 @@ Schema:
|
|
|
6
6
|
auth_type TEXT NOT NULL,
|
|
7
7
|
encrypted_data TEXT NOT NULL,
|
|
8
8
|
created_at TEXT NOT NULL,
|
|
9
|
-
updated_at TEXT NOT NULL
|
|
9
|
+
updated_at TEXT NOT NULL,
|
|
10
|
+
expires_at TEXT -- nullable; set when OAuth tokens have an expiry
|
|
10
11
|
);
|
|
11
12
|
|
|
12
13
|
CREATE TABLE oauth_states (
|
|
@@ -20,23 +21,42 @@ Schema:
|
|
|
20
21
|
"""
|
|
21
22
|
|
|
22
23
|
import json
|
|
24
|
+
import logging
|
|
23
25
|
import os
|
|
24
26
|
import secrets
|
|
25
27
|
import sqlite3
|
|
26
28
|
import threading
|
|
27
29
|
import warnings
|
|
28
|
-
from contextlib import contextmanager
|
|
29
30
|
from collections.abc import Generator
|
|
31
|
+
from contextlib import contextmanager
|
|
30
32
|
from datetime import UTC, datetime, timedelta
|
|
31
33
|
from pathlib import Path
|
|
34
|
+
from typing import Any
|
|
32
35
|
|
|
36
|
+
import httpx
|
|
33
37
|
from cryptography.fernet import Fernet
|
|
34
38
|
|
|
39
|
+
logger = logging.getLogger("connectkit.vault")
|
|
40
|
+
|
|
35
41
|
|
|
36
42
|
def _now_iso() -> str:
|
|
37
43
|
return datetime.now(UTC).isoformat()
|
|
38
44
|
|
|
39
45
|
|
|
46
|
+
def _parse_expiry(token_data: dict) -> str | None:
|
|
47
|
+
"""Extract ISO expiry string from token data (expires_in or expires_at)."""
|
|
48
|
+
expires_in = token_data.get("expires_in")
|
|
49
|
+
if expires_in:
|
|
50
|
+
expires_at = datetime.now(UTC) + timedelta(seconds=int(expires_in))
|
|
51
|
+
return expires_at.isoformat()
|
|
52
|
+
expires_at = token_data.get("expires_at")
|
|
53
|
+
if expires_at:
|
|
54
|
+
if isinstance(expires_at, (int, float)):
|
|
55
|
+
expires_at = datetime.fromtimestamp(expires_at, tz=UTC).isoformat()
|
|
56
|
+
return str(expires_at)
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
|
|
40
60
|
def _get_or_create_key() -> bytes:
|
|
41
61
|
import base64
|
|
42
62
|
import hashlib
|
|
@@ -91,7 +111,8 @@ class CredentialVault:
|
|
|
91
111
|
auth_type TEXT NOT NULL,
|
|
92
112
|
encrypted_data TEXT NOT NULL,
|
|
93
113
|
created_at TEXT NOT NULL,
|
|
94
|
-
updated_at TEXT NOT NULL
|
|
114
|
+
updated_at TEXT NOT NULL,
|
|
115
|
+
expires_at TEXT
|
|
95
116
|
)
|
|
96
117
|
""")
|
|
97
118
|
cur.execute("""
|
|
@@ -114,14 +135,15 @@ class CredentialVault:
|
|
|
114
135
|
def store_token(self, service_name: str, auth_type: str, token_data: dict) -> None:
|
|
115
136
|
now = _now_iso()
|
|
116
137
|
encrypted = self._encrypt(token_data)
|
|
138
|
+
expires_at = _parse_expiry(token_data)
|
|
117
139
|
with self._connect() as cur:
|
|
118
140
|
cur.execute(
|
|
119
141
|
"INSERT OR REPLACE INTO credentials "
|
|
120
|
-
"(service_name, auth_type, encrypted_data, created_at, updated_at) "
|
|
142
|
+
"(service_name, auth_type, encrypted_data, created_at, updated_at, expires_at) "
|
|
121
143
|
"VALUES (?, ?, ?, COALESCE(("
|
|
122
144
|
"SELECT created_at FROM credentials WHERE service_name = ?"
|
|
123
|
-
"), ?), ?)",
|
|
124
|
-
(service_name, auth_type, encrypted, service_name, now, now),
|
|
145
|
+
"), ?), ?, ?)",
|
|
146
|
+
(service_name, auth_type, encrypted, service_name, now, now, expires_at),
|
|
125
147
|
)
|
|
126
148
|
|
|
127
149
|
def get_token(self, service_name: str) -> dict | None:
|
|
@@ -135,6 +157,30 @@ class CredentialVault:
|
|
|
135
157
|
return None
|
|
136
158
|
return self._decrypt(row["encrypted_data"])
|
|
137
159
|
|
|
160
|
+
def get_token_with_expiry(self, service_name: str) -> tuple[dict | None, str | None]:
|
|
161
|
+
"""Return (token_data, expires_at_iso) or (None, None)."""
|
|
162
|
+
with self._connect() as cur:
|
|
163
|
+
cur.execute(
|
|
164
|
+
"SELECT encrypted_data, expires_at FROM credentials WHERE service_name = ?",
|
|
165
|
+
(service_name,),
|
|
166
|
+
)
|
|
167
|
+
row = cur.fetchone()
|
|
168
|
+
if not row:
|
|
169
|
+
return None, None
|
|
170
|
+
return self._decrypt(row["encrypted_data"]), row["expires_at"]
|
|
171
|
+
|
|
172
|
+
def is_expired(self, service_name: str) -> bool:
|
|
173
|
+
"""Check if a token is past its expiry threshold (30s buffer)."""
|
|
174
|
+
_, expires_at = self.get_token_with_expiry(service_name)
|
|
175
|
+
if not expires_at:
|
|
176
|
+
return False
|
|
177
|
+
try:
|
|
178
|
+
expires_dt = datetime.fromisoformat(expires_at)
|
|
179
|
+
# 30-second buffer to avoid racing expiry
|
|
180
|
+
return datetime.now(UTC) >= (expires_dt - timedelta(seconds=30))
|
|
181
|
+
except Exception:
|
|
182
|
+
return False
|
|
183
|
+
|
|
138
184
|
def delete_token(self, service_name: str) -> bool:
|
|
139
185
|
with self._connect() as cur:
|
|
140
186
|
cur.execute(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "connectkit"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.2"
|
|
4
4
|
description = "Connect AI agents to SaaS — one YAML file per service. OAuth, token vault, tool discovery."
|
|
5
5
|
requires-python = ">=3.11"
|
|
6
6
|
readme = "README.md"
|
|
@@ -27,6 +27,7 @@ dependencies = [
|
|
|
27
27
|
"cryptography>=41.0",
|
|
28
28
|
"httpx>=0.28",
|
|
29
29
|
"fastapi>=0.129",
|
|
30
|
+
"mcp>=1.0.0",
|
|
30
31
|
]
|
|
31
32
|
|
|
32
33
|
[project.optional-dependencies]
|
|
@@ -98,7 +98,6 @@ class TestInit:
|
|
|
98
98
|
_write_specs(spec_dir, [_make_cli_spec("github")])
|
|
99
99
|
|
|
100
100
|
rt = ConnectorRuntime(spec_dir, vault, "alice")
|
|
101
|
-
assert len(rt.get_specs()) == 1
|
|
102
101
|
|
|
103
102
|
_write_specs(spec_dir, [_make_cli_spec("github"), _make_cli_spec("slack")])
|
|
104
103
|
rt.reload()
|
|
@@ -134,15 +133,17 @@ class TestListAvailable:
|
|
|
134
133
|
|
|
135
134
|
|
|
136
135
|
class TestGetTools:
|
|
137
|
-
|
|
136
|
+
@pytest.mark.asyncio
|
|
137
|
+
async def test_returns_nothing_when_nothing_connected(self, temp_dir, vault):
|
|
138
138
|
spec_dir = Path(temp_dir) / "connectors"
|
|
139
139
|
_write_specs(spec_dir, [_make_cli_spec("github")])
|
|
140
140
|
|
|
141
141
|
rt = ConnectorRuntime(spec_dir, vault, "alice")
|
|
142
|
-
tools = rt.get_tools()
|
|
142
|
+
tools = await rt.get_tools()
|
|
143
143
|
assert tools == []
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
@pytest.mark.asyncio
|
|
146
|
+
async def test_returns_tools_for_connected_cli(self, temp_dir, vault):
|
|
146
147
|
spec_dir = Path(temp_dir) / "connectors"
|
|
147
148
|
_write_specs(spec_dir, [_make_cli_spec("github")])
|
|
148
149
|
|
|
@@ -152,27 +153,26 @@ class TestGetTools:
|
|
|
152
153
|
|
|
153
154
|
with patch("connectkit.backends.cli.CLIAdapter.list_commands",
|
|
154
155
|
return_value=["repo:list", "issue:create"]):
|
|
155
|
-
tools = rt.get_tools()
|
|
156
|
+
tools = await rt.get_tools()
|
|
156
157
|
|
|
157
158
|
assert len(tools) == 2
|
|
158
159
|
names = {t["name"] for t in tools}
|
|
159
160
|
assert "github__repo_list" in names
|
|
160
161
|
assert "github__issue_create" in names
|
|
161
162
|
|
|
162
|
-
|
|
163
|
+
@pytest.mark.asyncio
|
|
164
|
+
async def test_skips_mcp_without_token(self, temp_dir, vault):
|
|
165
|
+
"""MCP source without a stored token should be skipped (not connected)."""
|
|
163
166
|
spec_dir = Path(temp_dir) / "connectors"
|
|
164
167
|
_write_specs(spec_dir, [_make_mcp_spec("dropbox")])
|
|
165
168
|
|
|
166
|
-
vault.store_token("dropbox", "oauth2", {"access_token": "sl.123"})
|
|
167
|
-
|
|
168
169
|
rt = ConnectorRuntime(spec_dir, vault, "alice")
|
|
169
|
-
tools = rt.get_tools()
|
|
170
|
+
tools = await rt.get_tools()
|
|
170
171
|
|
|
171
|
-
assert
|
|
172
|
-
assert tools[0]["name"] == "dropbox__mcp_status"
|
|
173
|
-
assert tools[0]["_is_mcp_placeholder"] is True
|
|
172
|
+
assert tools == [] # not connected, so skipped
|
|
174
173
|
|
|
175
|
-
|
|
174
|
+
@pytest.mark.asyncio
|
|
175
|
+
async def test_skips_broken_connector(self, temp_dir, vault):
|
|
176
176
|
spec_dir = Path(temp_dir) / "connectors"
|
|
177
177
|
_write_specs(spec_dir, [_make_cli_spec("github"), _make_cli_spec("slack")])
|
|
178
178
|
|
|
@@ -181,8 +181,7 @@ class TestGetTools:
|
|
|
181
181
|
|
|
182
182
|
rt = ConnectorRuntime(spec_dir, vault, "alice")
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
original_load = rt._load_connector
|
|
184
|
+
original_load = rt._load_cli_connector
|
|
186
185
|
|
|
187
186
|
call_count = 0
|
|
188
187
|
|
|
@@ -193,30 +192,31 @@ class TestGetTools:
|
|
|
193
192
|
raise RuntimeError("Slack adapter crash")
|
|
194
193
|
return original_load(spec)
|
|
195
194
|
|
|
196
|
-
with patch.object(rt, "
|
|
197
|
-
tools = rt.get_tools()
|
|
195
|
+
with patch.object(rt, "_load_cli_connector", side_effect=mock_load):
|
|
196
|
+
tools = await rt.get_tools()
|
|
198
197
|
|
|
199
|
-
# Should return github tools only, not crash
|
|
200
198
|
assert len(tools) >= 0
|
|
201
199
|
|
|
202
200
|
|
|
203
201
|
class TestHealth:
|
|
204
|
-
|
|
202
|
+
@pytest.mark.asyncio
|
|
203
|
+
async def test_all_not_connected(self, temp_dir, vault):
|
|
205
204
|
spec_dir = Path(temp_dir) / "connectors"
|
|
206
205
|
_write_specs(spec_dir, [_make_cli_spec("github")])
|
|
207
206
|
|
|
208
207
|
rt = ConnectorRuntime(spec_dir, vault, "alice")
|
|
209
|
-
h = rt.health()
|
|
208
|
+
h = await rt.health()
|
|
210
209
|
assert h["status"] == "ok"
|
|
211
210
|
assert h["connectors"]["github"]["status"] == "not_connected"
|
|
212
211
|
|
|
213
|
-
|
|
212
|
+
@pytest.mark.asyncio
|
|
213
|
+
async def test_connected_ok(self, temp_dir, vault):
|
|
214
214
|
spec_dir = Path(temp_dir) / "connectors"
|
|
215
215
|
_write_specs(spec_dir, [_make_cli_spec("github")])
|
|
216
216
|
|
|
217
217
|
vault.store_token("github", "api_key", {"api_key": "ghp_123"})
|
|
218
218
|
|
|
219
219
|
rt = ConnectorRuntime(spec_dir, vault, "alice")
|
|
220
|
-
h = rt.health()
|
|
220
|
+
h = await rt.health()
|
|
221
221
|
assert h["connectors"]["github"]["status"] == "ok"
|
|
222
|
-
assert h["connectors"]["github"]["tools"] >= 0
|
|
222
|
+
assert h["connectors"]["github"]["tools"] >= 0
|