Skip to content

Commit 57b0181

Browse files
john-walkoeclaude
andcommitted
Consolidated release
USPTO Final Petition Decisions MCP server: petition decision search, details, document download with persistent links, and OCR content extraction over the USPTO FPD API. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KR48pyTbzP5sACy79HqLon
0 parents  commit 57b0181

149 files changed

Lines changed: 40892 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
# =============================================================================
3+
# OAuth sign-in (dual IdP: Google + Entra ID) — HTTP mode only
4+
# =============================================================================
5+
# "none" (default) keeps today's behavior. "oauth" turns the HTTP surface into
6+
# an OAuth 2.1 authorization server: users sign in with Google/Microsoft and
7+
# must have an active row in the mcp_users table (see
8+
# scripts/manage_mcp_users.py and the FPD_manage_users tool). In the suite
9+
# deployment FPD points FPD_AUTH_DB_PATH at the shared paid-tier file
10+
# hosted by PFW (shared bind mount, same host only).
11+
# FPD_AUTH_MODE=oauth
12+
# FPD_AUTH_BASE_URL=https://your-public-hostname.example.com
13+
# FPD_AUTH_JWT_SECRET= # openssl rand -hex 32 — rotating logs everyone out
14+
# FPD_AUTH_GOOGLE_CLIENT_ID=
15+
# FPD_AUTH_GOOGLE_CLIENT_SECRET=
16+
# FPD_AUTH_MS_CLIENT_ID=
17+
# FPD_AUTH_MS_CLIENT_SECRET=
18+
# FPD_AUTH_MS_TENANT=common # common | organizations | tenant GUID
19+
# FPD_AUTH_INTERNAL_TOKEN= # openssl rand -hex 32 — static bearer for headless clients
20+
# # (fpd:user ONLY as of the M1 hardening pass —
21+
# # existing internal-gateway tokens keep working
22+
# # for search/document tools but no longer grants
23+
# # fpd:admin; this is intended)
24+
# FPD_AUTH_INTERNAL_ADMIN_TOKEN= # openssl rand -hex 32 — SEPARATE static
25+
# # bearer granting fpd:user + fpd:admin. Issue
26+
# # this only to whichever internal caller
27+
# # actually needs to manage users; most
28+
# # deployments should leave it unset.
29+
# FPD_AUTH_REGISTER_URL= # optional "Request access" link
30+
# FPD_AUTH_ACCESS_TTL=3600
31+
# FPD_AUTH_REFRESH_TTL=2592000
32+
# FPD_AUTH_DB_PATH=data/mcp_auth.db
33+
34+
# =============================================================================
35+
# Shared USPTO rate limiting (off by default)
36+
# =============================================================================
37+
# All 4 USPTO MCPs (citations/pfw/ptab/fpd) can run as containers sharing one
38+
# host/netns under a SINGLE USPTO API key. USPTO's documented limits are
39+
# per-KEY (burst=1, no parallel requests; 4-15 req/sec by call type; weekly
40+
# quotas), so a per-process limiter can't see what the other 3 processes are
41+
# doing. Setting USPTO_SHARED_RATE_LIMIT_DIR points all of them at one
42+
# bind-mounted directory; a cross-process token bucket + a bounded pool of
43+
# concurrency slots, both arbitrated via POSIX file locks (flock — released
44+
# automatically by the kernel on process death, so it's crash-safe), keep
45+
# the combined request rate under the shared key's limits. Leave unset for a
46+
# standalone deployment.
47+
# USPTO_SHARED_RATE_LIMIT_DIR=/var/run/uspto-shared-rate-limit
48+
# USPTO_SHARED_RATE_LIMIT_RPS=4.0 # total tokens/sec across ALL 4 MCPs
49+
# USPTO_SHARED_MAX_CONCURRENT=2 # shared in-flight request slots
50+
51+
# Registration gate for the FPD_manage_users admin tool. Default off: the
52+
# tool is not registered at all (absent from tools/list) unless this is
53+
# "true". stdio never needs it (seed admins with scripts/manage_mcp_users.py);
54+
# in a non-OAuth HTTP deployment it would be protected only by the shared
55+
# INTERNAL_AUTH_SECRET. **OAuth deployments must set this true** or the admin
56+
# tool disappears. When enabled + FPD_AUTH_MODE=oauth it is additionally
57+
# gated behind the fpd:admin scope.
58+
# FPD_ENABLE_USER_MANAGEMENT=false

