concinno-skills-crm
CRM agent skills for Concinno —
HubSpot + Salesforce. Databricks 2026 State of AI Agents places
customer experience (~40 % of enterprise use cases) at the top of the
agent workload pile; CRM is the system-of-record, so it is the first
ecosystem we ship after concinno-skills-chat and
concinno-skills-google.
Status
MVP (0.1.0) — four tools, two ecosystems:
| Tool class | Platform | Underlying SDK | SDK licence |
|---|---|---|---|
HubSpotContact |
HubSpot | hubspot-api-client |
Apache-2.0 |
HubSpotDeal |
HubSpot | hubspot-api-client |
Apache-2.0 |
SalesforceQuery |
Salesforce | simple-salesforce |
Apache-2.0 |
SalesforceUpsert |
Salesforce | simple-salesforce |
Apache-2.0 |
Pipedrive / Zoho / Microsoft Dynamics are deferred to 0.2.x until a maintained Python SDK with a permissive licence is proven stable.
Install
pip install concinno-skills-crm
Both SDKs are hard dependencies and pulled in automatically.
Credentials
Tokens live under well-known keys in the Concinno CredentialStore,
which reads (in order):
- Runtime overrides via
CredentialStore.set(...). - Env var
CONCINNO_CRED_<UPPER_KEY>. ~/.concinno/credentials.json.
HubSpot
| Key | Env var |
|---|---|
hubspot_access_token |
CONCINNO_CRED_HUBSPOT_ACCESS_TOKEN |
Produce the token via HubSpot → Settings → Integrations → Private Apps (or an OAuth install if you run a marketplace app).
Salesforce
Two auth flows are supported. Provide one set of keys:
Password + security token flow:
| Key | Env var |
|---|---|
salesforce_username |
CONCINNO_CRED_SALESFORCE_USERNAME |
salesforce_password |
CONCINNO_CRED_SALESFORCE_PASSWORD |
salesforce_security_token |
CONCINNO_CRED_SALESFORCE_SECURITY_TOKEN |
Session-id flow (when you already hold a bearer session):
| Key | Env var |
|---|---|
salesforce_session_id |
CONCINNO_CRED_SALESFORCE_SESSION_ID |
salesforce_instance_url |
CONCINNO_CRED_SALESFORCE_INSTANCE_URL |
Optional for both flows: salesforce_domain — set to "test" for a
sandbox org, default is "login".
Example ~/.concinno/credentials.json:
{
"hubspot_access_token": "pat-na1-...",
"salesforce_username": "me@example.com",
"salesforce_password": "secret",
"salesforce_security_token": "abcdef",
"salesforce_domain": "login"
}
Missing credentials return {"error": "no <service> credentials — set via CredentialStore / env ..."} rather than crashing.
Usage via Concinno ToolRegistry
When the consumer sets CONCINNO_LOAD_PLUGINS=1, the default registry
auto-mounts every CRM tool:
import os
os.environ["CONCINNO_LOAD_PLUGINS"] = "1"
from concinno.tools.registry import get_default_registry
reg = get_default_registry()
assert {
"HubSpotContact",
"HubSpotDeal",
"SalesforceQuery",
"SalesforceUpsert",
} <= set(reg.list_deferred())
Direct Python usage
from concinno_skills_crm import (
HubSpotContact,
HubSpotDeal,
SalesforceQuery,
SalesforceUpsert,
)
HubSpotContact().call(
action="create",
properties={"email": "a@b.com", "firstname": "A"},
)
HubSpotDeal().call(action="list", limit=50)
SalesforceQuery().call(
action="soql",
query="SELECT Id, Name FROM Account LIMIT 5",
)
SalesforceUpsert().call(
action="upsert",
sobject="Account",
external_id_field="External_Id__c",
external_id="X123",
data={"Name": "Acme"},
)
All tools return {"ok": True, ...} (or {"results": [...]} for
list) on success and {"error": "..."} on failure — same shape as
every other Concinno built-in tool. No exceptions escape call().
Concurrency
All four tools set is_concurrency_safe = False. CRM clients hold
session + rate-limit state, and serial calls are the sane default for
HubSpot's per-account budget and Salesforce's API limits (typically
15k / 24h / org per free tier).
Safety notes
SalesforceQuery.soqlforwards the query string verbatim but warn-logs when a DML verb (UPDATE/DELETE/INSERT/UPSERT/MERGE) leads the string — SFDC's/queryendpoint will reject it, this is purely triage help.listactions cap the page size at 100 (HubSpot) / 1000 (defensive). Larger pulls belong in a 0.2.xlist_allaction with explicit pagination.
License
Apache-2.0.
Metadata
Release files for concinno-skills-crm 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| concinno_skills_crm-0.1.0.tar.gz | 42.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| concinno_skills_crm-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 60.7 kB
Release files / concinno_skills_crm-0.1.0.tar.gz
| Download URL | concinno_skills_crm-0.1.0.tar.gz |
|---|---|
| Size | 42.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
516adca6dcf71bcd90cfc4e47778a6ad3458ea1a7c8adfe5d2aaa962dce7fcad
|
|
BLAKE2b-256 checksum How to use checksums |
830ec232d9e52e58086ebde81ed0f1005b520f8c35e00693db1fd4fffb2f8052
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / concinno_skills_crm-0.1.0-py3-none-any.whl
| Download URL | concinno_skills_crm-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
61c535e9cbc1341534797cb2b67c6a9ca0f55f1154f57881c56b2eb3cdf81ba2
|
|
BLAKE2b-256 checksum How to use checksums |
cbe87520b29f43c4aa81ec04bfd48229c25d0342f5d2e5f654dc96d8b14ad968
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|