@thecorporation/mcp-server 26.3.9 → 26.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,7 +39,40 @@ claude mcp add thecorporation -- npx -y @thecorporation/mcp-server
39
39
 
40
40
  ## Authentication
41
41
 
42
- On first run, the server automatically provisions a workspace and saves credentials to `~/.corp/config.json`. To use an existing workspace, set environment variables:
42
+ The MCP server shares credentials with the CLI. Authenticate once, use everywhere.
43
+
44
+ ### Option 1: Authenticate via CLI (recommended)
45
+
46
+ ```bash
47
+ npx @thecorporation/cli setup
48
+ ```
49
+
50
+ This sends a magic link to your email. Click the link, paste the code into the terminal, and your credentials are saved to `~/.corp/config.json`. The MCP server reads this file automatically — no additional configuration needed.
51
+
52
+ Your workspace is the same whether you access it from the CLI, MCP server, or chat at [humans.thecorporation.ai](https://humans.thecorporation.ai/chat).
53
+
54
+ ### Option 2: Environment variables
55
+
56
+ Set credentials explicitly in your MCP client config:
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "thecorporation": {
62
+ "command": "npx",
63
+ "args": ["-y", "@thecorporation/mcp-server"],
64
+ "env": {
65
+ "CORP_API_KEY": "sk_...",
66
+ "CORP_WORKSPACE_ID": "ws_..."
67
+ }
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Option 3: Self-hosted
74
+
75
+ Point to your own API server:
43
76
 
44
77
  ```json
45
78
  {
@@ -48,6 +81,7 @@ On first run, the server automatically provisions a workspace and saves credenti
48
81
  "command": "npx",
49
82
  "args": ["-y", "@thecorporation/mcp-server"],
50
83
  "env": {
84
+ "CORP_API_URL": "http://localhost:8000",
51
85
  "CORP_API_KEY": "sk_...",
52
86
  "CORP_WORKSPACE_ID": "ws_..."
53
87
  }
@@ -59,8 +93,8 @@ On first run, the server automatically provisions a workspace and saves credenti
59
93
  | Env var | Description | Default |
60
94
  |---|---|---|
61
95
  | `CORP_API_URL` | API base URL | `https://api.thecorporation.ai` |
62
- | `CORP_API_KEY` | API key | auto-provisioned |
63
- | `CORP_WORKSPACE_ID` | Workspace ID | auto-provisioned |
96
+ | `CORP_API_KEY` | API key | from `~/.corp/config.json` |
97
+ | `CORP_WORKSPACE_ID` | Workspace ID | from `~/.corp/config.json` |
64
98
 
65
99
  ## Tools
66
100
 
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ function createMcpServer(client) {
64
64
  }
65
65
 
66
66
  // src/auth.ts
67
- import { readFileSync, writeFileSync, mkdirSync } from "fs";
67
+ import { readFileSync } from "fs";
68
68
  import { join as join2 } from "path";
69
69
  import { homedir as homedir2 } from "os";
70
70
  var CONFIG_FILE = join2(homedir2(), ".corp", "config.json");
@@ -75,21 +75,6 @@ function loadConfig() {
75
75
  return {};
76
76
  }
77
77
  }
78
- function saveConfig(cfg) {
79
- const dir = join2(homedir2(), ".corp");
80
- mkdirSync(dir, { recursive: true });
81
- writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n");
82
- }
83
- async function provision(apiUrl) {
84
- const resp = await fetch(`${apiUrl.replace(/\/+$/, "")}/v1/workspaces/provision`, {
85
- method: "POST",
86
- headers: { "Content-Type": "application/json" },
87
- body: JSON.stringify({ name: "mcp-auto" }),
88
- signal: AbortSignal.timeout(15e3)
89
- });
90
- if (!resp.ok) throw new Error(`Provision failed: ${resp.status}`);
91
- return await resp.json();
92
- }
93
78
  async function resolveOrProvisionAuth(apiUrl = "https://api.thecorporation.ai") {
94
79
  const envKey = process.env.CORP_API_KEY || "";
95
80
  const envWs = process.env.CORP_WORKSPACE_ID || "";
@@ -100,12 +85,9 @@ async function resolveOrProvisionAuth(apiUrl = "https://api.thecorporation.ai")
100
85
  if (cfg.api_key && cfg.workspace_id) {
101
86
  return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: ["*"] };
102
87
  }
103
- const result = await provision(apiUrl);
104
- cfg.api_key = result.api_key;
105
- cfg.workspace_id = result.workspace_id;
106
- if (!cfg.api_url) cfg.api_url = apiUrl;
107
- saveConfig(cfg);
108
- return { workspaceId: result.workspace_id, apiKey: result.api_key, scopes: ["*"] };
88
+ throw new Error(
89
+ "No credentials found. Run `npx @thecorporation/cli setup` to authenticate, or set CORP_API_KEY and CORP_WORKSPACE_ID environment variables."
90
+ );
109
91
  }