.github/workflows/secret-scan.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Secret Scanning
2+
3+
on:
4+
push:
5+
branches: [ main, master, develop ]
6+
pull_request:
7+
branches: [ main, master, develop ]
8+
9+
jobs:
10+
secret-scan:
11+
name: Detect Secrets
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0 # Full history for comprehensive scanning
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install detect-secrets
26+
run: |
27+
pip install detect-secrets
28+
29+
- name: Run detect-secrets scan
30+
run: |
31+
detect-secrets scan \
32+
--exclude-files 'configs/.*\.json' \
33+
--exclude-files '\.md$' \
34+
--exclude-files 'package-lock\.json' \
35+
--exclude-files '\.lock$' \
36+
--baseline .secrets.baseline
37+
38+
- name: Check for secrets in git history (last 100 commits)
39+
run: |
40+
# Scan recent git history for accidentally committed secrets
41+
git log --all --pretty=format: -p -100 | \
42+
detect-secrets scan --stdin \
43+
--exclude-files 'configs/.*\.json' \
44+
--exclude-files '\.md$' || true
45+
46+
- name: Security scan summary
47+
if: always()
48+
run: |
49+
echo "✅ Secret scanning complete"
50+
echo "If secrets were detected, the job will fail above"
51+
echo "To update baseline: detect-secrets scan --baseline .secrets.baseline"
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Security Scanning
2+
3+
on:
4+
push:
5+
branches: [ main, master, develop ]
6+
pull_request:
7+
branches: [ main, master, develop ]
8+
9+
jobs:
10+
secret-scan:
11+
name: Detect Secrets
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0 # Full history for comprehensive scanning
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install detect-secrets
26+
run: |
27+
pip install detect-secrets
28+
29+
- name: Run detect-secrets scan
30+
run: |
31+
detect-secrets scan \
32+
--exclude-files 'configs/.*\.json' \
33+
--exclude-files '\.md$' \
34+
--exclude-files 'package-lock\.json' \
35+
--exclude-files '\.lock$' \
36+
--baseline .secrets.baseline
37+
38+
- name: Check for secrets in git history (last 100 commits)
39+
run: |
40+
# Scan recent git history for accidentally committed secrets
41+
git log --all --pretty=format: -p -100 | \
42+
detect-secrets scan --stdin \
43+
--exclude-files 'configs/.*\.json' \
44+
--exclude-files '\.md$' || true
45+
46+
- name: Security scan summary
47+
if: always()
48+
run: |
49+
echo "✅ Secret scanning complete"
50+
echo "If secrets were detected, the job will fail above"
51+
echo "To update baseline: detect-secrets scan --baseline .secrets.baseline"
52+
53+
prompt-injection-check:
54+
name: Prompt Injection Security Scan
55+
runs-on: ubuntu-latest
56+
57+
steps:
58+
- name: Checkout repository
59+
uses: actions/checkout@v4
60+
61+
- name: Set up Python
62+
uses: actions/setup-python@v5
63+
with:
64+
python-version: '3.11'
65+
66+
- name: Install uv
67+
uses: astral-sh/setup-uv@v3
68+
69+
- name: Install dependencies
70+
run: uv sync
71+
72+
- name: Run prompt injection detection
73+
run: |
74+
echo "🔍 Scanning for prompt injection patterns..."
75+
echo "Includes detection for Unicode steganography attacks from Repello.ai article"
76+
echo ""
77+
78+
# Create baseline if it doesn't exist, then check against it
79+
if [ ! -f .prompt_injections.baseline ]; then
80+
echo "📋 Creating baseline for first time..."
81+
uv run python .security/check_prompt_injections.py --update-baseline src/ tests/ *.md *.yml *.yaml *.json *.py
82+
else
83+
echo "📋 Using existing baseline..."
84+
uv run python .security/check_prompt_injections.py --baseline src/ tests/ *.yml *.yaml *.json *.py
85+
fi

