{"service":"nordnai-mcp","version":"0.1.1079","status":"ready","protocol":"Model Context Protocol","transport":"streamable-http","endpoint":"https://mcp.nordn.ai/mcp","tools":["nordnai_list_countries","nordnai_search_companies","nordnai_get_company","nordnai_get_company_section","nordnai_search_domains","nordnai_get_domain","nordnai_get_domain_section","nordnai_search_persons","nordnai_get_person","nordnai_get_person_section","nordnai_list_changes","nordnai_get_core_model","nordnai_list_fields"],"core_model":{"schema":"nordnai_leads_core_model_v1","canonical_truths":[{"key":"companies","label":"Companies","table":"companies","owns":"One legal entity row.","collects":["register identity, status and legal form","addresses, industry, size and country","website and company contact channels","source attribution and normal business metadata"]},{"key":"domains","label":"Domains","table":"domains","owns":"One independent domain inventory row.","collects":["domain name, status and crawlability","website content summary and metadata","tech stack, language and last crawl state","source attribution for discovered ownership evidence"]},{"key":"persons","label":"Persons","table":"persons","owns":"One business-context person row.","collects":["name, role or title","email, phone and LinkedIn","source provenance and confidence","business context through company or domain links"]}],"relationship_links":[{"table":"domain_company_links","from":"domains","to":"companies","rule":"Only truth for company-domain ownership. A domain can exist without a company link."},{"table":"company_people","from":"companies","to":"persons","rule":"Only direct company-person link. Relationship context lives here, not duplicate person facts."},{"table":"domain_contacts","from":"domains","to":"persons","rule":"Only domain-person link. Crawler-discovered people can attach to a domain before a company is proven."}],"relationship_map":{"title":"Company-domain-person relationship map","summary":"Companies, domains and persons are independent entity truths. The three link tables attach them without copying facts.","nodes":[{"id":"companies","label":"Companies","kind":"canonical_truth","owns":"Legal entity and normal company facts."},{"id":"domains","label":"Domains","kind":"canonical_truth","owns":"Independent website/domain inventory."},{"id":"persons","label":"Persons","kind":"canonical_truth","owns":"Named employee facts and direct contact channels."},{"id":"domain_company_links","label":"domain_company_links","kind":"relationship_context","owns":"Company-domain ownership or attribution proof."},{"id":"company_people","label":"company_people","kind":"relationship_context","owns":"Direct company-person role/context proof."},{"id":"domain_contacts","label":"domain_contacts","kind":"relationship_context","owns":"Domain-person context where the person was found."}],"edges":[{"from":"domains","via":"domain_company_links","to":"companies","label":"domain belongs to company","rule":"A domain can exist before this link is proven."},{"from":"companies","via":"company_people","to":"persons","label":"person works for company","rule":"Use only for direct company-person proof."},{"from":"domains","via":"domain_contacts","to":"persons","label":"person found on domain","rule":"Crawler can attach person to domain before company attribution is proven."}],"derivedViews":[{"view":"company profile people","derivesFrom":["company_people","domain_company_links","domain_contacts","persons"],"rule":"A company can show direct company_people plus people linked through its domains."},{"view":"domain profile company","derivesFrom":["domain_company_links","companies"],"rule":"A domain profile shows company context only when a link exists."},{"view":"person profile context","derivesFrom":["persons","company_people","domain_contacts","domain_company_links"],"rule":"A person is returned only with business/domain context, never as a standalone private person."}]},"structure_hierarchy":[{"layer":"Canonical truths","purpose":"The only durable business entities in leads.","nodes":["companies","domains","persons"],"rule":"Every collected business fact must belong to exactly one of these entities or be derived from their links."},{"layer":"Relationship context","purpose":"Small link tables that attach entities without copying their facts.","nodes":["domain_company_links","company_people","domain_contacts"],"rule":"Links may store proof, role/context and source metadata, but never duplicate person contact facts."},{"layer":"Entity facts","purpose":"Concrete, source-backed facts under one canonical entity.","nodes":["company register/contact facts","domain crawl/content/tech facts","person role/contact/provenance facts"],"rule":"Prefer normal register, domain, content, tech, email, phone and employee data; reject broad enrichment by default."},{"layer":"Read models and API","purpose":"Rebuildable projections for search, summaries, sections, OpenAPI and MCP.","nodes":["api.company_*","api.domain_*","api.person_*","api.field_manifest"],"rule":"API/MCP output is derived from canonical entities, links and field provenance; it is not a fourth truth."},{"layer":"Control metadata","purpose":"Source, worker, budget, audit, quality, translation and backup evidence.","nodes":["source catalog","worker/budget/run controls","audit, quality and translation metadata"],"rule":"Control metadata explains how data was collected and operated; it must not become product-facing enrichment noise."}],"collection_priorities":[{"priority":"P0","label":"People contact reachability","owner":"persons + company_people/domain_contacts","collects":["named employees","role or title","email","phone","LinkedIn"],"rule":"Highest lead value. Store the person once, then link the person to the proven company or source domain."},{"priority":"P0","label":"Company contact channels","owner":"companies","collects":["switchboard phone","sales/support email","mobile","website"],"rule":"Keep generic company channels on companies when they are not tied to a named person."},{"priority":"P1","label":"Domain and website intelligence","owner":"domains + domain_* facts","collects":["domain status","crawlability","content summary","language","tech stack"],"rule":"Domains are independent inventory. They can be discovered and crawled before company ownership is proven."},{"priority":"P1","label":"Normal company facts","owner":"companies + company_* facts","collects":["register status","addresses","industry","size","legal form"],"rule":"Keep concrete register and operational company facts that help identify and filter B2B leads."},{"priority":"P2","label":"Evidence, quality and translations","owner":"control metadata + read models","collects":["source provenance","confidence","field history","native text","English text"],"rule":"Use this data to prove and expose the core facts. Do not turn control metadata into a fourth business truth."}],"contact_field_ownership":[{"owner":"Company generic channels","table":"companies","fields":["email","phone","mobile","website"],"rule":"Only store company-level channels here, such as switchboard, reception, support, sales or register-provided contacts. Do not put named employee contact values on companies."},{"owner":"Person direct channels","table":"persons","fields":["primary_email","phone","linkedin_url"],"rule":"Store named employee contact values only once on persons, with source provenance and business context through company_people or domain_contacts."},{"owner":"Company-person context","table":"company_people","fields":["role_code","role_label","title","is_primary_contact"],"rule":"Store relationship context only. Never copy person email, phone, LinkedIn or name into company_people."},{"owner":"Domain-person context","table":"domain_contacts","fields":["department","title","source_page","confidence"],"rule":"Attach a person to the domain where the evidence was found. Never copy person email, phone, LinkedIn or name into domain_contacts."},{"owner":"Domain website facts","table":"domains","fields":["domain","title","description","language","status"],"rule":"Store website/domain facts here. A domain can show contact evidence before company ownership is proven, but named contact values still belong on persons."}],"source_decision_policy":[{"decision":"Keep active core source","appliesWhen":"The source is official, legal/free or approved, no-secret or properly credentialed, and fills companies, domains, persons or required control metadata.","requiredEvidence":["explicit source_catalog and activation manifest decision","storage target under the three-truth model","dry-run or cadence proof","DB placement, entity change-log and API projection proof before promotion"]},{"decision":"Ready paused","appliesWhen":"The connector is technically ready, but import/crawl/data loading still waits for exact Robert approval.","requiredEvidence":["safe_to_run status is explainable","operator next action says keep paused","no manual /run, Workflow ingestion, provider volume, Domain Finder or Web Crawl has started"]},{"decision":"Drop from scope","appliesWhen":"The source is high-cost, low-value, broad enrichment, legally unclear, hard to maintain or does not directly improve company/domain/person lead value.","requiredEvidence":["disabled source metadata or physical purge when irrelevant/rebuildable","worker cron/budget/admin references removed or parked fail-closed","docs and audits explain that the source is not active product truth"]},{"decision":"Reject no execution","appliesWhen":"The source has paid/illegal/unclear access, unsafe person data, weak rights or no machine-readable contract.","requiredEvidence":["enabled=false and safe_to_run=false","no source fetch, dry-run, sample-write or raw payload persisted","future use requires a new legal/source/API contract decision"]},{"decision":"Reopen later only by new product decision","appliesWhen":"A removed or parked source becomes valuable enough to reconsider.","requiredEvidence":["new schema/API target under companies, domains or persons","country/legal/privacy readiness","budget and worker ownership","redacted canary proof before any broad run"]}],"field_placement":[{"evidence":"Named employee identity and direct channels","writeTarget":"persons","fields":["full_name","first_name","last_name","primary_email","phone","linkedin_url"],"linkContext":"company_people or domain_contacts required","rule":"Store named employees once. Never copy direct person contacts to companies, domains or link tables."},{"evidence":"Company-person employment proof","writeTarget":"company_people","fields":["company_id","person_id","role_code","role_label","title","is_primary_contact"],"linkContext":"companies + persons","rule":"Relationship only. No person name, email, phone or LinkedIn copy belongs here."},{"evidence":"Domain-person discovery proof","writeTarget":"domain_contacts","fields":["domain_id","person_id","department","title","source_page","confidence"],"linkContext":"domains + persons","rule":"Attach crawler-found people to the source domain. Company relation is derived when domain_company_links exists. Never copy person email, phone, LinkedIn or name into domain_contacts."},{"evidence":"Generic company contact channel","writeTarget":"companies","fields":["email","phone","mobile","website","linkedin_url"],"linkContext":"none unless ownership evidence exists","rule":"Only switchboard, sales, support, register or B2B company profile channels. Named people still go to persons."},{"evidence":"Website company profile facts","writeTarget":"companies + company_translations","fields":["description","employee_range","description@en"],"linkContext":"company_id + source_url","rule":"Store concise source-language company descriptions on companies and English display translations separately. Do not collect slogans, inferred customer segments, deep product catalogs or broad profile arrays."},{"evidence":"Domain identity and crawl state","writeTarget":"domains","fields":["domain","status","http_status","language","title","description","last_crawled_at"],"linkContext":"domain_company_links optional","rule":"Domain can be stored before company ownership is proven."},{"evidence":"Website metadata and tech stack","writeTarget":"domain_meta + domain_tech_stack","fields":["page_title","meta_description","language_detected","cms_platform","hosting_provider","analytics_platforms"],"linkContext":"domain_id","rule":"Content metadata and technology belong to the domain, not the company."},{"evidence":"Register company facts and locations","writeTarget":"companies + company_locations/company_brreg_details + company_translations","fields":["org_nr","company_name","country","org_form_code","nace_code","street_address","purpose_text","activity_text","purpose_text@en","activity_text@en"],"linkContext":"source_code + country","rule":"Official register facts identify and filter companies. Do not create person rows unless named business people are present."}],"crawler_write_flow":[{"step":"Domain found","writeTarget":"domains","rule":"Upsert the domain as an independent inventory row even when no company is proven yet."},{"step":"Company ownership proven","writeTarget":"domain_company_links","rule":"Attach company-domain ownership only through the link table; do not store company ownership on domains as extra truth."},{"step":"Person found on a domain","writeTarget":"persons + domain_contacts","rule":"Upsert the person once in persons with role/title, email, phone, LinkedIn and provenance, then attach the person to the domain through domain_contacts."},{"step":"Person-company proof found","writeTarget":"company_people","rule":"Add the direct company-person link only when there is explicit proof. Do not duplicate person contact values in the link."},{"step":"Company profile display","writeTarget":"API/read model","rule":"Show people from direct company_people plus persons linked through the company domains, derived from canonical links."}],"invariants":["Person name, role/title, email, phone and LinkedIn live only on persons.","Companies do not store their own person rows; they link to persons.","Domains do not require a company link before they can exist.","No private person is stored without company or domain context.","API, MCP, crawler and admin must explain the same company-domain-person model."],"language_rules":["Native/source-country language is preserved for crawl/import business fields.","Language-dependent business/display fields also get an English version.","English never overwrites native/source values.","Identifiers, addresses, phones, emails, domains, codes, hashes, timestamps and raw evidence are not translated."],"out_of_scope":["awards, patents and broad IP history","property, vehicles and physical asset catalogs","deep product catalogs and random media/social/news feeds","traffic, backlink and SEO-history datasets","grant, tender or legal side-fields unless a new source-backed product decision reopens them"],"read_model_policy":"API, SDK and MCP payloads are derived from canonical entities and links; they are not a fourth truth."},"canonical_api":"https://api.nordn.ai/v1","auth":{"type":"bearer","header":"Authorization: Bearer <nordn_api_key>","metadata":"https://mcp.nordn.ai/.well-known/oauth-protected-resource"}}