110
92
 
111
93
  // src/index.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/auth.ts"],"sourcesContent":["/**\n * Entry point — resolve auth, start MCP server on stdio.\n */\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { CorpAPIClient } from \"@thecorporation/corp-tools\";\nimport { createMcpServer } from \"./server.js\";\nimport { resolveOrProvisionAuth } from \"./auth.js\";\n\nasync function main(): Promise<void> {\n const apiUrl = process.env.CORP_API_URL || \"https://api.thecorporation.ai\";\n\n const ctx = await resolveOrProvisionAuth(apiUrl);\n const client = new CorpAPIClient(apiUrl, ctx.apiKey, ctx.workspaceId);\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n});\n","/**\n * MCP server — registers all tools from corp-tools definitions,\n * dispatches to the backend API via CorpAPIClient.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport {\n GENERATED_TOOL_DEFINITIONS,\n CorpAPIClient,\n executeTool,\n type ToolContext,\n} from \"@thecorporation/corp-tools\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Build Zod schemas from JSON Schema properties\n// ---------------------------------------------------------------------------\n\ninterface ToolFunction {\n name: string;\n description: string;\n parameters: {\n type: string;\n properties: Record<string, { type: string; description?: string; enum?: string[]; items?: { type: string } }>;\n required: string[];\n };\n}\n\ninterface ToolDef {\n type: string;\n function: ToolFunction;\n}\n\nfunction buildZodShape(fn: ToolFunction): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n const props = fn.parameters.properties || {};\n const required = new Set(fn.parameters.required || []);\n\n for (const [pname, pinfo] of Object.entries(props)) {\n let schema: z.ZodTypeAny;\n switch (pinfo.type) {\n case \"integer\":\n schema = z.number().int();\n break;\n case \"number\":\n schema = z.number();\n break;\n case \"boolean\":\n schema = z.boolean();\n break;\n case \"array\":\n schema = z.array(pinfo.items?.type === \"object\" ? z.record(z.unknown()) : z.string());\n break;\n case \"object\":\n schema = z.record(z.unknown());\n break;\n default:\n schema = pinfo.enum ? z.enum(pinfo.enum as [string, ...string[]]) : z.string();\n }\n if (pinfo.description) schema = schema.describe(pinfo.description);\n if (!required.has(pname)) schema = schema.optional();\n shape[pname] = schema;\n }\n return shape;\n}\n\n// ---------------------------------------------------------------------------\n// Create and configure MCP server\n// ---------------------------------------------------------------------------\n\nexport function createMcpServer(client: CorpAPIClient): McpServer {\n const server = new McpServer({\n name: \"thecorporation\",\n version: \"0.1.0\",\n });\n\n const ctx: ToolContext = {\n dataDir: join(homedir(), \".corp\", \"data\"),\n };\n\n for (const td of GENERATED_TOOL_DEFINITIONS as unknown as ToolDef[]) {\n const fn = td.function;\n const shape = buildZodShape(fn);\n\n server.tool(fn.name, fn.description, shape, async (args) => {\n const result = await executeTool(fn.name, args as Record<string, unknown>, client, ctx);\n return { content: [{ type: \"text\" as const, text: result }] };\n });\n }\n\n return server;\n}\n","/**\n * MCP server authentication — auto-provisioning and shared config.\n *\n * Resolution order:\n * 1. CORP_API_KEY + CORP_WORKSPACE_ID env vars (explicit)\n * 2. ~/.corp/config.json (shared with TUI/CLI)\n * 3. Auto-provision via POST /v1/workspaces/provision\n */\n\nimport { readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface McpAuthContext {\n workspaceId: string;\n apiKey: string;\n scopes: string[];\n}\n\nconst CONFIG_FILE = join(homedir(), \".corp\", \"config.json\");\n\nfunction loadConfig(): Record<string, string> {\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nfunction saveConfig(cfg: Record<string, string>): void {\n const dir = join(homedir(), \".corp\");\n mkdirSync(dir, { recursive: true });\n writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + \"\\n\");\n}\n\nasync function provision(apiUrl: string): Promise<Record<string, string>> {\n const resp = await fetch(`${apiUrl.replace(/\\/+$/, \"\")}/v1/workspaces/provision`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name: \"mcp-auto\" }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!resp.ok) throw new Error(`Provision failed: ${resp.status}`);\n return await resp.json() as Record<string, string>;\n}\n\nexport async function resolveOrProvisionAuth(\n apiUrl: string = \"https://api.thecorporation.ai\",\n): Promise<McpAuthContext> {\n // 1. Env vars\n const envKey = process.env.CORP_API_KEY || \"\";\n const envWs = process.env.CORP_WORKSPACE_ID || \"\";\n if (envKey && envWs) {\n return { workspaceId: envWs, apiKey: envKey, scopes: [\"*\"] };\n }\n\n // 2. Config file\n const cfg = loadConfig();\n if (cfg.api_key && cfg.workspace_id) {\n return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: [\"*\"] };\n }\n\n // 3. Auto-provision\n const result = await provision(apiUrl);\n cfg.api_key = result.api_key;\n cfg.workspace_id = result.workspace_id;\n if (!cfg.api_url) cfg.api_url = apiUrl;\n saveConfig(cfg);\n\n return { workspaceId: result.workspace_id, apiKey: result.api_key, scopes: [\"*\"] };\n}\n"],"mappings":"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","names":["CorpAPIClient","join","homedir","CorpAPIClient"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/auth.ts"],"sourcesContent":["/**\n * Entry point — resolve auth, start MCP server on stdio.\n */\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { CorpAPIClient } from \"@thecorporation/corp-tools\";\nimport { createMcpServer } from \"./server.js\";\nimport { resolveOrProvisionAuth } from \"./auth.js\";\n\nasync function main(): Promise<void> {\n const apiUrl = process.env.CORP_API_URL || \"https://api.thecorporation.ai\";\n\n const ctx = await resolveOrProvisionAuth(apiUrl);\n const client = new CorpAPIClient(apiUrl, ctx.apiKey, ctx.workspaceId);\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n});\n","/**\n * MCP server — registers all tools from corp-tools definitions,\n * dispatches to the backend API via CorpAPIClient.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport {\n GENERATED_TOOL_DEFINITIONS,\n CorpAPIClient,\n executeTool,\n type ToolContext,\n} from \"@thecorporation/corp-tools\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Build Zod schemas from JSON Schema properties\n// ---------------------------------------------------------------------------\n\ninterface ToolFunction {\n name: string;\n description: string;\n parameters: {\n type: string;\n properties: Record<string, { type: string; description?: string; enum?: string[]; items?: { type: string } }>;\n required: string[];\n };\n}\n\ninterface ToolDef {\n type: string;\n function: ToolFunction;\n}\n\nfunction buildZodShape(fn: ToolFunction): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n const props = fn.parameters.properties || {};\n const required = new Set(fn.parameters.required || []);\n\n for (const [pname, pinfo] of Object.entries(props)) {\n let schema: z.ZodTypeAny;\n switch (pinfo.type) {\n case \"integer\":\n schema = z.number().int();\n break;\n case \"number\":\n schema = z.number();\n break;\n case \"boolean\":\n schema = z.boolean();\n break;\n case \"array\":\n schema = z.array(pinfo.items?.type === \"object\" ? z.record(z.unknown()) : z.string());\n break;\n case \"object\":\n schema = z.record(z.unknown());\n break;\n default:\n schema = pinfo.enum ? z.enum(pinfo.enum as [string, ...string[]]) : z.string();\n }\n if (pinfo.description) schema = schema.describe(pinfo.description);\n if (!required.has(pname)) schema = schema.optional();\n shape[pname] = schema;\n }\n return shape;\n}\n\n// ---------------------------------------------------------------------------\n// Create and configure MCP server\n// ---------------------------------------------------------------------------\n\nexport function createMcpServer(client: CorpAPIClient): McpServer {\n const server = new McpServer({\n name: \"thecorporation\",\n version: \"0.1.0\",\n });\n\n const ctx: ToolContext = {\n dataDir: join(homedir(), \".corp\", \"data\"),\n };\n\n for (const td of GENERATED_TOOL_DEFINITIONS as unknown as ToolDef[]) {\n const fn = td.function;\n const shape = buildZodShape(fn);\n\n server.tool(fn.name, fn.description, shape, async (args) => {\n const result = await executeTool(fn.name, args as Record<string, unknown>, client, ctx);\n return { content: [{ type: \"text\" as const, text: result }] };\n });\n }\n\n return server;\n}\n","/**\n * MCP server authentication — shared config with CLI.\n *\n * Resolution order:\n * 1. CORP_API_KEY + CORP_WORKSPACE_ID env vars (explicit)\n * 2. ~/.corp/config.json (shared with CLI — run `corp setup` first)\n *\n * MCP servers run over stdio, so interactive auth (magic link) is not\n * possible here. Users authenticate once via `corp setup` (which does\n * the magic link flow for cloud) and the MCP server reuses those\n * credentials from the shared config file.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface McpAuthContext {\n workspaceId: string;\n apiKey: string;\n scopes: string[];\n}\n\nconst CONFIG_FILE = join(homedir(), \".corp\", \"config.json\");\n\nfunction loadConfig(): Record<string, string> {\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport async function resolveOrProvisionAuth(\n apiUrl: string = \"https://api.thecorporation.ai\",\n): Promise<McpAuthContext> {\n // 1. Env vars (set in claude_desktop_config.json or similar)\n const envKey = process.env.CORP_API_KEY || \"\";\n const envWs = process.env.CORP_WORKSPACE_ID || \"\";\n if (envKey && envWs) {\n return { workspaceId: envWs, apiKey: envKey, scopes: [\"*\"] };\n }\n\n // 2. Shared config from CLI (run `corp setup` to authenticate)\n const cfg = loadConfig();\n if (cfg.api_key && cfg.workspace_id) {\n return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: [\"*\"] };\n }\n\n // No credentials found guide user to authenticate via CLI\n throw new Error(\n \"No credentials found. Run `npx @thecorporation/cli setup` to authenticate, \" +\n \"or set CORP_API_KEY and CORP_WORKSPACE_ID environment variables.\"\n );\n}\n"],"mappings":"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","names":["CorpAPIClient","join","homedir","CorpAPIClient"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecorporation/mcp-server",