.gitignore

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
MANIFEST
23+
24+
# Virtual environments
25+
.venv/
26+
venv/
27+
ENV/
28+
env/
29+
.env
30+
31+
# IDE
32+
.vscode/
33+
.idea/
34+
.claude/
35+
*.swp
36+
*.swo
37+
*~
38+
.DS_Store
39+
40+
# Testing
41+
.tox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*.cover
48+
.hypothesis/
49+
.pytest_cache/
50+
51+
# Environment variables - NEVER commit secrets!
52+
.env
53+
.env.local
54+
.env.*.local
55+
*.env
56+
.env.*
57+
!.env.example
58+
59+
# Claude assistant reference file with API keys
60+
61+
# Logs
62+
*.log
63+
logs/
64+
65+
# OS
66+
Thumbs.db
67+
68+
# uv lock file
69+
70+
# Project specific files to exclude (per user request)
71+
tests/archive/
72+
73+
# Claude assistant documents
74+
Claude_Documents/
75+
76+
# Proxy persistent-link cache (never commit the Fernet key)
77+
.fpd_proxy_encryption_key
78+
fpd_proxy_link_cache.db
79+
fpd_proxy_link_cache.db-*
80+
81+
# OAuth auth store (SQLite) — users + AS state, never commit
82+
data/
83+
*.db-wal
84+
*.db-shm
85+
86+
# Local-only code-review reports
87+
audits/
88+
CLAUDE.md

.pre-commit-config.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Pre-commit hooks for FPD MCP
2+
# Install: pip install pre-commit && pre-commit install
3+
# Run manually: pre-commit run --all-files
4+
5+
repos:
6+
- repo: https://github.com/Yelp/detect-secrets
7+
rev: v1.5.0
8+
hooks:
9+
- id: detect-secrets
10+
args:
11+
- '--baseline'
12+
- '.secrets.baseline'
13+
- '--exclude-files'
14+
- 'configs/.*\.json'
15+
- '--exclude-files'
16+
- '\.md$'
17+
- '--exclude-files'
18+
- 'package-lock\.json'
19+
exclude: ^\.secrets\.baseline$
20+
21+
- repo: https://github.com/pre-commit/pre-commit-hooks
22+
rev: v4.5.0
23+
hooks:
24+
- id: trailing-whitespace
25+
exclude: ^\.secrets\.baseline$
26+
- id: end-of-file-fixer
27+
exclude: ^\.secrets\.baseline$
28+
- id: check-yaml
29+
- id: check-added-large-files
30+
args: ['--maxkb=1000']
31+
- id: check-json
32+
exclude: ^configs/.*\.json$ # Allow placeholder keys in example configs
33+
- id: check-merge-conflict
34+
- id: detect-private-key
35+
36+
- repo: local
37+
hooks:
38+
- id: prompt-injection-check
39+
name: Check for prompt injection patterns (Unicode steganography & FPD attacks)
40+
entry: uv run python .security/check_prompt_injections.py
41+
language: system
42+
files: \.(py|txt|md|yml|yaml|json|js|ts|html|xml|csv|rst|cfg|ini|toml|log|env|sh|bat|ps1)$
43+
exclude: ^(\.security/.*\.py|SECURITY_.*\.md|PROMPTS\.md|README\.md|CLAUDE\.md|\.github/workflows/.*\.yml|deploy/.*|src/fpd_mcp/prompts/.*\.py|src/fpd_mcp/shared/injection_scan\.py|tests/test_injection_scan\.py|docs/CONTENT_PROVENANCE\.md)$

0 commit comments

Comments
 (0)