Publish a tool
Add sign-in to your MCP server, then publish it for other companies.
Start with our SDK
Install our SDK. Wrap your MCP server. Every request now comes with the signed-in person.
npm install @closedmcp/sdk @modelcontextprotocol/sdkimport { McpServer } from
"@modelcontextprotocol/sdk/server/mcp.js";
import {
closedMcpPerson,
serveWithClosedMcp,
} from "@closedmcp/sdk";
serveWithClosedMcp(() => {
const mcp = new McpServer({
name: "hello", version: "1.0.0",
});
mcp.registerTool("hello", { inputSchema: {} },
async () => ({ content: [{
type: "text",
text: `Hello ${closedMcpPerson().email}`,
}] }));
return mcp;
}, {
resource: "https://example.com/mcp",
allowedDomains: ["example.com"],
});Each request has a pass that identifies the signed-in person. The SDK checks the pass. Your tool decides what that person can do.
The 3 steps
- Wrap your server. Install the SDK above and set your public MCP URL and customer domains.
- Use the person in each tool. Read their email and company from the SDK’s person helper.
- Add your MCP URL in ClosedMCP. Open Add an MCP. Other companies can then install your tool.
See the complete SDK server example for a runnable Node.js server.
What a pass contains
A tool identity token is a JWT signed with Ed25519 (alg: EdDSA). Its kid names the key in the public key set.
isshttps://closedmcp.com. The same for every company.aud- The server this token is for. Must match your MCP server URL (
resource). sub- The person’s stable ClosedMCP id.
email- The person’s work email.
domain- Their company’s domain, confirmed by Google Workspace at sign-in (Google’s
hdequals it). org- Their company’s ClosedMCP workspace.
client- The AI app they use, like
Claude, when known. The app names itself, so show it but don’t rely on it for security. iat,exp- When it was made and when it expires: 5 minutes at most.
jti- A unique id for this token.
| Field | What it means |
|---|---|
iss | https://closedmcp.com. The same for every company. |
aud | The server this token is for. Must match your MCP server URL (resource). |
sub | The person’s stable ClosedMCP id. |
email | The person’s work email. |
domain | Their company’s domain, confirmed by Google Workspace at sign-in (Google’s hd equals it). |
org | Their company’s ClosedMCP workspace. |
client | The AI app they use, like Claude, when known. The app names itself, so show it but don’t rely on it for security. |
iat, exp | When it was made and when it expires: 5 minutes at most. |
jti | A unique id for this token. |
ClosedMCP makes a fresh tool identity token for every call. It never sends your MCP server the person’s ClosedMCP key or their Google tokens. Your server receives only the tool identity token.
Rules your server must follow
- Check every request. The SDK verifies the signature, issuer, audience, and expiry. It refuses missing or invalid passes.
- Accept only your customers. Set
ALLOWED_DOMAINSto the company domains you serve. A valid pass identifies a person; it does not make them your customer. - Check what each person may do. Use their
suboremailfor permissions in your service. - Do not store passes or send them elsewhere.
AI apps that connect directly
AI apps discover ClosedMCP through your server’s sign-in metadata. The SDK serves that metadata and verifies each pass they send.
Publish in three steps
- 1
Wrap your server with the SDK above
Each request now has a signed-in person. - 2
Add your tool link
- 3
What happens next
Your admin reviews it if needed. Once approved, other companies can install it in one click.
Other companies can install your tool. They cannot use your company’s accounts. If everyone uses the same company account, you can share the tool only with your team.
Manage your tool
Who can make changes?
Admins and the person who added the tool can manage it. Removing a public tool also removes it for companies that installed it.