3
- "version": "26.3.9",
3
+ "version": "26.3.11",
4
4
  "description": "MCP server for agent-native corporate operations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@modelcontextprotocol/sdk": "^1.12.0",
16
- "@thecorporation/corp-tools": "26.3.9",
16
+ "@thecorporation/corp-tools": "26.3.11",
17
17
  "zod": "^3.24.0"
18
18
  },
19
19
  "devDependencies": {
package/src/auth.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  /**
2
- * MCP server authentication — auto-provisioning and shared config.
2
+ * MCP server authentication — shared config with CLI.
3
3
  *
4
4
  * Resolution order:
5
5
  * 1. CORP_API_KEY + CORP_WORKSPACE_ID env vars (explicit)
6
- * 2. ~/.corp/config.json (shared with TUI/CLI)
7
- * 3. Auto-provision via POST /v1/workspaces/provision
6
+ * 2. ~/.corp/config.json (shared with CLI — run `corp setup` first)
7
+ *
8
+ * MCP servers run over stdio, so interactive auth (magic link) is not
9
+ * possible here. Users authenticate once via `corp setup` (which does
10
+ * the magic link flow for cloud) and the MCP server reuses those
11
+ * credentials from the shared config file.
8
12
  */
9
13
 
10
- import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
14
+ import { readFileSync } from "node:fs";
11
15
  import { join } from "node:path";
12
16
  import { homedir } from "node:os";
13
17
 
@@ -27,45 +31,25 @@ function loadConfig(): Record<string, string> {
27
31
  }
28
32
  }
