Skip to main content
This guide takes an internal system from “reachable by us” to “callable by our agents, governed”. The reference for each piece is on the Organizations, Policies, Audit Log and Data Plane pages.

Prerequisites

  • An organization you own or administer. Members can use internal tools; only owners and admins register them.
  • For a system that is only reachable inside your network, an owner on the Team or Enterprise plan: enrolling a data-plane agent is an entitlement of the organization owner’s plan and answers 402 otherwise.
  • Something to register: an OpenAPI 3.x document (a URL or the file), a remote MCP server, or a list of HTTP endpoints you can describe as a connector.

1. Choose reachability

Both are visible to every member of the organization and nobody else. local_only covers HTTP services and remote MCP servers (streamable HTTP or SSE); the agent connects to the server, discovers its tools and makes every call, and Danube never reaches it. A local (stdio) MCP server cannot be registered for an organization at all. See MCP servers for the transports and the credential format. A database or warehouse (Postgres, Redshift, MySQL, Snowflake, BigQuery, Databricks, ClickHouse, Trino) is registered as local_only too, with source: database: each read-only query template becomes a tool, the connection string stays behind an env:// or vault:// reference the agent resolves, and the agent image is built with the drivers you need. Connect a Warehouse covers the reference forms, the read-only role per engine and the errors.

2. Register

1

Open Create Tools

Go to Dashboard > Tools > Create Tools. For a spec-less HTTP service use the Connector Builder instead; it has the same owner and visibility controls.
2

Set the owner and the visibility

Owner: the organization. Visibility: Internal or Runs inside your network.
3

Point it at the source

An OpenAPI URL, an uploaded OpenAPI document, or a remote MCP server URL. A document without a servers entry needs a base URL.
4

Preview import

The preview is a dry run: it parses everything, writes nothing and lists every tool it would create, each marked create or update, with any parse errors verbatim. Fix what it reports, then create.
The same registration over the API, owner or admin, with a session token or an API key:
source is openapi_url, openapi_spec (the document itself, as an object or JSON / YAML text, with spec_filename if you have one), mcp ({"mcp": {"server_url": "https://...", "transport": "http", "auth_type": "bearer"}}; name is required) or connector ({"connector": {...}}, a connector spec). Run it once with "dry_run": true, read the tools and errors it returns, then repeat without dry_run. The real registration answers with the service, tool_count, tools_failed, sync (running for an MCP server whose tools are being discovered in the background) and warnings. Limits: a document of at most 5,000,000 bytes and 500 operations. The service now appears on the Tools page, on the tab named after your organization, with an Internal or In your network badge, and in every member’s search results. GET /v1/organizations/{org_id}/services lists it for the API.

3. Give people access

With no grants, every member of the organization can use the new tools. To narrow that, go to Policies:
  • The first grant flips the organization to deny-by-default, for every internal tool at once, not only this one. Create the allows you need in the same sitting. The public catalog stays open to members whatever you allow; a deny on a catalog service or tool is the one grant that reaches it.
  • Allow a team the whole service, then deny the organization the one or two tools that should stay out of reach; a deny always wins. Teams are created and staffed under Teams on the Organization page.
  • Owners and admins keep access without a grant; only an explicit deny reaches them.
  • A member who is not granted a tool does not see it in search or in the service’s tool list, and a call to it answers 403 Your organization does not have access to this tool. When an agent reports that message, the fix is a grant from an admin, not a retry.

4. Credentials

An internal service usually authenticates with one key the company holds. Store it once for the organization, and every member who has no credential of their own for the service uses it:
Or open the service page, add the credential and choose the organization in the form. A member who stores a personal credential for the same service overrides the shared one for their own calls. OAuth connections are always personal. The shared credential is listed under Shared credentials on the Organization page with who stored it and when; its value is never shown again. For a local_only service the value must not be a value at all: store a reference that the agent resolves inside your network, env://VAR_NAME for an environment variable on the agent’s host or vault://<mount>/<path>#<field> for HashiCorp Vault. A credential held only as a value in Danube is never shipped to the agent; the call fails with credential_reference_unresolved.

Choosing an authentication method

A connector names its method in the spec and takes the secret as a credential. Pick by what the system checks on the wire: a static key or token it issued you is api_key, bearer or basic; an AWS service, or anything fronted by API Gateway with IAM authorization, is aws_sigv4 with the service’s signing name (s3, athena, redshift-data, lambda, execute-api) and region; an API that expects a token from your identity provider, an Okta or Entra application, a Google service account, or an Auth0 tenant, is oauth2_client_credentials with the provider’s token URL and the scope or audience it requires; a service that authenticates the client certificate on the TLS handshake is mtls, with the certificate and key pasted as PEM. The credential form asks for exactly the fields the method reads, and on the data plane each of them is an env:// or vault:// reference, the same as any other secret.

5. Verify

  1. Test run. Open the service on the Tools page and run one read-only tool, or over the API POST /v1/tools/call/{tool_id} with {"tool_input": {...}} from a member’s key. A local_only tool needs an agent online: the Data Plane page shows each agent’s Online badge and version.
  2. Audit log. Open Audit Log and filter by the tool. You should see the service.create row from the registration and one tool.execute row per test call, with the key that made it and a hash of the parameters. A tool.denied row with org_policy:no_grant means step 3 is missing an allow.
  3. A second member. Have someone with the member role search for the tool. Seeing it confirms visibility and the grants; not seeing it, when the organization has grants, means they are not granted.

6. Operate

Troubleshooting

Registration errors, from POST /v1/organizations/{org_id}/services and the dashboard’s preview: Execution errors, in the error_type of a failed call: And the two refusals that come back as an HTTP status: 403 Your organization does not have access to this tool (no grant, or an explicit deny; ask an admin for a grant) and 404 Tool not found for someone outside the organization, which is deliberate so an internal tool’s existence is not revealed.