Integrations
Lock an MCP server to a package
Official Kody doc
A connected MCP server is a live connector. Every discovered tool becomes
kody.mcp["server-name"].tool_name(...) for execute and every package.
That is often wider than the job. Lock the server to a package so only that
published surface can call it.
This is the MCP counterpart to
Gmail drafts without send. OAuth tokens stay as wide
as the provider issued them; a publish lock holds a package tree. An MCP server
lock holds who may call the connector. Integration connections use the same
tighten-only grant via
resourceLock({ kind: 'integration', name, package_id }).
What the lock does
Usage on the saved server (usage_mode on mcp_server_settings):
- Any context (default) — execute and every package can call
kody.mcp["name"]. - Specific packages — only the listed saved package ids can call it. Ad hoc execute is denied. Other packages are denied.
Tokens stay in the per-user MCP client hub. Disable still hides tools for everyone; lock leaves the connection up and narrows who may use it.
resourceLock({ kind: 'mcp_server', server, package_id }) switches the server
to packages mode and adds that package id. Additional grants accumulate.
Unlocking or removing a grant is website-only at
/@<slug>/-/mcp-servers/:serverId.
The loop
- Connect the server. Follow
Connect remote MCP servers (
mcpServerAdd, authorize if needed). Confirm tools withmcpServerList. - Name the grant. "This package may call these tools. Execute may not."
Write that in README
## Intentand in the export JSDoc Purpose. - Save a thin wrapper package. Follow
package_authoring. Give it its own package name leaf. The export callskody.mcp["server-name"]for the allowed tools only. Do not re-export the whole server. - Publish, then lock. After the first successful publish, call
resourceLock({ kind: 'mcp_server', server, package_id })with the server id or name and the savedpackage_id(or set Usage on/@<slug>/-/mcp-servers/:serverId). Say so in chat so the owner knows unlock is a website click. - Smoke-test from the package, not execute. Invoke the named export. A
later
executethat callskody.mcp["server-name"]should fail with the account URL.
Later grants
resourceLock({ kind: 'mcp_server', server, package_id }) with another
package_id adds that package. It does not unlock. The owner removes a grant or
returns the server to any context on the account page.
If a package needs the lock off, send the owner to
/@<slug>/-/mcp-servers/:serverId. Do not invent an unlock capability.
When to load this guide
Load locked_mcp_server when someone wants a connected MCP server that execute
must not call, when a home or third-party MCP is coarser than the intended
package, or when they ask how MCP usage compares to publish lock or
resourceLock({ kind: 'integration', name, package_id }). For connecting the
server, load the usage page and
local_mcp_tunnels for home LAN servers. For holding a published tree still,
load locked_gmail_drafts and
Packages → Publish lock (raw).