Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,16 +322,31 @@ Specs live in git (`docs/specs/*.md` by convention), not in CodePlans. Link a sp

---

## Connect Claude (MCP)
## Connect Claude Code or Cursor (MCP)

CodePlans ships an MCP server at `/api/mcp/mcp` (Streamable HTTP). Create an API key in **Settings → API Keys**, then:
CodePlans ships an MCP server at `/api/mcp/mcp` (Streamable HTTP). Create an API key in **Settings → API Keys** — the settings page shows these snippets with your host and freshly minted key pre-filled.

**Claude Code** (user scope — available in every project):

```bash
claude mcp add --transport http codeplans http://localhost:3000/api/mcp/mcp \
claude mcp add --scope user --transport http codeplans http://localhost:3000/api/mcp/mcp \
--header "Authorization: Bearer cpk_your_key"
```

Claude can then read plans/work items/tech debt and (with a write-scope key) model products, assets, and dependencies, manage plans end-to-end (create, target assets, activate/complete), file work items, manage tasks, and record branch/PR status on plan assets. Keys act as your user, so org access rules and mirrored-field protections apply unchanged. See [`docs/specs/mcp-server-spec.md`](docs/specs/mcp-server-spec.md).
**Cursor** — add to `~/.cursor/mcp.json` (or `.cursor/mcp.json` per project), then enable under Settings → MCP:

```json
{
"mcpServers": {
"codeplans": {
"url": "http://localhost:3000/api/mcp/mcp",
"headers": { "Authorization": "Bearer cpk_your_key" }
}
}
}
```

Your agent can then read plans/work items/tech debt and (with a write-scope key) model products, assets, and dependencies, manage plans end-to-end (create, target assets, activate/complete), file work items, manage tasks, and record branch/PR status on plan assets. Keys act as your user, so org access rules and mirrored-field protections apply unchanged. See [`docs/specs/mcp-server-spec.md`](docs/specs/mcp-server-spec.md).

---

Expand Down
94 changes: 92 additions & 2 deletions app/(dashboard)/settings/api-keys-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
'use client'

import { useState, useTransition } from 'react'
import { useEffect, useState, useTransition } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { KeyRound, Plus, Trash2, Copy } from 'lucide-react'
import { KeyRound, Plus, Trash2, Copy, TerminalSquare } from 'lucide-react'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { formatDateShort } from '@/lib/utils'
import { createApiKeyAction, revokeApiKeyAction } from '../actions'

Expand Down Expand Up @@ -40,6 +41,7 @@ export function ApiKeysPanel({ keys }: { keys: ApiKeyRow[] }) {
}

return (
<>
<Card className="bg-card border-border">
<CardHeader>
<div className="flex items-center gap-2">
Expand Down Expand Up @@ -130,5 +132,93 @@ export function ApiKeysPanel({ keys }: { keys: ApiKeyRow[] }) {
)}
</CardContent>
</Card>
<ConnectCard mintedKey={minted} />
</>
)
}

/** Copy-paste client setup, shown alongside key generation. */
function ConnectCard({ mintedKey }: { mintedKey: string | null }) {
const [origin, setOrigin] = useState('https://your-codeplans-host')
const [copied, setCopied] = useState<string | null>(null)
useEffect(() => setOrigin(window.location.origin), [])

const key = mintedKey ?? 'cpk_your_key'
const claudeSnippet = `claude mcp add --scope user --transport http codeplans ${origin}/api/mcp/mcp \\
--header "Authorization: Bearer ${key}"`
const cursorSnippet = `{
"mcpServers": {
"codeplans": {
"url": "${origin}/api/mcp/mcp",
"headers": { "Authorization": "Bearer ${key}" }
}
}
}`

function copy(label: string, text: string) {
navigator.clipboard.writeText(text)
setCopied(label)
setTimeout(() => setCopied(null), 1500)
}

function Snippet({ label, text }: { label: string; text: string }) {
return (
<div className="relative">
<pre className="overflow-x-auto rounded-md bg-muted p-3 pr-12 text-xs leading-relaxed">
<code>{text}</code>
</pre>
<Button
variant="ghost"
size="icon"
className="absolute right-1.5 top-1.5 h-7 w-7 text-muted-foreground"
title="Copy"
onClick={() => copy(label, text)}
>
<Copy className="h-3.5 w-3.5" />
</Button>
{copied === label && (
<span className="absolute right-10 top-2.5 text-xs text-accent">Copied</span>
)}
</div>
)
}

return (
<Card className="bg-card border-border">
<CardHeader>
<div className="flex items-center gap-2">
<TerminalSquare className="h-5 w-5 text-muted-foreground" />
<CardTitle className="text-base">Use with Claude Code &amp; Cursor</CardTitle>
</div>
<CardDescription>
{mintedKey
? 'Your new key is already filled in below — copy a snippet before navigating away.'
: 'Generate a key above, then connect your agent. Snippets show a placeholder key.'}
</CardDescription>
</CardHeader>
<CardContent>
<Tabs defaultValue="claude">
<TabsList className="bg-muted mb-3">
<TabsTrigger value="claude">Claude Code</TabsTrigger>
<TabsTrigger value="cursor">Cursor</TabsTrigger>
</TabsList>
<TabsContent value="claude" className="space-y-2">
<p className="text-xs text-muted-foreground">
Run once in a terminal — <code>--scope user</code> makes the server available in every project:
</p>
<Snippet label="claude" text={claudeSnippet} />
<p className="text-xs text-muted-foreground">
Verify with <code>claude mcp list</code>, then ask Claude to &ldquo;list my CodePlans products&rdquo;.
</p>
</TabsContent>
<TabsContent value="cursor" className="space-y-2">
<p className="text-xs text-muted-foreground">
Add to <code>~/.cursor/mcp.json</code> (all projects) or <code>.cursor/mcp.json</code> in a repo (that project only), then enable it under Cursor Settings → MCP:
</p>
<Snippet label="cursor" text={cursorSnippet} />
</TabsContent>
</Tabs>
</CardContent>
</Card>
)
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codeplans",
"version": "0.3.17",
"version": "0.3.18",
"description": "Manage and track coordinated changes across your software architecture.",
"author": "Sai Prakash <sylonzero@gmail.com>",
"homepage": "https://codeplans.ai",
Expand Down
Loading