29
33
 
30
- function saveConfig(cfg: Record<string, string>): void {
31
- const dir = join(homedir(), ".corp");
32
- mkdirSync(dir, { recursive: true });
33
- writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n");
34
- }
35
-
36
- async function provision(apiUrl: string): Promise<Record<string, string>> {
37
- const resp = await fetch(`${apiUrl.replace(/\/+$/, "")}/v1/workspaces/provision`, {
38
- method: "POST",
39
- headers: { "Content-Type": "application/json" },
40
- body: JSON.stringify({ name: "mcp-auto" }),
41
- signal: AbortSignal.timeout(15_000),
42
- });
43
- if (!resp.ok) throw new Error(`Provision failed: ${resp.status}`);
44
- return await resp.json() as Record<string, string>;
45
- }
46
-
47
34
  export async function resolveOrProvisionAuth(
48
35
  apiUrl: string = "https://api.thecorporation.ai",
49
36
  ): Promise<McpAuthContext> {
50
- // 1. Env vars
37
+ // 1. Env vars (set in claude_desktop_config.json or similar)
51
38
  const envKey = process.env.CORP_API_KEY || "";
52
39
  const envWs = process.env.CORP_WORKSPACE_ID || "";
53
40
  if (envKey && envWs) {
54
41
  return { workspaceId: envWs, apiKey: envKey, scopes: ["*"] };
55
42
  }
56
43
 
57
- // 2. Config file
44
+ // 2. Shared config from CLI (run `corp setup` to authenticate)
58
45
  const cfg = loadConfig();
59
46
  if (cfg.api_key && cfg.workspace_id) {
60
47
  return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: ["*"] };
61
48
  }
62
49
 
63
- // 3. Auto-provision
64
- const result = await provision(apiUrl);
65
- cfg.api_key = result.api_key;
66
- cfg.workspace_id = result.workspace_id;
67
- if (!cfg.api_url) cfg.api_url = apiUrl;
68
- saveConfig(cfg);
69
-
70
- return { workspaceId: result.workspace_id, apiKey: result.api_key, scopes: ["*"] };
50
+ // No credentials found — guide user to authenticate via CLI
51
+ throw new Error(
52
+ "No credentials found. Run `npx @thecorporation/cli setup` to authenticate, " +
53
+ "or set CORP_API_KEY and CORP_WORKSPACE_ID environment variables."
54
+ );
71
55
  }